View Javadoc

1   /*
2    * Copyright 2011 The Kuali Foundation.
3    * 
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    * http://www.opensource.org/licenses/ecl2.php
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.docstore.discovery.service;
17  
18  import org.kuali.ole.docstore.discovery.model.SearchCondition;
19  import org.kuali.ole.docstore.discovery.model.SearchParams;
20  import org.kuali.ole.docstore.discovery.util.PropertyUtil;
21  import org.slf4j.Logger;
22  import org.slf4j.LoggerFactory;
23  
24  import java.io.BufferedReader;
25  import java.io.InputStreamReader;
26  import java.io.UnsupportedEncodingException;
27  import java.net.URL;
28  import java.net.URLConnection;
29  import java.net.URLDecoder;
30  import java.net.URLEncoder;
31  import java.util.*;
32  
33  public class DiscoveryServiceImpl
34          implements DiscoveryService {
35      private static final Logger           LOG              = LoggerFactory.getLogger(DiscoveryServiceImpl.class);
36      private static       String           docSearchUrl     = null;
37      private static       DiscoveryService discoveryService = null;
38  
39      private DiscoveryServiceImpl() {
40          LOG.debug("DiscoveryServiceImpl ");
41          init();
42      }
43  
44      public static DiscoveryService getInstance() {
45          if (null == discoveryService) {
46              discoveryService = new DiscoveryServiceImpl();
47          }
48          return discoveryService;
49      }
50  
51      protected void init() {
52          LOG.debug("DiscoveryServiceImpl init ");
53          setDocSearchUrl(PropertyUtil.getPropertyUtil().getProperty("docSearchURL"));
54      }
55  
56      public String search(SearchParams searchParams) {
57          String response = "";
58          LOG.debug("in search1");
59          String searchType = searchParams.getSearchType();
60          LOG.debug("searchType " + searchType);
61          StringBuffer query = new StringBuffer();
62          query.append(SolrServerManager.getInstance().getSolrCoreURL() + "/select");
63          if (searchParams.getSearchFieldsList() != null && searchParams.getSearchFieldsList().size() <= 0 && (
64                  searchType != null && !searchType.equalsIgnoreCase(SEARCH_TYPE_LINK))) {
65              buildInitialQuery(query, searchParams);
66              searchParams.setSearchTerms("");
67          }
68          else if (searchType != null && (searchType.equalsIgnoreCase(SEARCH_TYPE_ADVANCED)
69                                          || searchType.equalsIgnoreCase(SEARCH_TYPE_FACET)
70                                          || searchType.equalsIgnoreCase(SEARCH_TYPE_FACET_DELETE) || searchType
71                  .equalsIgnoreCase(SEARCH_TYPE_MORE_FACET))) {
72              buildInitialQuery(query, searchParams);
73              if (searchParams.getSearchFieldsList().size() > 0) {
74                  query.append("AND(");
75              }
76              query.append(buildQueryWithSearchParameters(searchParams.getSearchFieldsList()));
77              LOG.debug("query for search terms............." + query.toString());
78              String searchTerms = buildQueryWithSearchParameters(searchParams.getSearchFieldsList())
79                      .replaceAll("_search", "");
80              try {
81                  searchTerms = URLDecoder.decode(searchTerms, "UTF-8");
82              }
83              catch (UnsupportedEncodingException e) {
84                  e.printStackTrace();
85              }
86              searchParams.setSearchTerms(searchTerms.substring(0, searchTerms.lastIndexOf(")")));
87          }
88          if (SEARCH_TYPE_LINK.equals(searchType)) {
89              query.append("?q=id:");
90              query.append(searchParams.getLinkValue());
91          }
92          query.append("&rows=" + searchParams.getResultPageSize());
93          String docType = searchParams.getDocType();
94          LOG.info("docType-->" + docType);
95  
96          query.append("&start=" + searchParams.getResultFromIndex());
97          List<String> facetList = new ArrayList<String>();
98          facetList.add(AUTHOR_FACET);
99          facetList.add(SUBJECT_FACET);
100         facetList.add(FORMAT_FACET);
101         facetList.add(LANGUAGE_FACET);
102         facetList.add(PUBLICATION_DATE_FACET);
103         facetList.add(GENRE_FACET);
104         query.append(buildQueryWithFacetParameters(facetList, 1, 10, searchParams));
105         LOG.debug("sort terms buildQueryWithSortFields" + searchParams.getSortByTerms());
106         LOG.debug("sort Field buildQueryWithSortFields" + searchParams.getSortField());
107         LOG.debug("sort Order buildQueryWithSortFields" + searchParams.getSortOrder());
108         query.append(buildQueryWithSortFields(searchParams.getSortField(), searchParams.getSortOrder()));
109         query.append(buildQueryWithFieldListParameters(searchParams.getFieldList()));
110         Map<String, String> facetTermsMap = searchParams.getFacetTermsMap();
111         query.append(buildFilterQuery(facetTermsMap));
112         String holdingFields
113                 = "RecordType_display,EncodingLevel_display,ReceiptStatus_display,AcquisitionMethod_display,PolicyType_display,CopiesReported_display";
114         String itemFields
115                 = "Barcode_display,ItemType_display,LocationStatus_display,ShelvingScheme_display,ShelvingOrder_display,Address_display,CopyNumber_display,VolumeNumber_display";
116         String instanceFields = "Source_display";
117         String patronFields
118                 = "RecordNumber_display,BeginDate_display,Name_display,BorrowerType_display,BarCodeNumber_display,BarCodeStatus_display,";
119         String onixplFields
120                 = "ContractNumber_display,Title_display,Method_display,Status_display,Type_display,Licensor_display,Licensee_display";
121         String licenseBinaryFields = "Name_display,FileName_display,DateUploaded_display,Owner_display,Notes_display";
122         //query.append("&fl=" + fieldList);
123         query.append(
124                 "&fl=Title_display,Author_display,Publisher_display,Description_display,Subject_display,Location_display,PublicationDate_display,Format_display,DocType,DocFormat,id,ItemLinks,BibliographicLinks,Barcode_display,instanceIdentifier,holdingsIdentifier,itemIdentifier,bibIdentifier"
125                 /*
126                                 + "," + "245a,245b"
127                                 + "," + "100a,110a,111a,700a,710a,711a,800a,810a,811a,400a,410a,411a"
128                                 + "," + "600a,610a,611a,630a,650a,651a,653a"
129                                 + "," + "505a"
130                                 + "," + "856u"
131                                 + "," + "260b"
132                 */ + "," + holdingFields + "," + itemFields + "," + instanceFields + "," + patronFields + "," + onixplFields + ","
133                 + licenseBinaryFields);
134 
135         LOG.debug("query---> " + query);
136         try {
137             String queryStr = query.toString().replaceAll(" ", "+");
138 
139             searchParams.setSearchQuery(queryStr);
140             URL url = new URL(queryStr);
141             URLConnection urlc = null;
142             urlc = url.openConnection();
143             urlc.setDoOutput(true);
144             urlc.setAllowUserInteraction(false);
145             BufferedReader br = new BufferedReader(new InputStreamReader(urlc.getInputStream()));
146             StringBuilder sb = new StringBuilder();
147             String line;
148             while ((line = br.readLine()) != null) {
149                 sb.append(line);
150                 sb.append("\n");
151             }
152             br.close();
153             response = sb.toString();
154         }
155         catch (Exception e) {
156 
157         }
158         return response;
159     }
160 
161     public String getFieldList(String docType) {
162         String fieldList = "";
163         String holdingFields = HOLDINGS_FIELDS;
164         String itemFields = ITEM_FIELDS;
165         String instanceFields = INSTANCE_FIELDS;
166         String bibFields = BIB_FIELDS;
167 
168         if (docType.equalsIgnoreCase(BIBLIOGRAPHIC)) {
169             fieldList = bibFields;
170 
171         }
172         else if (docType.equalsIgnoreCase(INSTANCE)) {
173             fieldList = instanceFields;
174 
175         }
176         else if (docType.equalsIgnoreCase(HOLDINGS)) {
177             fieldList = holdingFields;
178 
179         }
180         else if (docType.equalsIgnoreCase(ITEM)) {
181             fieldList = itemFields;
182         }
183         return fieldList;
184     }
185 
186 
187     public static void setDocSearchUrl(String docSearchUrl) {
188     }
189 
190     public static String getDocSearchUrl() {
191         return docSearchUrl;
192     }
193 
194     public String buildQuery(SearchParams searchParams) {
195         StringBuffer query = new StringBuffer();
196         String searchType = searchParams.getSearchType();
197         query.append(SolrServerManager.getInstance().getSolrCoreURL() + "/select");
198         buildInitialQuery(query, searchParams);
199         if (searchParams.getSearchFieldsList().size() > 0) {
200             query.append("AND(");
201         }
202         query.append(buildQueryWithSearchParameters(searchParams.getSearchFieldsList()));
203         if (searchParams.getResultPageSize() != null) {
204             query.append("&rows=" + searchParams.getResultPageSize());
205         }
206         if (searchParams.getResultFromIndex() != null) {
207             query.append("&start=" + searchParams.getResultFromIndex());
208         }
209         List<String> facetFieldList = searchParams.getFacetFieldList();
210         query.append(buildQueryWithFacetParameters(facetFieldList, 1, 10, searchParams));
211         query.append(buildQueryWithSortFields(searchParams.getSortField(), searchParams.getSortOrder()));
212         query.append(buildQueryWithFieldListParameters(searchParams.getFieldList()));
213         Map<String, String> facetTermsMap = searchParams.getFacetTermsMap();
214         query.append(buildFilterQuery(facetTermsMap));
215 
216         return query.toString();
217     }
218 
219 
220     public String buildQueryWithSearchParameters(List<SearchCondition> searchFieldsList) {
221         SearchCondition docSearchFieldsDTO = null;
222         StringBuffer queryStringbuffer = new StringBuffer();
223         StringBuffer highlightBuffer = new StringBuffer("&hl.fl=");
224         if (searchFieldsList != null && searchFieldsList.size() > 0) {
225 
226             for (int i = 0; i < searchFieldsList.size(); i++) {
227                 docSearchFieldsDTO = searchFieldsList.get(i);
228                 if (docSearchFieldsDTO.getOperator() != null) {
229                     queryStringbuffer.append(docSearchFieldsDTO.getOperator());
230                 }
231                 queryStringbuffer.append("(");
232                 if (docSearchFieldsDTO.getDocField().equalsIgnoreCase("all")) {
233                     queryStringbuffer.append("all_text");
234                     highlightBuffer.append("*");
235 
236                 }
237                 else {
238                     queryStringbuffer.append(docSearchFieldsDTO.getDocField());
239                     highlightBuffer.append(docSearchFieldsDTO.getDocField());
240 
241                     if (i != searchFieldsList.size() - 1) {
242                         highlightBuffer.append(",");
243                     }
244                 }
245                 queryStringbuffer.append(":");
246                 String searchScope = docSearchFieldsDTO.getSearchScope();
247                 String searchText = docSearchFieldsDTO.getSearchText();
248                 searchText = searchText.toLowerCase();
249                 LOG.debug("searchText-->" + searchText);
250                 //searchText = searchText.replaceAll("[^a-zA-Z 0-9*]+", "");
251                 String searchTextVal = null;
252                 if (searchText.length() > 0) {
253                     queryStringbuffer.append("(");
254                     if (searchScope.equalsIgnoreCase("AND")) {
255                         searchText = searchText.replaceAll("\\s+", " ");
256                         searchTextVal = searchText.trim().replace(" ", " AND ");
257                     }
258                     else if (searchScope.equalsIgnoreCase("OR")) {
259                         searchText = searchText.replaceAll("\\s+", " ");
260                         searchTextVal = searchText.trim().replace(" ", " OR ");
261                     }
262                     else if (searchScope.equalsIgnoreCase("phrase")) {
263                         searchTextVal = "\"" + searchText + "\"";
264                     }
265                     try {
266                         searchTextVal = URLEncoder.encode(searchTextVal, "UTF-8");
267                     }
268                     catch (UnsupportedEncodingException e) {
269                         e.printStackTrace();
270                     }
271                     queryStringbuffer.append(searchTextVal);
272                     LOG.debug("searchTextVal............" + searchTextVal + "........" + queryStringbuffer.toString());
273                     queryStringbuffer.append(")");
274                 }
275                 queryStringbuffer.append(")");
276             }
277             queryStringbuffer.append(")");
278             queryStringbuffer.append(highlightBuffer.toString());
279 
280             queryStringbuffer.append("&hl=true");
281         }
282 
283 
284         return queryStringbuffer.toString();
285     }
286 
287     public String buildQueryWithFacetParameters(List<String> facetsParametersList, int facetMinCount, int facetLimit,
288                                                 SearchParams searchParams) {
289         String facetFieldName = "";
290         String queryWithFacetParameters = "";
291         String facetPrefix = searchParams.getFacetPrefix();
292         String facetPageSize = searchParams.getFacetPageSize();
293         String facetSort = searchParams.getFacetSort();
294         String facetOffset = searchParams.getFacetOffset();
295         if (facetsParametersList != null) {
296             StringBuffer facetsQueryStringbuffer = new StringBuffer();
297 
298             facetsQueryStringbuffer.append("&facet=true");
299 
300             facetsQueryStringbuffer.append("&facet.mincount=" + facetMinCount);
301 
302             facetsQueryStringbuffer.append("&facet.prefix=" + facetPrefix);
303 
304             facetsQueryStringbuffer.append("&facet.offset=" + facetOffset);
305 
306             facetsQueryStringbuffer.append("&facet.limit=" + facetPageSize);
307 
308             facetsQueryStringbuffer.append("&facet.sort=" + facetSort);
309             facetsQueryStringbuffer.append("&");
310 
311             for (int i = 0; i < facetsParametersList.size(); i++) {
312                 facetFieldName = facetsParametersList.get(i);
313                 facetsQueryStringbuffer.append("facet.field=" + facetFieldName);
314                 facetsQueryStringbuffer.append("&");
315 
316             }
317             queryWithFacetParameters = facetsQueryStringbuffer.substring(0, facetsQueryStringbuffer.length() - 1);
318         }
319         return queryWithFacetParameters;
320     }
321 
322 
323     public String buildQueryWithSortFields(String sortField, String sortOrder) {
324         StringBuffer sortFieldsQuery = new StringBuffer();
325         if (null != sortField) {
326             sortFieldsQuery.append("&");
327             sortFieldsQuery.append("sort=");
328             sortFieldsQuery.append(sortField);
329             if (null != sortOrder) {
330                 sortFieldsQuery.append(" ");
331                 sortFieldsQuery.append(sortOrder);
332             }
333         }
334         return sortFieldsQuery.toString();
335     }
336 
337     public String buildQueryWithFieldListParameters(List<String> fieldsList) {
338         String queryWithFieldListParameters = "";
339         if (fieldsList != null) {
340             StringBuffer fieldsListQueryStringbuffer = new StringBuffer();
341             fieldsListQueryStringbuffer.append("&");
342             fieldsListQueryStringbuffer.append("fl=");
343             for (int i = 0; i < fieldsList.size(); i++) {
344                 fieldsListQueryStringbuffer.append(fieldsList.get(i));
345                 fieldsListQueryStringbuffer.append(",");
346             }
347             queryWithFieldListParameters = fieldsListQueryStringbuffer
348                     .substring(0, fieldsListQueryStringbuffer.length() - 1);
349         }
350         return queryWithFieldListParameters;
351     }
352 
353     public static String convertListToStringFieldValues(Map<String, String> map) {
354         StringBuffer sb = new StringBuffer();
355         Set set = map.keySet();
356         Iterator<String> ite = set.iterator();
357         while (ite.hasNext()) {
358             sb.append(ite.next());
359             sb.append("|");
360         }
361         String str = sb.toString();
362         if (str != null && str.length() > 0) {
363             str = str.substring(0, str.length() - 1);
364         }
365         return str;
366     }
367 
368     public String buildFilterQuery(Map<String, String> facetTermsMap) {
369         String filterQuery = "";
370         int temp = 0;
371         int tokenInt = 0;
372         if ((null != facetTermsMap) && (facetTermsMap.size() > 0)) {
373 
374             String facetTerms = convertListToStringFieldValues(facetTermsMap);
375             StringBuffer facetQueryTemp = new StringBuffer();
376             facetQueryTemp.append("&terms=" + facetTerms);
377             facetQueryTemp.append("&fq=");
378             StringTokenizer sttoken = new StringTokenizer(facetTerms, "|");
379             String token;
380             while (sttoken.hasMoreElements()) {
381                 token = sttoken.nextToken();
382                 facetQueryTemp.append("(");
383                 facetQueryTemp.append(facetTermsMap.get(token));
384                 facetQueryTemp.append(":\"");
385                 facetQueryTemp.append(token);
386                 facetQueryTemp.append("\")");
387                 facetQueryTemp.append("AND");
388             }
389             if (facetQueryTemp.length() > 0) {
390                 filterQuery = (facetQueryTemp.toString().substring(0, facetQueryTemp.toString().length() - 3));
391             }
392         }
393         return filterQuery;
394     }
395 
396 
397     /**
398      * @param query
399      * @param searchParams Usage: This method builds initial SOLR query with DocType and DocFormat as SolrParams
400      */
401     private void buildInitialQuery(StringBuffer query, SearchParams searchParams) {
402         query.append("?q=");
403         //query.append("(DocType:" + searchParams.getDocType() + ")");
404         if (searchParams.getDocFormat().equalsIgnoreCase("marc")) {
405             query.append("((DocType:" + searchParams.getDocType() + ")" + "OR(DocType:item))");
406         }
407         else {
408             query.append("(DocType:" + searchParams.getDocType() + ")");
409         }
410 
411         if (searchParams.getDocFormat() != null && !searchParams.getDocFormat().equalsIgnoreCase("all")) {
412             if ("dublin".equals(searchParams.getDocFormat())) {
413                 searchParams.setDocFormat("dublin");
414             }
415             query.append("AND(DocFormat:" + searchParams.getDocFormat() + ")");
416         }
417     }
418 
419 }