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