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