View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.restapi.v1;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.net.URL;
24  import java.net.URLEncoder;
25  import java.nio.charset.StandardCharsets;
26  import java.util.List;
27  import java.util.Scanner;
28  
29  import org.apache.logging.log4j.LogManager;
30  import org.apache.logging.log4j.Logger;
31  import org.mycore.restapi.v1.errors.MCRRestAPIException;
32  import org.mycore.solr.MCRSolrClientFactory;
33  
34  import jakarta.servlet.http.HttpServletRequest;
35  import jakarta.ws.rs.DefaultValue;
36  import jakarta.ws.rs.GET;
37  import jakarta.ws.rs.Path;
38  import jakarta.ws.rs.Produces;
39  import jakarta.ws.rs.QueryParam;
40  import jakarta.ws.rs.core.Context;
41  import jakarta.ws.rs.core.MediaType;
42  import jakarta.ws.rs.core.Response;
43  import jakarta.ws.rs.core.UriInfo;
44  
45  /**
46   * Rest API methods that cover SOLR searches.
47   *
48   * @author Robert Stephan
49   *
50   * @version $Revision: $ $Date: $
51   */
52  @Path("/search")
53  public class MCRRestAPISearch {
54      private static Logger LOGGER = LogManager.getLogger(MCRRestAPISearch.class);
55  
56      public static final String FORMAT_JSON = "json";
57  
58      public static final String FORMAT_XML = "xml";
59  
60      public static final String FORMAT_CSV = "csv";
61  
62      /**
63       * see http://wiki.apache.org/solr/CommonQueryParameters for syntax of parameters
64       *
65       * @param info - the injected Jersey URIInfo object
66       * @param request - the injected HTTPServletRequest object
67       *
68       * @param query
69       *      the Query in SOLR Query syntax
70       * @param sort
71       *      the sort parameter - syntax as defined by SOLR
72       * @param wt
73       *      the format parameter - syntax as defined by SOLR
74       * @param start
75       *      the start parameter (number) - syntax as defined by SOLR      
76       * @param rows
77       *      the rows parameter (number) - syntax as defined by SOLR
78       * @param fq
79       *      the filter query parameter - syntax as defined by SOLR
80       * @param fl
81       *      the list of fields to be returned - syntax as defined by SOLR
82       * @param facet
83       *      the facet parameter (true to return facets)  - syntax as defined by SOLR
84       * @param facetFields
85       *      the list of facetFields to be returned - syntax as defined by SOLR
86       * @param jsonWrf
87       *      the name of the JSONP callback function - syntax as defined by SOLR 
88       *
89       * @return a Jersey Response Object
90       * @throws MCRRestAPIException
91       */
92      @GET
93      @Produces({ MediaType.TEXT_XML + ";charset=UTF-8", MediaType.APPLICATION_JSON + ";charset=UTF-8",
94          MediaType.TEXT_PLAIN + ";charset=ISO-8859-1", MediaType.TEXT_PLAIN + ";charset=UTF-8" })
95      public Response search(@Context UriInfo info, @Context HttpServletRequest request, @QueryParam("q") String query,
96          @QueryParam("sort") String sort, @QueryParam("wt") @DefaultValue("xml") String wt,
97          @QueryParam("start") String start, @QueryParam("rows") String rows,
98          @QueryParam("fq") List<String> fq, @QueryParam("fl") List<String> fl,
99          @QueryParam("facet") String facet, @QueryParam("facet.sort") String facetSort,
100         @QueryParam("facet.limit") String facetLimit, @QueryParam("facet.field") List<String> facetFields,
101         @QueryParam("facet.mincount") String facetMinCount,
102         @QueryParam("json.wrf") String jsonWrf)
103         throws MCRRestAPIException {
104         StringBuilder url = new StringBuilder(MCRSolrClientFactory.getMainSolrCore().getV1CoreURL());
105         url.append("/select?");
106 
107         if (query != null) {
108             url.append("&q=").append(URLEncoder.encode(query, StandardCharsets.UTF_8));
109         }
110         if (sort != null) {
111             url.append("&sort=").append(URLEncoder.encode(sort, StandardCharsets.UTF_8));
112         }
113         if (wt != null) {
114             url.append("&wt=").append(wt);
115         }
116         if (start != null) {
117             url.append("&start=").append(start);
118         }
119         if (rows != null) {
120             url.append("&rows=").append(rows);
121         }
122         if (fq != null) {
123             for (String fqItem : fq) {
124                 url.append("&fq=").append(URLEncoder.encode(fqItem, StandardCharsets.UTF_8));
125             }
126         }
127         if (fl != null) {
128             for (String flItem : fl) {
129                 url.append("&fl=").append(URLEncoder.encode(flItem, StandardCharsets.UTF_8));
130             }
131         }
132         if (facet != null) {
133             url.append("&facet=").append(URLEncoder.encode(facet, StandardCharsets.UTF_8));
134         }
135         for (String ff : facetFields) {
136             url.append("&facet.field=").append(URLEncoder.encode(ff, StandardCharsets.UTF_8));
137         }
138         if (facetSort != null) {
139             url.append("&facet.sort=").append(facetSort);
140         }
141         if (facetLimit != null) {
142             url.append("&facet.limit=").append(facetLimit);
143         }
144         if (facetMinCount != null) {
145             url.append("&facet.mincount=").append(facetMinCount);
146         }
147         if (jsonWrf != null) {
148             url.append("&json.wrf=").append(jsonWrf);
149         }
150 
151         try (InputStream is = new URL(url.toString()).openStream()) {
152             try (Scanner scanner = new Scanner(is, StandardCharsets.UTF_8.name())) {
153                 String text = scanner.useDelimiter("\\A").next();
154 
155                 String contentType;
156                 switch (wt) {
157                 case FORMAT_XML:
158                     contentType = "application/xml; charset=UTF-8";
159                     break;
160                 case FORMAT_JSON:
161                     contentType = "application/json; charset=UTF-8";
162                     break;
163                 case FORMAT_CSV:
164                     contentType = "text/comma-separated-values; charset=UTF-8";
165                     break;
166                 default:
167                     contentType = "text";
168                 }
169                 return Response.ok(text)
170                     .type(contentType)
171                     .build();
172 
173             }
174         } catch (IOException e) {
175             LOGGER.error(e);
176         }
177 
178         return Response.status(Response.Status.BAD_REQUEST).build();
179     }
180 }