1
2
3
4
5
6
7
8
9
10
11
12
13
14
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.rice.core.api.config.property.ConfigContext;
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.text.CharacterIterator;
32 import java.text.StringCharacterIterator;
33 import java.util.*;
34
35 public class DiscoveryServiceImpl
36 implements DiscoveryService {
37 private static final Logger LOG = LoggerFactory.getLogger(DiscoveryServiceImpl.class);
38 private static String docSearchUrl = null;
39 private static DiscoveryService discoveryService = null;
40
41 private DiscoveryServiceImpl() {
42 LOG.debug("DiscoveryServiceImpl ");
43 init();
44 }
45
46 public static DiscoveryService getInstance() {
47 if (null == discoveryService) {
48 discoveryService = new DiscoveryServiceImpl();
49 }
50 return discoveryService;
51 }
52
53 protected void init() {
54 LOG.debug("DiscoveryServiceImpl init ");
55 if(ConfigContext.getCurrentContextConfig()!=null){
56 setDocSearchUrl(ConfigContext.getCurrentContextConfig().getProperty("docSearchURL"));
57 }
58 }
59
60 public String search(SearchParams searchParams) {
61 String response = "";
62 LOG.debug("in search1");
63 String searchType = searchParams.getSearchType();
64 LOG.debug("searchType " + searchType);
65 StringBuffer query = new StringBuffer();
66 query.append(SolrServerManager.getInstance().getSolrCoreURL() + "/select");
67 if (searchType.equals(SEARCH_TYPE_MORE_FACET)) {
68 String facetPrefix = searchParams.getFacetPrefix();
69 String facetPageSize = searchParams.getFacetPageSize();
70 String facetSort = searchParams.getFacetSort();
71 String facetOffset = searchParams.getFacetOffset();
72 buildInitialQuery(query, searchParams);
73 query.append("&facet=true");
74
75 query.append("&facet.mincount=1");
76
77 query.append("&facet.prefix=" + facetPrefix);
78
79 query.append("&facet.offset=" + facetOffset);
80
81 query.append("&facet.limit=" + facetPageSize);
82
83 query.append("&facet.sort=" + facetSort);
84
85 query.append("&facet.field=" + searchParams.getFacetField());
86
87 Map<String, String> facetTermsMap = searchParams.getFacetTermsMap();
88 query.append(buildFilterQuery(facetTermsMap));
89 } else {
90 if (searchParams.getSearchFieldsList() != null && searchParams.getSearchFieldsList().size() <= 0 && (
91 searchType != null && !searchType.equalsIgnoreCase(SEARCH_TYPE_LINK))) {
92 buildInitialQuery(query, searchParams);
93 searchParams.setSearchTerms("");
94 } else if (searchType != null && (searchType.equalsIgnoreCase(SEARCH_TYPE_ADVANCED)
95 || searchType.equalsIgnoreCase(SEARCH_TYPE_FACET) || searchType
96 .equalsIgnoreCase(SEARCH_TYPE_FACET_DELETE))) {
97 buildInitialQuery(query, searchParams);
98 if (searchParams.getSearchFieldsList().size() > 0) {
99 query.append("AND(");
100 }
101 query.append(buildQueryWithSearchParameters(searchParams.getSearchFieldsList()));
102 LOG.debug("query for search terms............." + query.toString());
103 String searchTerms = buildQueryWithSearchParameters(searchParams.getSearchFieldsList())
104 .replaceAll("_search", "");
105 try {
106 searchTerms = URLDecoder.decode(searchTerms, "UTF-8");
107 } catch (UnsupportedEncodingException e) {
108 e.printStackTrace();
109 }
110 searchParams.setSearchTerms(searchTerms.substring(0, searchTerms.lastIndexOf(")")));
111 }
112 if (SEARCH_TYPE_LINK.equals(searchType)) {
113 query.append("?q=id:");
114 query.append(searchParams.getLinkValue());
115 }
116 query.append("&rows=" + searchParams.getResultPageSize());
117 String docType = searchParams.getDocType();
118 LOG.info("docType-->" + docType);
119
120 query.append("&start=" + searchParams.getResultFromIndex());
121 List<String> facetList = new ArrayList<String>();
122 facetList.add(AUTHOR_FACET);
123 facetList.add(SUBJECT_FACET);
124 facetList.add(FORMAT_FACET);
125 facetList.add(LANGUAGE_FACET);
126 facetList.add(PUBLICATION_DATE_FACET);
127 facetList.add(GENRE_FACET);
128 query.append(buildQueryWithFacetParameters(facetList, 1, 10));
129 LOG.debug("sort terms buildQueryWithSortFields" + searchParams.getSortByTerms());
130 LOG.debug("sort Field buildQueryWithSortFields" + searchParams.getSortField());
131 LOG.debug("sort Order buildQueryWithSortFields" + searchParams.getSortOrder());
132 query.append(buildQueryWithSortFields(searchParams.getSortField(), searchParams.getSortOrder()));
133 query.append(buildQueryWithFieldListParameters(searchParams.getFieldList()));
134 Map<String, String> facetTermsMap = searchParams.getFacetTermsMap();
135 query.append(buildFilterQuery(facetTermsMap));
136 String holdingFields
137 = "LocalId_display,Uri_display,HoldingsNote_display,ReceiptStatus_display,CallNumber_display,CallNumberPrefix_display,CallNumberType_display,ClassificationPart_display,LocationLevel_display,ShelvingSchemeCode_display";
138 String itemFields
139 = "LocalId_display,ItemBarcode_display,ItemTypeFullValue_display,VendorLineItemIdentifier_display,ShelvingOrderValue_display,ShelvingSchemeValue_display,PurchaseOrderLineItemIdentifier_display,CopyNumber_display,Enumeration_display,Chronology_display,VolumeNumber_display,ItemStatus_display";
140 String instanceFields = "LocalId_display,Source_display";
141 String patronFields
142 = "RecordNumber_display,BeginDate_display,Name_display,BorrowerType_display,BarCodeNumber_display,BarCodeStatus_display,";
143 String onixplFields
144 = "ContractNumber_display,Title_display,Method_display,Status_display,Type_display,Licensor_display,Licensee_display";
145 String licenseBinaryFields
146 = "Name_display,FileName_display,DateUploaded_display,Owner_display,Notes_display";
147 String eInstanceFields = "AccessStatus_display,Imprint_display,Platform_display,StatisticalSearchingCodeValue_display,EResource_name_display";
148
149 query.append(
150 "&fl=LocalId_display,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,staffOnlyFlag"
151
152
153
154
155
156
157
158 + "," + holdingFields + "," + itemFields + "," + instanceFields + "," + patronFields
159 + "," + onixplFields + "," + licenseBinaryFields + "," + eInstanceFields);
160 }
161 LOG.debug("query---> " + query);
162 try {
163 String queryStr = query.toString().replaceAll(" ", "+");
164
165 searchParams.setSearchQuery(queryStr);
166 URL url = new URL(queryStr);
167 URLConnection urlc = null;
168 urlc = url.openConnection();
169 urlc.setDoOutput(true);
170 urlc.setAllowUserInteraction(false);
171 BufferedReader br = new BufferedReader(new InputStreamReader(urlc.getInputStream()));
172 StringBuilder sb = new StringBuilder();
173 String line;
174 while ((line = br.readLine()) != null) {
175 sb.append(line);
176 sb.append("\n");
177 }
178 br.close();
179 response = sb.toString();
180 } catch (Exception e) {
181 LOG.error("Exception:" + e.getMessage(), e);
182 }
183 return response;
184 }
185
186 public String getFieldList(String docType) {
187 String fieldList = "";
188 String holdingFields = HOLDINGS_FIELDS;
189 String itemFields = ITEM_FIELDS;
190 String instanceFields = INSTANCE_FIELDS;
191 String bibFields = BIB_FIELDS;
192
193 if (docType.equalsIgnoreCase(BIBLIOGRAPHIC)) {
194 fieldList = bibFields;
195
196 } else if (docType.equalsIgnoreCase(INSTANCE)) {
197 fieldList = instanceFields;
198
199 } else if (docType.equalsIgnoreCase(HOLDINGS)) {
200 fieldList = holdingFields;
201
202 } else if (docType.equalsIgnoreCase(ITEM)) {
203 fieldList = itemFields;
204 }
205 return fieldList;
206 }
207
208
209 public static void setDocSearchUrl(String docSearchUrl) {
210 }
211
212 public static String getDocSearchUrl() {
213 return docSearchUrl;
214 }
215
216 public String buildQuery(SearchParams searchParams) {
217 StringBuffer query = new StringBuffer();
218 String searchType = searchParams.getSearchType();
219 query.append(SolrServerManager.getInstance().getSolrCoreURL() + "/select");
220 buildInitialQuery(query, searchParams);
221 if (searchParams.getSearchFieldsList().size() > 0) {
222 query.append("AND(");
223 }
224 query.append(buildQueryWithSearchParameters(searchParams.getSearchFieldsList()));
225 if (searchParams.getResultPageSize() != null) {
226 query.append("&rows=" + searchParams.getResultPageSize());
227 }
228 if (searchParams.getResultFromIndex() != null) {
229 query.append("&start=" + searchParams.getResultFromIndex());
230 }
231 List<String> facetFieldList = searchParams.getFacetFieldList();
232 query.append(buildQueryWithFacetParameters(facetFieldList, 1, 10));
233 query.append(buildQueryWithSortFields(searchParams.getSortField(), searchParams.getSortOrder()));
234 query.append(buildQueryWithFieldListParameters(searchParams.getFieldList()));
235 Map<String, String> facetTermsMap = searchParams.getFacetTermsMap();
236 query.append(buildFilterQuery(facetTermsMap));
237
238 return query.toString();
239 }
240
241
242 public String buildQueryWithSearchParameters(List<SearchCondition> searchFieldsList) {
243 SearchCondition docSearchFieldsDTO = null;
244 StringBuffer queryStringbuffer = new StringBuffer();
245 StringBuffer highlightBuffer = new StringBuffer("&hl.fl=");
246 if (searchFieldsList != null && searchFieldsList.size() > 0) {
247
248 for (int i = 0; i < searchFieldsList.size(); i++) {
249 int searchScopeAddLimit = i;
250 docSearchFieldsDTO = searchFieldsList.get(i);
251 if (docSearchFieldsDTO.getOperator() != null) {
252
253 }
254 queryStringbuffer.append("(");
255 if (docSearchFieldsDTO.getDocField().equalsIgnoreCase("all")) {
256 queryStringbuffer.append("all_text");
257 highlightBuffer.append("*");
258
259 } else {
260 queryStringbuffer.append(docSearchFieldsDTO.getDocField());
261 highlightBuffer.append(docSearchFieldsDTO.getDocField());
262
263
264 if (i != searchFieldsList.size() - 1) {
265 highlightBuffer.append(",");
266 }
267 }
268 queryStringbuffer.append(":");
269 String searchScope = docSearchFieldsDTO.getSearchScope();
270 String searchText = docSearchFieldsDTO.getSearchText();
271 String searchOperator = docSearchFieldsDTO.getOperator();
272
273 LOG.debug("searchText-->" + searchText);
274
275
276 String modifiedSearchText = getModifiedText(searchText);
277 String searchTextVal = null;
278 if (modifiedSearchText.length() > 0) {
279 queryStringbuffer.append("(");
280 if (searchScope.equalsIgnoreCase("AND")) {
281 modifiedSearchText = modifiedSearchText.replaceAll("\\s+", " ");
282 searchTextVal = modifiedSearchText.trim().replace(" ", " AND ");
283 } else if (searchScope.equalsIgnoreCase("OR")) {
284 modifiedSearchText = modifiedSearchText.replaceAll("\\s+", " ");
285 searchTextVal = modifiedSearchText.trim().replace(" ", " OR ");
286 } else if (searchScope.equalsIgnoreCase("phrase")) {
287 searchTextVal = "\"" + searchText + "\"";
288 }
289 try {
290 searchTextVal = URLEncoder.encode(searchTextVal, "UTF-8");
291 } catch (UnsupportedEncodingException e) {
292 e.printStackTrace();
293 }
294 queryStringbuffer.append(searchTextVal);
295 LOG.debug("searchTextVal............" + searchTextVal + "........" + queryStringbuffer.toString());
296 queryStringbuffer.append(")");
297 }
298 queryStringbuffer.append(")");
299 ++searchScopeAddLimit;
300 if (searchScopeAddLimit != searchFieldsList.size()) {
301 queryStringbuffer.append(searchOperator);
302 }
303 }
304 queryStringbuffer.append(")");
305 String highLight = highlightBuffer.toString().replace("LocalId_search", "LocalId_display");
306 queryStringbuffer.append(highLight);
307
308 queryStringbuffer.append("&hl=true");
309 }
310
311
312 return queryStringbuffer.toString();
313 }
314
315 public String buildQueryWithFacetParameters(List<String> facetsParametersList, int facetMinCount, int facetLimit) {
316 String facetFieldName = "";
317 String queryWithFacetParameters = "";
318 if (facetsParametersList != null) {
319 StringBuffer facetsQueryStringbuffer = new StringBuffer();
320
321 facetsQueryStringbuffer.append("&facet=true");
322
323 facetsQueryStringbuffer.append("&facet.mincount=" + facetMinCount);
324
325 facetsQueryStringbuffer.append("&");
326
327 for (int i = 0; i < facetsParametersList.size(); i++) {
328 facetFieldName = facetsParametersList.get(i);
329 facetsQueryStringbuffer.append("facet.field=" + facetFieldName);
330 facetsQueryStringbuffer.append("&");
331
332 }
333 queryWithFacetParameters = facetsQueryStringbuffer.substring(0, facetsQueryStringbuffer.length() - 1);
334 }
335 return queryWithFacetParameters;
336 }
337
338
339 public String buildQueryWithSortFields(String sortField, String sortOrder) {
340 StringBuffer sortFieldsQuery = new StringBuffer();
341 if (null != sortField) {
342 sortFieldsQuery.append("&");
343 sortFieldsQuery.append("sort=");
344 sortFieldsQuery.append(sortField);
345 if (null != sortOrder) {
346 sortFieldsQuery.append(" ");
347 sortFieldsQuery.append(sortOrder);
348 }
349 }
350 return sortFieldsQuery.toString();
351 }
352
353 public String buildQueryWithFieldListParameters(List<String> fieldsList) {
354 String queryWithFieldListParameters = "";
355 if (fieldsList != null) {
356 StringBuffer fieldsListQueryStringbuffer = new StringBuffer();
357 fieldsListQueryStringbuffer.append("&");
358 fieldsListQueryStringbuffer.append("fl=");
359 for (int i = 0; i < fieldsList.size(); i++) {
360 fieldsListQueryStringbuffer.append(fieldsList.get(i));
361 fieldsListQueryStringbuffer.append(",");
362 }
363 queryWithFieldListParameters = fieldsListQueryStringbuffer
364 .substring(0, fieldsListQueryStringbuffer.length() - 1);
365 }
366 return queryWithFieldListParameters;
367 }
368
369 public static String convertListToStringFieldValues(Map<String, String> map) {
370 StringBuffer sb = new StringBuffer();
371 Set set = map.keySet();
372 Iterator<String> ite = set.iterator();
373 while (ite.hasNext()) {
374 sb.append(ite.next());
375 sb.append("|");
376 }
377 String str = sb.toString();
378 if (str != null && str.length() > 0) {
379 str = str.substring(0, str.length() - 1);
380 }
381 return str;
382 }
383
384 public String buildFilterQuery(Map<String, String> facetTermsMap) {
385 String filterQuery = "";
386 int temp = 0;
387 int tokenInt = 0;
388 if ((null != facetTermsMap) && (facetTermsMap.size() > 0)) {
389
390 String facetTerms = convertListToStringFieldValues(facetTermsMap);
391 StringBuffer facetQueryTemp = new StringBuffer();
392 facetQueryTemp.append("&terms=" + facetTerms);
393 facetQueryTemp.append("&fq=");
394 StringTokenizer sttoken = new StringTokenizer(facetTerms, "|");
395 String token;
396 while (sttoken.hasMoreElements()) {
397 token = sttoken.nextToken();
398 facetQueryTemp.append("(");
399 facetQueryTemp.append(facetTermsMap.get(token));
400 facetQueryTemp.append(":\"");
401 facetQueryTemp.append(token);
402 facetQueryTemp.append("\")");
403 facetQueryTemp.append("AND");
404 }
405 if (facetQueryTemp.length() > 0) {
406 filterQuery = (facetQueryTemp.toString().substring(0, facetQueryTemp.toString().length() - 3));
407 }
408 }
409 return filterQuery;
410 }
411
412
413
414
415
416
417 private void buildInitialQuery(StringBuffer query, SearchParams searchParams) {
418 query.append("?q=");
419
420 if (searchParams.getDocFormat().equalsIgnoreCase("marc")) {
421 query.append("((DocType:" + searchParams.getDocType() + ")" + "OR(DocType:item))");
422 } else {
423 query.append("(DocType:" + searchParams.getDocType() + ")");
424 }
425
426 if (searchParams.getDocFormat() != null && !searchParams.getDocFormat().equalsIgnoreCase("all")) {
427 if ("dublin".equals(searchParams.getDocFormat())) {
428 searchParams.setDocFormat("dublin");
429 }
430 query.append("AND(DocFormat:" + searchParams.getDocFormat() + ")");
431 }
432 }
433
434 private String getModifiedText(String searchText) {
435 StringBuffer modifiedText = new StringBuffer();
436 StringCharacterIterator stringCharacterIterator = new StringCharacterIterator(searchText);
437 char character = stringCharacterIterator.current();
438 while (character != CharacterIterator.DONE) {
439
440 if (character == '\\') {
441 modifiedText.append("\\\\");
442 } else if (character == '?') {
443 modifiedText.append("\\?");
444 } else if (character == '*') {
445 modifiedText.append("\\*");
446 } else if (character == '+') {
447 modifiedText.append("\\+");
448 } else if (character == ':') {
449 modifiedText.append("\\:");
450 } else if (character == '{') {
451 modifiedText.append("\\{");
452 } else if (character == '}') {
453 modifiedText.append("\\}");
454 } else if (character == '[') {
455 modifiedText.append("\\[");
456 } else if (character == ']') {
457 modifiedText.append("\\]");
458 } else if (character == '(') {
459 modifiedText.append("\\(");
460 } else if (character == ')') {
461 modifiedText.append("\\)");
462 } else if (character == '^') {
463 modifiedText.append("\\^");
464 } else if (character == '~') {
465 modifiedText.append("\\~");
466 } else if (character == '-') {
467 modifiedText.append("\\-");
468 } else if (character == '!') {
469 modifiedText.append("\\!");
470 } else if (character == '\'') {
471 modifiedText.append("\\'");
472 } else if (character == '@') {
473 modifiedText.append("\\@");
474 } else if (character == '#') {
475 modifiedText.append("\\#");
476 } else if (character == '$') {
477 modifiedText.append("\\$");
478 } else if (character == '%') {
479 modifiedText.append("\\%");
480 } else {
481
482
483 modifiedText.append(character);
484 }
485 character = stringCharacterIterator.next();
486 }
487
488 return modifiedText.toString().toLowerCase();
489 }
490
491 }