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 queryStringbuffer.append(docSearchFieldsDTO.getOperator());
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 searchText = searchText.toLowerCase();
274 LOG.debug("searchText-->" + searchText);
275 searchText = searchText.replaceAll("[~!(){}\\[\\]':]+"," ");
276 String searchTextVal = null;
277 if (searchText.length() > 0) {
278 queryStringbuffer.append("(");
279 if (searchScope.equalsIgnoreCase("AND")) {
280 searchText = searchText.replaceAll("\\s+", " ");
281 searchTextVal = searchText.trim().replace(" ", " AND ");
282 }
283 else if (searchScope.equalsIgnoreCase("OR")) {
284 searchText = searchText.replaceAll("\\s+", " ");
285 searchTextVal = searchText.trim().replace(" ", " OR ");
286 }
287 else if (searchScope.equalsIgnoreCase("phrase")) {
288 searchTextVal = "\"" + searchText + "\"";
289 }
290 try {
291 searchTextVal = URLEncoder.encode(searchTextVal, "UTF-8");
292 }
293 catch (UnsupportedEncodingException e) {
294 e.printStackTrace();
295 }
296 queryStringbuffer.append(searchTextVal);
297 LOG.debug("searchTextVal............" + searchTextVal + "........" + queryStringbuffer.toString());
298 queryStringbuffer.append(")");
299 }
300 queryStringbuffer.append(")");
301 ++searchScopeAddLimit;
302 if (searchScopeAddLimit != searchFieldsList.size()) {
303 queryStringbuffer.append(searchScope);
304 }
305 }
306 queryStringbuffer.append(")");
307 queryStringbuffer.append(highlightBuffer.toString());
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 }
424 else {
425 query.append("(DocType:" + searchParams.getDocType() + ")");
426 }
427
428 if (searchParams.getDocFormat() != null && !searchParams.getDocFormat().equalsIgnoreCase("all")) {
429 if ("dublin".equals(searchParams.getDocFormat())) {
430 searchParams.setDocFormat("dublin");
431 }
432 query.append("AND(DocFormat:" + searchParams.getDocFormat() + ")");
433 }
434 }
435
436 }