1   package org.kuali.ole.docstore.engine.service.search;
2   
3   import org.apache.commons.lang.StringUtils;
4   import org.apache.solr.client.solrj.SolrRequest;
5   import org.apache.solr.client.solrj.SolrServer;
6   import org.apache.solr.client.solrj.SolrServerException;
7   import org.apache.solr.client.solrj.response.*;
8   import org.apache.solr.common.SolrDocument;
9   import org.apache.solr.common.SolrDocumentList;
10  import org.kuali.ole.DocumentUniqueIDPrefix;
11  import org.kuali.ole.docstore.common.document.*;
12  import org.kuali.ole.docstore.common.exception.DocstoreIndexException;
13  import org.kuali.ole.docstore.common.search.*;
14  import org.kuali.ole.docstore.common.search.FacetResultField;
15  import org.kuali.ole.docstore.discovery.service.SolrServerManager;
16  import org.kuali.ole.docstore.engine.service.index.solr.BibConstants;
17  import org.kuali.ole.docstore.model.enums.DocType;
18  import org.slf4j.Logger;
19  import org.slf4j.LoggerFactory;
20  import org.apache.solr.client.solrj.SolrQuery;
21  import org.springframework.util.CollectionUtils;
22  
23  import java.text.CharacterIterator;
24  import java.text.StringCharacterIterator;
25  import java.util.*;
26  
27  
28  
29  
30  
31  
32  
33  
34  public class DocstoreSolrSearchService implements DocstoreSearchService {
35  
36      private static final Logger LOG = LoggerFactory.getLogger(DocstoreSolrSearchService.class);
37  
38      private static Map<String, String> searchFieldsMap = new HashMap<>();
39      private static Map<String, String> searchResultFieldsMap = new HashMap<>();
40  
41      static {
42          searchFieldsMap.put(Bib.ID, "id");
43          searchFieldsMap.put(Bib.AUTHOR, "Author_search");
44          searchFieldsMap.put(Bib.TITLE, "Title_search");
45          searchFieldsMap.put(Bib.PUBLICATIONDATE, "PublicationDate_search");
46          searchFieldsMap.put(Bib.PUBLISHER, "Publisher_search");
47          searchFieldsMap.put(Bib.ISBN, "ISBN_search");
48          searchFieldsMap.put(Bib.ISSN, "ISSN_search");
49          searchFieldsMap.put(Bib.SUBJECT, "Subject_search");
50          searchFieldsMap.put(Bib.EDITION, "Edition_search");
51          searchFieldsMap.put(Bib.DESCRIPTION, "Description_search");
52          searchFieldsMap.put(Bib.FORMAT, "Format_search");
53          searchFieldsMap.put(Bib.LANGUAGE, "Language_search");
54          searchFieldsMap.put(Bib.BIBIDENTIFIER, "bibIdentifier");
55          searchFieldsMap.put(Holdings.HOLDINGSIDENTIFIER, "holdingsIdentifier");
56          searchFieldsMap.put(Holdings.LOCATION_NAME, "Location_search");
57          searchFieldsMap.put(Holdings.LOCATION_LEVEL1, "Location_search");
58          searchFieldsMap.put(Holdings.LOCATION_LEVEL2, "Location_search");
59          searchFieldsMap.put(Holdings.LOCATION_LEVEL3, "Location_search");
60          searchFieldsMap.put(Holdings.LOCATION_LEVEL4, "Location_search");
61          searchFieldsMap.put(Holdings.LOCATION_LEVEL5, "Location_search");
62          searchFieldsMap.put(Holdings.CALL_NUMBER, "CallNumber_search");
63          searchFieldsMap.put(Holdings.CALLNUMBER_PREFIX, "CallNumberPrefix_search");
64          searchFieldsMap.put(Holdings.CALLNUMBER_TYPE, "CallNumberType_search");
65          searchFieldsMap.put(Holdings.COPY_NUMBER, "CopyNumber_search");
66          searchFieldsMap.put(Item.ITEMIDENTIFIER, "ItemIdentifier_search");
67          searchFieldsMap.put(Item.SHELVING_ORDER, "ShelvingOrder_search");
68          searchFieldsMap.put(Item.ITEM_BARCODE, "ItemBarcode_search");
69          searchFieldsMap.put(Item.ENUMERATION, "Enumeration_search");
70          searchFieldsMap.put(Item.CHRONOLOGY, "Chronology_search");
71          searchFieldsMap.put(Item.ITEM_TYPE, "ItemTypeCodeValue_search");
72          searchFieldsMap.put(Item.VOLUME_NUMBER, "VolumeNumber_search");
73          searchFieldsMap.put(Item.ITEM_STATUS, "ItemStatus_search");
74          searchFieldsMap.put(Item.DONOR_CODE, "DonorCode_search");
75          searchFieldsMap.put(Item.DONOR_NOTE, "DonorNote_display");
76          searchFieldsMap.put(Item.DONOR_PUBLIC, "DonorPublic_display");
77          searchFieldsMap.put(Item.HOLDINGS_CALL_NUMBER, "HoldingsCallNumber_search");
78          searchFieldsMap.put(Item.HOLDINGS_CALL_NUMBER_PREFIX, "CallNumberPrefix_search");
79          searchFieldsMap.put(Item.HOLDINGS_CALL_NUMBER_TYPE, "CallNumberType_search");
80          searchFieldsMap.put(Item.HOLDINGS_COPY_NUMBER, "HoldingsCopyNumber_search");
81          searchFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL1, "HoldingsLocation_search");
82          searchFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL2, "HoldingsLocation_search");
83          searchFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL3, "HoldingsLocation_search");
84          searchFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL4, "HoldingsLocation_search");
85          searchFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL5, "HoldingsLocation_search");
86          searchFieldsMap.put(Item.VENDOR_LINE_ITEM_IDENTIFIER, "VendorLineItemIdentifier_search");
87          searchFieldsMap.put(EHoldings.ACCESS_STATUS, "AccessStatus_search");
88          searchFieldsMap.put(EHoldings.URL, "URL_search");
89          searchFieldsMap.put(EHoldings.PERSISTENT_LINK, "Persist_Link_search");
90          searchFieldsMap.put(EHoldings.LINK_TEXT, "Link_Text_search");
91          searchFieldsMap.put(EHoldings.PUBLIC_DISPLAY_NOTE, "Public_Note_display");
92          searchFieldsMap.put(EHoldings.COVERAGE_START_DATE, "CoverageDate_display");
93          searchFieldsMap.put(EHoldings.COVERAGE_END_DATE, "CoverageDate_display");
94          searchFieldsMap.put(EHoldings.STATISTICAL_CODE, "StatisticalSearchingCodeValue_display");
95          searchFieldsMap.put(EHoldings.PLATFORM, "Platform_display");
96  
97          searchResultFieldsMap.put(Bib.ID, "id");
98          searchResultFieldsMap.put(Bib.AUTHOR, "Author_display");
99          searchResultFieldsMap.put(Bib.TITLE, "Title_display");
100         searchResultFieldsMap.put(Bib.PUBLICATIONDATE, "PublicationDate_display");
101         searchResultFieldsMap.put(Bib.PUBLISHER, "Publisher_display");
102         searchResultFieldsMap.put(Bib.ISBN, "ISBN_display");
103         searchResultFieldsMap.put(Bib.ISSN, "ISSN_display");
104         searchResultFieldsMap.put(Bib.SUBJECT, "Subject_display");
105         searchResultFieldsMap.put(Bib.EDITION, "Edition_display");
106         searchResultFieldsMap.put(Bib.DESCRIPTION, "Description_display");
107         searchResultFieldsMap.put(Bib.FORMAT, "Format_display");
108         searchResultFieldsMap.put(Bib.LANGUAGE, "Language_display");
109         searchResultFieldsMap.put(Bib.BIBIDENTIFIER, "bibIdentifier");
110         searchResultFieldsMap.put(Holdings.HOLDINGSIDENTIFIER, "holdingsIdentifier");
111         searchResultFieldsMap.put(Holdings.LOCATION_NAME, "Location_display");
112         searchResultFieldsMap.put(Holdings.LOCATION_LEVEL1, "Location_display");
113         searchResultFieldsMap.put(Holdings.LOCATION_LEVEL2, "Location_display");
114         searchResultFieldsMap.put(Holdings.LOCATION_LEVEL3, "Location_display");
115         searchResultFieldsMap.put(Holdings.LOCATION_LEVEL4, "Location_display");
116         searchResultFieldsMap.put(Holdings.LOCATION_LEVEL5, "Location_display");
117         searchResultFieldsMap.put(Holdings.CALL_NUMBER, "CallNumber_display");
118         searchResultFieldsMap.put(Holdings.CALLNUMBER_PREFIX, "CallNumberPrefix_display");
119         searchResultFieldsMap.put(Holdings.CALLNUMBER_TYPE, "CallNumberType_display");
120         searchResultFieldsMap.put(Holdings.COPY_NUMBER, "CopyNumber_display");
121         searchResultFieldsMap.put(Item.ITEMIDENTIFIER, "itemIdentifier");
122         searchResultFieldsMap.put(Item.SHELVING_ORDER, "ShelvingOrder_display");
123         searchResultFieldsMap.put(Item.ITEM_BARCODE, "ItemBarcode_display");
124         searchResultFieldsMap.put(Item.ENUMERATION, "Enumeration_display");
125         searchResultFieldsMap.put(Item.CHRONOLOGY, "Chronology_display");
126         searchResultFieldsMap.put(Item.ITEM_TYPE, "ItemTypeCodeValue_display");
127         searchResultFieldsMap.put(Item.VOLUME_NUMBER, "VolumeNumber_display");
128         searchResultFieldsMap.put(Item.ITEM_STATUS, "ItemStatus_display");
129         searchResultFieldsMap.put(Item.DONOR_CODE, "DonorCode_display");
130         searchResultFieldsMap.put(Item.DONOR_NOTE, "DonorNote_display");
131         searchResultFieldsMap.put(Item.DONOR_PUBLIC, "DonorPublic_display");
132         searchResultFieldsMap.put(Item.HOLDINGS_CALL_NUMBER, "HoldingsCallNumber_display");
133         searchResultFieldsMap.put(Item.HOLDINGS_CALL_NUMBER_PREFIX, "CallNumberPrefix_display");
134         searchResultFieldsMap.put(Item.HOLDINGS_CALL_NUMBER_TYPE, "CallNumberType_display");
135         searchResultFieldsMap.put(Item.HOLDINGS_COPY_NUMBER, "HoldingsCopyNumber_display");
136         searchResultFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL1, "HoldingsLocation_display");
137         searchResultFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL2, "HoldingsLocation_display");
138         searchResultFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL3, "HoldingsLocation_display");
139         searchResultFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL4, "HoldingsLocation_display");
140         searchResultFieldsMap.put(Item.HOLDINGS_LOCATION_LEVEL5, "HoldingsLocation_display");
141         searchResultFieldsMap.put(Item.VENDOR_LINE_ITEM_IDENTIFIER, "VendorLineItemIdentifier_display");
142         searchResultFieldsMap.put(EHoldings.ACCESS_STATUS, "AccessStatus_display");
143         searchResultFieldsMap.put(EHoldings.URL, "URL_display");
144         searchResultFieldsMap.put(EHoldings.PERSISTENT_LINK, "Persist_Link_display");
145         searchResultFieldsMap.put(EHoldings.LINK_TEXT, "Link_Text_display");
146         searchResultFieldsMap.put(EHoldings.PUBLIC_DISPLAY_NOTE, "Public_Note_display");
147         searchResultFieldsMap.put(EHoldings.PUBLIC_DISPLAY_NOTE, "CoverageDate_display");
148         searchResultFieldsMap.put(EHoldings.STATISTICAL_CODE, "StatisticalSearchingCodeValue_display");
149         searchResultFieldsMap.put(EHoldings.PLATFORM, "Platform_display");
150     }
151 
152     @Override
153     public SearchResponse search(SearchParams searchParams) {
154         try {
155             SolrQuery solrQuery = new SolrQuery();
156             SolrServer server = SolrServerManager.getInstance().getSolrServer();
157             String query = buildQueryWithSearchParams(searchParams);
158             solrQuery.setQuery(query);
159             if (!CollectionUtils.isEmpty(searchParams.getSortConditions())) {
160                 buildQueryWithSortConditions(solrQuery, searchParams.getSortConditions());
161             }
162             if (searchParams.getPageSize() != 0) {
163                 solrQuery.setRows(searchParams.getPageSize());
164             }
165             solrQuery.setStart(searchParams.getStartIndex());
166             if (!CollectionUtils.isEmpty(searchParams.getSearchResultFields())) {
167                 solrQuery.setFields(buildQueryWithResultFieldsLists(searchParams));
168             }
169             if (!CollectionUtils.isEmpty(searchParams.getFacetFields())) {
170                 for(String facetField : searchParams.getFacetFields()) {
171                     solrQuery.addFacetField(facetField);
172                 }
173                 solrQuery.setFacet(true);
174                 if(StringUtils.isNotEmpty(searchParams.getFacetPrefix())) {
175                     if(!searchParams.getFacetPrefix().equalsIgnoreCase("all")) {
176                         solrQuery.setFacetPrefix(searchParams.getFacetPrefix().toLowerCase());
177                     }
178                 }
179 
180                     solrQuery.setFacetLimit(searchParams.getFacetLimit());
181 
182                 solrQuery.setFacetMinCount(1);
183                 solrQuery.setFacetSort(searchParams.getFacetSort());
184                 solrQuery.set("facet.offset", searchParams.getFacetOffset());
185             }
186 
187             if (!CollectionUtils.isEmpty(searchParams.getFacetConditions())) {
188                buildQueryWithFacetConditions(solrQuery, searchParams.getFacetConditions());
189             }
190             LOG.info("Executing solr query :" +solrQuery.toString());
191             QueryResponse response = server.query(solrQuery, SolrRequest.METHOD.POST);
192             return buildSearchResponse(response, searchParams);
193         } catch (SolrServerException ex) {
194             LOG.info("Exception :", ex);
195             throw new DocstoreIndexException(ex.getMessage());
196         }
197     }
198 
199     private void buildQueryWithFacetConditions(SolrQuery solrQuery, List<FacetCondition> facetConditions) {
200 
201         StringBuffer facetTerms = new StringBuffer();
202         StringBuffer filterQuery = new StringBuffer();
203         int facetConditionsSize = facetConditions.size();
204         for (int i=0; i < facetConditionsSize; i++) {
205             FacetCondition facetCondition = facetConditions.get(i);
206             if(StringUtils.isNotEmpty(facetCondition.getFieldValue())) {
207                 facetTerms.append(facetCondition.getFieldValue());
208                 if(i != (facetConditionsSize-1)) {
209                     facetTerms.append("|");
210                 }
211             }
212             if(StringUtils.isNotEmpty(facetCondition.getFieldValue())) {
213                 filterQuery.append(facetCondition.getFieldName());
214                 filterQuery.append(":");
215                 filterQuery.append("\"" + facetCondition.getFieldValue() + "\"");
216 
217                 if(i != (facetConditionsSize-1)) {
218                     filterQuery.append(" AND ");
219                 }
220             }
221         }
222 
223         solrQuery.setTermsRegex(facetTerms.toString());
224         solrQuery.setFilterQueries(filterQuery.toString());
225     }
226 
227 
228     private SearchResponse buildSearchResponse(QueryResponse response, SearchParams searchParams) {
229         SolrDocumentList results = response.getResults();
230         List<org.apache.solr.client.solrj.response.FacetField> facetFields = response.getFacetFields();
231         String searchConditionDocType = null;
232         SearchResponse searchResponse = new SearchResponse();
233         List<SearchResult> searchResults = new ArrayList<>();
234         if (!CollectionUtils.isEmpty(searchParams.getSearchConditions())) {
235             for(SearchCondition searchCondition:searchParams.getSearchConditions()){
236                 if(searchCondition.getSearchField()!=null){
237                     searchConditionDocType = searchCondition.getSearchField().getDocType();
238                     break;
239                 }
240             }
241         }
242         List<SearchResultField> searchResultFields = new ArrayList<SearchResultField>();
243         if (CollectionUtils.isEmpty(searchParams.getSearchResultFields())) {
244             searchResultFields = getDefaultSearchResultFields(searchParams);
245         } else {
246             searchResultFields = searchParams.getSearchResultFields();
247         }
248         for (SolrDocument solrDocument : results) {
249             SolrDocument bibSolrDocument = null;
250             
251             
252             SearchResult searchResult = new SearchResult();
253             List<SearchResultField> newSearchResultFields = new ArrayList<SearchResultField>();
254             for (SearchResultField searchResultField : searchResultFields) {
255                 SearchResultField newSearchResultField = new SearchResultField();
256                 if (StringUtils.isBlank(searchConditionDocType) || searchResultField.getDocType().equalsIgnoreCase(searchConditionDocType)) {
257                     String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
258                     if (fieldValue.equalsIgnoreCase("id") || fieldValue.equalsIgnoreCase("bibIdentifier")
259                             || fieldValue.equalsIgnoreCase("holdingsIdentifier")
260                             || fieldValue.equalsIgnoreCase("itemIdentifier")
261                             || fieldValue.equalsIgnoreCase("ItemIdentifier_display")
262                             || fieldValue.equalsIgnoreCase("DonorCode_search")
263                             || fieldValue.equalsIgnoreCase("DonorCode_display")
264                             || fieldValue.equalsIgnoreCase("ISBN_search")
265                             || fieldValue.equalsIgnoreCase("ISBN_display")
266                             || fieldValue.equalsIgnoreCase("ISSN_search")
267                             || fieldValue.equalsIgnoreCase("ISSN_display")) {
268                         newSearchResultFields.addAll(buildSearchResultsForIds(solrDocument, searchResultField));
269                         continue;
270                     }
271                     String resultFieldValue = getSolrFieldValue(solrDocument, fieldValue);
272                     if (StringUtils.isNotBlank(resultFieldValue)) {
273                         newSearchResultField.setFieldValue(resultFieldValue);
274                     }
275                 } else {
276                     if (searchResultField.getDocType().equalsIgnoreCase(HOLDINGS)) {
277                         if (searchConditionDocType.equalsIgnoreCase(ITEM) || searchConditionDocType.equalsIgnoreCase(BIBLIOGRAPHIC)) {
278                             newSearchResultFields.addAll(buildHoldingsSearchResults(solrDocument, searchResultField));
279                             continue;
280                         }
281                     } else if (searchResultField.getDocType().equalsIgnoreCase(BIBLIOGRAPHIC)) {
282                         if (searchConditionDocType.equalsIgnoreCase(ITEM) || searchConditionDocType.equalsIgnoreCase(HOLDINGS) || searchConditionDocType.equalsIgnoreCase(EHOLDINGS) ) {
283                              newSearchResultFields.addAll(buildBibSearchResults(solrDocument, searchResultField));
284                             continue;
285                         }
286                     } else if (searchResultField.getDocType().equalsIgnoreCase(ITEM)) {
287                         if (searchConditionDocType.equalsIgnoreCase(HOLDINGS)) {
288                             newSearchResultFields.addAll(buildItemSearchResultsForHoldings(solrDocument, searchResultField));
289                             continue;
290                         } else if (searchConditionDocType.equalsIgnoreCase(BIBLIOGRAPHIC)) {
291                             newSearchResultFields.addAll(buildItemSearchResultsForBib(solrDocument, searchResultField));
292                             continue;
293                         }
294                     } else if (searchConditionDocType.equalsIgnoreCase(EHOLDINGS)) {
295                         if (bibSolrDocument == null) {
296                             bibSolrDocument = getBibRecord((String) solrDocument.getFieldValue("bibIdentifier"));
297                         }
298                         String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
299                         String resultFieldValue = getSolrFieldValue(bibSolrDocument, fieldValue);
300                         if (StringUtils.isNotBlank(resultFieldValue)) {
301                             newSearchResultField.setFieldValue(resultFieldValue);
302                         }
303                     }
304                 }
305                 newSearchResultField.setDocType(searchResultField.getDocType());
306                 newSearchResultField.setFieldName(searchResultField.getFieldName());
307                 
308                 newSearchResultFields.add(newSearchResultField);
309             }
310             searchResult.getSearchResultFields().addAll(newSearchResultFields);
311             searchResults.add(searchResult);
312         }
313         searchResponse.getSearchResults().addAll(searchResults);
314         searchResponse.setTotalRecordCount((int) results.getNumFound());
315         if (searchParams.getPageSize() == 0) {
316             searchResponse.setPageSize(results.size());
317         } else {
318             searchResponse.setPageSize(searchParams.getPageSize());
319         }
320         searchResponse.setStartIndex(searchParams.getStartIndex());
321         searchResponse.setEndIndex(searchParams.getStartIndex() + searchParams.getPageSize());
322         FacetResult facetResult = new FacetResult();
323         if (!CollectionUtils.isEmpty(facetFields)) {
324 
325             for (org.apache.solr.client.solrj.response.FacetField facetField : facetFields) {
326 
327 
328                 FacetResultField facetFieldResult = new FacetResultField();
329                 facetFieldResult.setFieldName(facetField.getName());
330 
331                 if(facetField.getValues() != null) {
332                     for (org.apache.solr.client.solrj.response.FacetField.Count count : facetField.getValues()) {
333                         String valCount = String.valueOf(count.getCount());
334                         if(!valCount.equalsIgnoreCase("0")) {
335 
336                             ValueCount valueCount = new ValueCount();
337                             String fullValue = count.getName();
338                             String value = "";
339                             if(fullValue.contains("/r/n!@#$")) {
340                                 int index = fullValue.indexOf("/r/n!@#$");
341                                 value = fullValue.substring(index + 8, fullValue.length());
342                             }
343                             else {
344                                 value = fullValue;
345                             }
346                             valueCount.setValue(value);
347                             valueCount.setFullValue(count.getName());
348                             valueCount.setCount(valCount);
349                             facetFieldResult.getValueCounts().add(valueCount);
350                         }
351                     }
352                 }
353 
354                 facetResult.getFacetResultFields().add(facetFieldResult);
355             }
356         }
357 
358         searchResponse.setFacetResult(facetResult);
359         searchResponse.setTime(response.getQTime());
360         return searchResponse;
361     }
362 
363     private List<SearchResultField> buildSearchResultsForIds(SolrDocument solrDocument, SearchResultField searchResultField) {
364         List<SearchResultField> newSearchResultFields = new ArrayList<SearchResultField>();
365         Object object = solrDocument.getFieldValue(searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName());
366         if (object instanceof String) {
367             SearchResultField newSearchResultField = new SearchResultField();
368             newSearchResultField.setDocType(searchResultField.getDocType());
369             newSearchResultField.setFieldName(searchResultField.getFieldName());
370             newSearchResultField.setFieldValue((String) object);
371             newSearchResultFields.add(newSearchResultField);
372         } else {
373             if (((List) object) != null) {
374                 for (Object identifier : (List) object) {
375                     SearchResultField newSearchResultField = new SearchResultField();
376                     newSearchResultField.setDocType(searchResultField.getDocType());
377                     newSearchResultField.setFieldName(searchResultField.getFieldName());
378                     newSearchResultField.setFieldValue((String) identifier);
379                     newSearchResultFields.add(newSearchResultField);
380                 }
381             }
382         }
383         return newSearchResultFields;
384     }
385 
386     private List<SearchResultField> buildBibSearchResults(SolrDocument solrDocument, SearchResultField searchResultField) {
387         List<SearchResultField> newSearchResultFields = new ArrayList<SearchResultField>();
388          Object object = solrDocument.getFieldValue("bibIdentifier");
389         if (object instanceof String) {
390              SearchResultField newSearchResultField = new SearchResultField();
391              SolrDocument bibSolrDocument = getBibRecord((String) object);
392             if (bibSolrDocument != null) {
393                 String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
394                 String resultFieldValue = getSolrFieldValue(bibSolrDocument, fieldValue);
395                 if (StringUtils.isNotBlank(resultFieldValue)) {
396                     newSearchResultField.setFieldValue(resultFieldValue);
397                 }
398                 newSearchResultField.setDocType(searchResultField.getDocType());
399                 newSearchResultField.setFieldName(searchResultField.getFieldName());
400                 
401                 newSearchResultFields.add(newSearchResultField);
402             }
403         } else {
404             if (((List) object) != null) {
405                 for (Object bibIdentifier : (List) object) {
406                     SearchResultField newSearchResultField = new SearchResultField();
407                     SolrDocument bibSolrDocument = getBibRecord((String) bibIdentifier);
408                     if (bibSolrDocument != null) {
409                         String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
410                         String resultFieldValue = getSolrFieldValue(bibSolrDocument, fieldValue);
411                         if (StringUtils.isNotBlank(resultFieldValue)) {
412                             newSearchResultField.setFieldValue(resultFieldValue);
413                         }
414                         newSearchResultField.setDocType(searchResultField.getDocType());
415                         newSearchResultField.setFieldName(searchResultField.getFieldName());
416                         
417                         newSearchResultFields.add(newSearchResultField);
418                     }
419                 }
420             }
421         }
422         return newSearchResultFields;
423     }
424 
425     private List<SearchResultField> buildItemSearchResultsForHoldings(SolrDocument solrDocument, SearchResultField searchResultField) {
426         List<SearchResultField> newSearchResultFields = new ArrayList<SearchResultField>();
427         Object object = solrDocument.getFieldValue("itemIdentifier");
428         if (object instanceof String) {
429             SearchResultField newSearchResultField = new SearchResultField();
430             SolrDocument itemSolrDocument = getItemRecord((String) object);
431             String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
432             String resultFieldValue = getSolrFieldValue(itemSolrDocument, fieldValue);
433             if (StringUtils.isNotBlank(resultFieldValue)) {
434                 newSearchResultField.setFieldValue(resultFieldValue);
435             }
436             newSearchResultField.setDocType(searchResultField.getDocType());
437             newSearchResultField.setFieldName(searchResultField.getFieldName());
438             
439             newSearchResultFields.add(newSearchResultField);
440         } else {
441             if (((List) object) != null) {
442                 for (Object identifier : (List) object) {
443                     SearchResultField newSearchResultField = new SearchResultField();
444                     SolrDocument itemSolrDocument = getItemRecord((String) identifier);
445                     String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
446                     String resultFieldValue = getSolrFieldValue(itemSolrDocument, fieldValue);
447                     if (StringUtils.isNotBlank(resultFieldValue)) {
448                         newSearchResultField.setFieldValue(resultFieldValue);
449                     }
450                     newSearchResultField.setDocType(searchResultField.getDocType());
451                     newSearchResultField.setFieldName(searchResultField.getFieldName());
452                     
453                     newSearchResultFields.add(newSearchResultField);
454                 }
455             }
456         }
457         return newSearchResultFields;
458     }
459 
460     private List<SearchResultField> buildItemSearchResultsForBib(SolrDocument solrDocument, SearchResultField searchResultField) {
461         List<SearchResultField> newSearchResultFields = new ArrayList<SearchResultField>();
462         Object holdingsObject = solrDocument.getFieldValue("holdingsIdentifier");
463         if (holdingsObject instanceof String) {
464             SearchResultField newSearchResultField = new SearchResultField();
465             SolrDocument holdingsSolrDocument = getHoldingsRecord((String) holdingsObject);
466             if (holdingsSolrDocument != null) {
467                 Object itemObject = holdingsSolrDocument.getFieldValue("itemIdentifier");
468                 if (itemObject instanceof String) {
469                     SolrDocument itemSolrDocument = getItemRecord((String) itemObject);
470                     String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
471                     String resultFieldValue = getSolrFieldValue(itemSolrDocument, fieldValue);
472                     if (StringUtils.isNotBlank(resultFieldValue)) {
473                         newSearchResultField.setFieldValue(resultFieldValue);
474                     }
475                     newSearchResultField.setDocType(searchResultField.getDocType());
476                     newSearchResultField.setFieldName(searchResultField.getFieldName());
477                     
478                     newSearchResultFields.add(newSearchResultField);
479                 } else {
480                     if (((List) itemObject) != null) {
481                         for (Object identifier : (List) itemObject) {
482                             SearchResultField newSearchResultField1 = new SearchResultField();
483                             SolrDocument itemSolrDocument = getItemRecord((String) identifier);
484                             String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
485                             String resultFieldValue = getSolrFieldValue(itemSolrDocument, fieldValue);
486                             if (StringUtils.isNotBlank(resultFieldValue)) {
487                                 newSearchResultField.setFieldValue(resultFieldValue);
488                             }
489                             newSearchResultField1.setDocType(searchResultField.getDocType());
490                             newSearchResultField1.setFieldName(searchResultField.getFieldName());
491                             
492                             newSearchResultFields.add(newSearchResultField1);
493                         }
494                     }
495                 }
496             }
497         } else {
498             if (((List) holdingsObject) != null) {
499                 for (Object identifier : (List) holdingsObject) {
500                     SearchResultField newSearchResultField = new SearchResultField();
501                     SolrDocument holdingsSolrDocument = getHoldingsRecord((String) identifier);
502                     if (holdingsSolrDocument != null) {
503                         Object itemObject = holdingsSolrDocument.getFieldValue("itemIdentifier");
504                         if (itemObject instanceof String) {
505                             SolrDocument itemSolrDocument = getItemRecord((String) itemObject);
506                             String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
507                             String resultFieldValue = getSolrFieldValue(itemSolrDocument, fieldValue);
508                             if (StringUtils.isNotBlank(resultFieldValue)) {
509                                 searchResultField.setFieldValue(resultFieldValue);
510                             }
511                             newSearchResultField.setDocType(searchResultField.getDocType());
512                             newSearchResultField.setFieldName(searchResultField.getFieldName());
513                             newSearchResultField.setFieldValue(searchResultField.getFieldValue());
514                             newSearchResultFields.add(newSearchResultField);
515                         } else {
516                             if (((List) itemObject) != null) {
517                                 for (Object itemIdentifier : (List) itemObject) {
518                                     SearchResultField newSearchResultField1 = new SearchResultField();
519                                     SolrDocument itemSolrDocument = getItemRecord((String) itemIdentifier);
520                                     String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
521                                     String resultFieldValue = getSolrFieldValue(itemSolrDocument, fieldValue);
522                                     if (StringUtils.isNotBlank(resultFieldValue)) {
523                                         searchResultField.setFieldValue(resultFieldValue);
524                                     }
525                                     newSearchResultField1.setDocType(searchResultField.getDocType());
526                                     newSearchResultField1.setFieldName(searchResultField.getFieldName());
527                                     newSearchResultField1.setFieldValue(searchResultField.getFieldValue());
528                                     newSearchResultFields.add(newSearchResultField1);
529                                 }
530                             }
531                         }
532                     }
533                 }
534             }
535         }
536         return newSearchResultFields;
537     }
538 
539     private List<SearchResultField> buildHoldingsSearchResults(SolrDocument solrDocument, SearchResultField searchResultField) {
540         List<SearchResultField> newSearchResultFields = new ArrayList<SearchResultField>();
541         Object object = solrDocument.getFieldValue("holdingsIdentifier");
542         if (object instanceof String) {
543             SearchResultField newSearchResultField = new SearchResultField();
544             SolrDocument holdingsSolrDocument = getHoldingsRecord((String) object);
545             if (holdingsSolrDocument != null) {
546                 String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
547                 String resultFieldValue = getSolrFieldValue(holdingsSolrDocument, fieldValue);
548                 if (StringUtils.isNotBlank(resultFieldValue)) {
549                     newSearchResultField.setFieldValue(resultFieldValue);
550                 }
551                 newSearchResultField.setDocType(searchResultField.getDocType());
552                 newSearchResultField.setFieldName(searchResultField.getFieldName());
553                 
554                 newSearchResultFields.add(newSearchResultField);
555             }
556         } else {
557             if (((List) object) != null) {
558                 for (Object identifier : (List) object) {
559                     SearchResultField newSearchResultField = new SearchResultField();
560                     SolrDocument holdingsSolrDocument = getHoldingsRecord((String) identifier);
561                     if (holdingsSolrDocument != null) {
562                         String fieldValue = searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultField.getFieldName().toUpperCase()) : searchResultField.getFieldName();
563                         String resultFieldValue = getSolrFieldValue(holdingsSolrDocument, fieldValue);
564                         if (StringUtils.isNotBlank(resultFieldValue)) {
565                             newSearchResultField.setFieldValue(resultFieldValue);
566                         }
567                         newSearchResultField.setDocType(searchResultField.getDocType());
568                         newSearchResultField.setFieldName(searchResultField.getFieldName());
569                         
570                         newSearchResultFields.add(newSearchResultField);
571                     }
572                 }
573             }
574         }
575         return newSearchResultFields;
576     }
577 
578     private String getSolrFieldValue(SolrDocument solrDocument, String fieldValue) {
579         Object obj = solrDocument.getFieldValue(fieldValue);
580         String resultFieldValue = null;
581         if (obj instanceof String) {
582             resultFieldValue = (String) obj;
583         } else if (obj instanceof Boolean) {
584             resultFieldValue = String.valueOf(obj);
585         } else if (obj instanceof Date) {
586             resultFieldValue = String.valueOf(obj);
587         } else if (obj instanceof List) {
588             if(fieldValue.endsWith("_display")) {
589                 if (((List) obj) != null) {
590                     StringBuilder resultFieldList = new StringBuilder();
591                     ArrayList<String> fields = (ArrayList<String>) obj;
592                     for(String s : fields) {
593                         resultFieldList.append(s);
594                         resultFieldList.append(", ");
595                     }
596                     resultFieldValue = resultFieldList.substring(0, (resultFieldList.length() -1));
597                 }
598             }
599             else {
600                 resultFieldValue = (String) ((List) obj).get(0);
601             }
602         }
603         return resultFieldValue;
604     }
605 
606     private List<SearchResultField> getDefaultSearchResultFields(SearchParams searchParams) {
607         String docType = null;
608         if (!CollectionUtils.isEmpty(searchParams.getSearchConditions())) {
609             docType = searchParams.getSearchConditions().get(0).getSearchField().getDocType();
610         }
611         List<SearchResultField> searchResultFields = new ArrayList<>();
612         if (StringUtils.isBlank(docType)) {
613             String allFields = BIB_FIELDS + "," + HOLDINGS_FIELDS + "," + ITEM_FIELDS;
614             for (String defaultField : getDefaultFields(allFields)) {
615                 SearchResultField searchResultField = new SearchResultField();
616                 searchResultField.setDocType(docType);
617                 searchResultField.setFieldName(defaultField);
618                 searchResultFields.add(searchResultField);
619             }
620         } else if (docType.equalsIgnoreCase(BIBLIOGRAPHIC)) {
621             for (String bibField : getDefaultFields(BIB_FIELDS)) {
622                 SearchResultField searchResultField = new SearchResultField();
623                 searchResultField.setDocType(docType);
624                 searchResultField.setFieldName(bibField);
625                 searchResultFields.add(searchResultField);
626             }
627         } else if (docType.equalsIgnoreCase(HOLDINGS)) {
628             for (String holdingsField : getDefaultFields(HOLDINGS_FIELDS)) {
629                 SearchResultField searchResultField = new SearchResultField();
630                 searchResultField.setDocType(docType);
631                 searchResultField.setFieldName(holdingsField);
632                 searchResultFields.add(searchResultField);
633             }
634         } else if (docType.equalsIgnoreCase(ITEM)) {
635             for (String itemField : getDefaultFields(ITEM_FIELDS)) {
636                 SearchResultField searchResultField = new SearchResultField();
637                 searchResultField.setDocType(docType);
638                 searchResultField.setFieldName(itemField);
639                 searchResultFields.add(searchResultField);
640             }
641         } else if (docType.equalsIgnoreCase(EHOLDINGS)) {
642             for (String itemField : getDefaultFields(EHOLDINGS_FIELDS)) {
643                 SearchResultField searchResultField = new SearchResultField();
644                 searchResultField.setDocType(docType);
645                 searchResultField.setFieldName(itemField);
646                 searchResultFields.add(searchResultField);
647             }
648         }
649         return searchResultFields;
650     }
651 
652     private List<String> getDefaultFields(String bibFields) {
653         return Arrays.asList(bibFields.split(","));
654     }
655 
656 
657     public String buildQueryWithSearchParams(SearchParams searchParams) {
658         return buildQueryWithSearchConditions(searchParams.getSearchConditions()) ;
659     }
660 
661     private SolrDocument getItemRecord(String itemIdentifier) {
662         try {
663             SolrDocument itemSolrDocument = null;
664             SearchParams searchParams = new SearchParams();
665             SearchField searchField = searchParams.buildSearchField("item", "itemIdentifier", itemIdentifier);
666             searchParams.getSearchConditions().add(searchParams.buildSearchCondition("none", searchField, null));
667             SolrQuery solrQuery = new SolrQuery();
668             SolrServer server = SolrServerManager.getInstance().getSolrServer();
669             solrQuery.setQuery(buildQueryWithSearchConditions(searchParams.getSearchConditions()));
670             QueryResponse response = server.query(solrQuery);
671             if (response.getResults().size() > 0) {
672                 itemSolrDocument = response.getResults().get(0);
673             }
674             return itemSolrDocument;
675         } catch (SolrServerException ex) {
676             LOG.info("Exception :", ex);
677             throw new DocstoreIndexException(ex.getMessage());
678         }
679     }
680 
681     private SolrDocument getBibRecord(String bibIdentifier) {
682         try {
683             SolrDocument bibSolrDocument = null;
684             SearchParams searchParams = new SearchParams();
685             SearchField searchField = searchParams.buildSearchField("bibliographic", "LocalId_search", DocumentUniqueIDPrefix.getDocumentId(bibIdentifier));
686             searchParams.getSearchConditions().add(searchParams.buildSearchCondition("none", searchField, null));
687             SolrQuery solrQuery = new SolrQuery();
688             SolrServer server = SolrServerManager.getInstance().getSolrServer();
689             solrQuery.setQuery(buildQueryWithSearchConditions(searchParams.getSearchConditions()));
690             QueryResponse response = server.query(solrQuery);
691             if (response.getResults().size() > 0) {
692                 bibSolrDocument = response.getResults().get(0);
693             }
694             return bibSolrDocument;
695         } catch (SolrServerException ex) {
696             LOG.info("Exception :", ex);
697             throw new DocstoreIndexException(ex.getMessage());
698         }
699     }
700 
701     private SolrDocument getHoldingsRecord(String holdingsIdentifier) {
702         try {
703             SolrDocument holdingsSolrDocument = null;
704             SearchParams searchParams = new SearchParams();
705             SearchField searchField = searchParams.buildSearchField("holdings", "holdingsIdentifier", holdingsIdentifier);
706             searchParams.getSearchConditions().add(searchParams.buildSearchCondition("none", searchField, null));
707             SolrQuery solrQuery = new SolrQuery();
708             SolrServer server = SolrServerManager.getInstance().getSolrServer();
709             solrQuery.setQuery(buildQueryWithSearchConditions(searchParams.getSearchConditions()));
710             QueryResponse response = server.query(solrQuery);
711             if (response.getResults().size() > 0) {
712                 holdingsSolrDocument = response.getResults().get(0);
713             }
714             return holdingsSolrDocument;
715         } catch (SolrServerException ex) {
716             LOG.info("Exception :", ex);
717             throw new DocstoreIndexException(ex.getMessage());
718         }
719     }
720 
721     private String buildQueryWithResultFieldsLists(SearchParams searchParams) {
722         String docType = null;
723         List<SearchResultField> searchResultFields = searchParams.getSearchResultFields();
724         if (!CollectionUtils.isEmpty(searchParams.getSearchConditions())) {
725             for(SearchCondition searchCondition:searchParams.getSearchConditions()){
726                 if(searchCondition.getSearchField()!=null){
727                     docType = searchCondition.getSearchField().getDocType();
728                     break;
729                 }
730             }
731         }
732         StringBuffer resultFieldsBuffer = new StringBuffer();
733         
734         
735         if (StringUtils.isBlank(docType)) {
736             if (!CollectionUtils.isEmpty(searchResultFields)) {
737                 for (int i = 0; i < searchResultFields.size(); i++) {
738                     resultFieldsBuffer.append(searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) : searchResultFields.get(i).getFieldName());
739                     if (i != searchResultFields.size() - 1) {
740                         resultFieldsBuffer.append(",");
741                     }
742                 }
743             } 
744 
745 
746         } else if (docType.equalsIgnoreCase(BIBLIOGRAPHIC)) {
747             if (!CollectionUtils.isEmpty(searchResultFields)) {
748                 for (int i = 0; i < searchResultFields.size(); i++) {
749                     if (searchResultFields.get(i).getDocType().equalsIgnoreCase(BIBLIOGRAPHIC)) {
750                         resultFieldsBuffer.append(searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) : searchResultFields.get(i).getFieldName());
751                         resultFieldsBuffer.append(",");
752                     }
753                 }
754                 resultFieldsBuffer.append(BIB_LINK_FIELDS);
755             } 
756 
757 
758         } else if (docType.equalsIgnoreCase(HOLDINGS)) {
759             if (!CollectionUtils.isEmpty(searchResultFields)) {
760                 for (int i = 0; i < searchResultFields.size(); i++) {
761                     if (searchResultFields.get(i).getDocType().equalsIgnoreCase(HOLDINGS)) {
762                         resultFieldsBuffer.append(searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) : searchResultFields.get(i).getFieldName());
763                         resultFieldsBuffer.append(",");
764                     }
765                 }
766                 resultFieldsBuffer.append(HOLDINGS_LINK_FIELDS);
767             } 
768 
769 
770 
771         } else if (docType.equalsIgnoreCase(ITEM)) {
772             if (!CollectionUtils.isEmpty(searchResultFields)) {
773                 for (int i = 0; i < searchResultFields.size(); i++) {
774                     if (searchResultFields.get(i).getDocType().equalsIgnoreCase(ITEM)) {
775                         resultFieldsBuffer.append(searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) : searchResultFields.get(i).getFieldName());
776                         resultFieldsBuffer.append(",");
777                     }
778                 }
779                 resultFieldsBuffer.append(ITEM_LINK_FIELDS);
780             } 
781 
782 
783         } else if (docType.equalsIgnoreCase(EHOLDINGS)) {
784             if (!CollectionUtils.isEmpty(searchResultFields)) {
785                 for (int i = 0; i < searchResultFields.size(); i++) {
786                     if (searchResultFields.get(i).getDocType().equalsIgnoreCase(EHOLDINGS)) {
787                         resultFieldsBuffer.append(searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) != null ? searchResultFieldsMap.get(searchResultFields.get(i).getFieldName().toUpperCase()) : searchResultFields.get(i).getFieldName());
788                         resultFieldsBuffer.append(",");
789                     }
790                 }
791                 resultFieldsBuffer.append(EHOLDINGS_FIELDS);
792             } 
793 
794 
795         }
796         return resultFieldsBuffer.toString();
797     }
798 
799     private List<String> getIds(List<SolrDocument> solrDocumentList) {
800         List<String> ids = new ArrayList<>();
801         for (SolrDocument solrDocument : solrDocumentList) {
802             String docType = (String) solrDocument.getFieldValue("DocType");
803             if (docType.equalsIgnoreCase(DocType.BIB.getCode())) {
804                 ids.add((String) solrDocument.getFieldValue("id"));
805             } else if (docType.equalsIgnoreCase(DocType.HOLDINGS.getCode())) {
806                 ids.add((String) solrDocument.getFieldValue("id"));
807             } else if (docType.equalsIgnoreCase(DocType.ITEM.getCode())) {
808                 ids.add((String) solrDocument.getFieldValue("id"));
809             }
810         }
811         return ids;
812     }
813 
814     public String buildQueryWithSearchConditions(List<SearchCondition> searchConditions) {
815         StringBuffer query = new StringBuffer();
816         StringBuffer addDocType = new StringBuffer();
817         if (searchConditions != null && searchConditions.size() > 0) {
818             for (SearchCondition searchCondition : searchConditions) {
819                 if (searchCondition.getSearchField() != null && searchCondition.getSearchField().getDocType() != null) {
820                     addDocType.append("(DocType:");
821                     addDocType.append(searchCondition.getSearchField().getDocType());
822                     addDocType.append(")");
823                     break;
824                 }
825             }
826         } else {
827             return "(*:*)";
828         }
829         Collections.reverse(searchConditions);
830         int size = searchConditions.size();
831 
832         String previousOperator = "";
833         for(int i= size-1 ; i >= 0 ; i--) {
834 
835             boolean isInsert = false;
836 
837             SearchCondition searchCondition = null;
838             String searchText =null;
839             String searchScope = null;
840 
841             if(searchConditions.get(i)!=null  && searchConditions.get(i).getSearchField() !=null){
842                 if((size-1) != i ) {
843                     query.insert(0, "(");
844                     isInsert = true;
845                 }
846                 searchCondition = searchConditions.get(i);
847                 searchText = searchCondition.getSearchField().getFieldValue();
848                 searchScope = searchCondition.getSearchScope();
849             }else{
850                 continue;
851             }
852 
853             if(isInsert) {
854                 query.append(previousOperator);
855             }
856             query.append("(");
857             if (StringUtils.isNotBlank(searchCondition.getSearchField().getFieldName())) {
858                 if (searchCondition.getSearchField().getFieldName().equalsIgnoreCase("all") || searchCondition.getSearchField().getFieldName().equalsIgnoreCase("any")) {
859                     query.append("all_text");
860                 } else {
861                     query.append(searchFieldsMap.get(searchCondition.getSearchField().getFieldName().toUpperCase()) != null ? searchFieldsMap.get(searchCondition.getSearchField().getFieldName().toUpperCase()) : searchCondition.getSearchField().getFieldName());
862                 }
863                 query.append(":");
864             }
865 
866             if (StringUtils.isNotBlank(searchText)) {
867                 String searchTextVal = getModifiedText(searchText);
868                 if (searchText.length() > 0) {
869                     query.append("(");
870                     if (StringUtils.isNotBlank(searchScope)) {
871                         if (searchScope.equalsIgnoreCase("AND")) {
872                             searchTextVal = searchTextVal.trim().replaceAll("\\s+", "+ AND +");
873                         } else if (searchScope.equalsIgnoreCase("OR")) {
874                             searchTextVal = searchTextVal.trim().replaceAll("\\s+", "+ OR +");
875                         } else if (searchScope.equalsIgnoreCase("phrase")) {
876                             searchTextVal = "\"" + searchText + "\"";
877                         } else if (searchScope.equalsIgnoreCase("none")) {
878                             searchTextVal = searchText;
879                         }
880                     }
881                     query.append(searchTextVal);
882                     query.append(")");
883                 }
884                 query.append(")");
885             }
886             else {
887                 query.append("(*:*)");
888                 query.append(")");
889             }
890             previousOperator = searchCondition.getOperator();
891             if(isInsert) {
892                 query.append(")");
893             }
894         }
895         if (addDocType != null && addDocType.length() > 0) {
896             return addDocType.append("AND").append(query).toString();
897         } else {
898             return query.toString();
899         }
900     }
901 
902 
903 
904 
905 
906 
907 
908 
909 
910 
911 
912 
913 
914 
915 
916 
917 
918 
919 
920 
921 
922 
923 
924 
925 
926 
927 
928 
929 
930 
931 
932 
933 
934 
935 
936 
937 
938 
939 
940 
941 
942 
943 
944 
945 
946 
947 
948 
949 
950 
951 
952 
953 
954 
955 
956 
957 
958 
959 
960 
961 
962 
963 
964 
965 
966 
967 
968 
969 
970 
971 
972 
973 
974 
975 
976 
977 
978 
979 
980 
981 
982 
983 
984 
985 
986 
987 
988 
989     private String getModifiedText(String searchText) {
990         StringBuffer modifiedText = new StringBuffer();
991         StringCharacterIterator stringCharacterIterator = new StringCharacterIterator(searchText);
992         char character = stringCharacterIterator.current();
993         while (character != CharacterIterator.DONE) {
994 
995             if (character == '\\') {
996                 modifiedText.append("\\\\");
997             } else if (character == '?') {
998                 modifiedText.append("\\?");
999             } else if (character == '*' && StringUtils.isEmpty(modifiedText.toString())) {
1000                 modifiedText.append("\\*");
1001             } else if (character == '+') {
1002                 modifiedText.append("\\+");
1003             } else if (character == ':') {
1004                 modifiedText.append("\\:");
1005             } else if (character == '{') {
1006                 modifiedText.append("\\{");
1007             } else if (character == '}') {
1008                 modifiedText.append("\\}");
1009             } else if (character == '[') {
1010                 modifiedText.append("\\[");
1011             } else if (character == ']') {
1012                 modifiedText.append("\\]");
1013             } else if (character == '(') {
1014                 modifiedText.append("\\(");
1015             } else if (character == ')') {
1016                 modifiedText.append("\\)");
1017             } else if (character == '^') {
1018                 modifiedText.append("\\^");
1019             } else if (character == '~') {
1020                 modifiedText.append("\\~");
1021             } else if (character == '-') {
1022                 modifiedText.append("\\-");
1023             } else if (character == '!') {
1024                 modifiedText.append("\\!");
1025             } else if (character == '\'') {
1026                 modifiedText.append("\\'");
1027             } else if (character == '@') {
1028                 modifiedText.append("\\@");
1029             } else if (character == '#') {
1030                 modifiedText.append("\\#");
1031             } else if (character == '$') {
1032                 modifiedText.append("\\$");
1033             } else if (character == '%') {
1034                 modifiedText.append("\\%");
1035             } else {
1036                 
1037                 
1038                 modifiedText.append(character);
1039             }
1040             character = stringCharacterIterator.next();
1041         }
1042         return modifiedText.toString();
1043     }
1044 
1045     
1046 
1047 
1048 
1049 
1050 
1051 
1052 
1053 
1054 
1055 
1056 
1057 
1058 
1059 
1060 
1061     private void buildQueryWithSortConditions(SolrQuery solrQuery, List<SortCondition> sortConditions) {
1062         for (SortCondition sortCondition : sortConditions) {
1063             String sortField = sortCondition.getSortField();
1064             String sortOrder = sortCondition.getSortOrder();
1065             if (StringUtils.isNotBlank(sortField) && StringUtils.isNotBlank(sortOrder)) {
1066                 solrQuery.addSortField(getSolrSortField(sortField.toUpperCase()) != null ? getSolrSortField(sortField.toUpperCase()) : sortField, SolrQuery.ORDER.valueOf(sortOrder));
1067             }
1068         }
1069     }
1070 
1071     private String getSolrSortField(String sortField) {
1072 
1073         if ("TITLE".equals(sortField)) {
1074             return "Title_sort";
1075         } else if ("AUTHOR".equals(sortField)) {
1076             return "Author_sort";
1077         } else if ("PUBLICATION DATE".equals(sortField)) {
1078             return "PublicationDate_sort";
1079         } else if ("LOCATION".equals(sortField)) {
1080             return "Location_sort";
1081         } else if ("CALL NUMBER".equals(sortField)) {
1082             return "CallNumber_sort";
1083         } else if ("LOCAL IDENTIFIER".equalsIgnoreCase(sortField)){
1084             return "LocalId_search";
1085         } else if ("Journal Title".equalsIgnoreCase(sortField)){
1086             return "JournalTitle_sort";
1087         }
1088         return null;
1089     }
1090 
1091     @Override
1092     public List<String> callNumberBrowse(BrowseParams browseParams) {
1093         try {
1094             SolrQuery solrQuery = new SolrQuery();
1095             SolrServer server = SolrServerManager.getInstance().getSolrServer();
1096             solrQuery.setQuery(buildQueryWithSearchParams(browseParams));
1097             QueryResponse response = server.query(solrQuery);
1098             browseParams.setTotalCount(response.getResults().getNumFound());
1099             return getIds(response.getResults());
1100         } catch (SolrServerException ex) {
1101             LOG.info("Exception :", ex);
1102             throw new DocstoreIndexException(ex.getMessage());
1103         }
1104     }
1105 
1106     @Override
1107     public String findBib(Map<String, String> map) {
1108         List<String> bibIds = new ArrayList<>();
1109         SearchParams searchParams = buildSearchParamsFromMap(map);
1110         SearchResponse searchResponse = search(searchParams);
1111         for (SearchResult searchResult : searchResponse.getSearchResults()) {
1112             for (SearchResultField searchResultField : searchResult.getSearchResultFields()) {
1113                 bibIds.add(searchResultField.getFieldValue());
1114             }
1115         }
1116         if (!CollectionUtils.isEmpty(bibIds)) {
1117             return bibIds.get(0);
1118         }
1119         return null;
1120     }
1121 
1122     private SearchParams buildSearchParamsFromMap(Map<String, String> map) {
1123         SearchParams searchParams = new SearchParams();
1124         Set<String> keys = map.keySet();
1125         for (String key : keys) {
1126             if (!BibConstants.DOC_TYPE.equalsIgnoreCase(key)) {
1127                 SearchCondition searchCondition = new SearchCondition();
1128                 SearchField searchField = searchParams.buildSearchField(map.get(BibConstants.DOC_TYPE), searchFieldsMap.get(key), map.get(key));
1129                 searchCondition.setSearchField(searchField);
1130                 searchParams.getSearchConditions().add(searchCondition);
1131             }
1132         }
1133         searchParams.getSearchResultFields().add(searchParams.buildSearchResultField(map.get(BibConstants.DOC_TYPE), "id"));
1134         return searchParams;
1135     }
1136 
1137     @Override
1138     public String findHoldings(Map<String, String> map) {
1139         List<String> holdingIds = new ArrayList<>();
1140         map.put(BibConstants.DOC_TYPE, "holdings");
1141         SearchParams searchParams = buildSearchParamsFromMap(map);
1142         SearchResponse searchResponse = search(searchParams);
1143         for (SearchResult searchResult : searchResponse.getSearchResults()) {
1144             for (SearchResultField searchResultField : searchResult.getSearchResultFields()) {
1145                 holdingIds.add(searchResultField.getFieldValue());
1146             }
1147         }
1148         if (!CollectionUtils.isEmpty(holdingIds)) {
1149             return holdingIds.get(0);
1150         }
1151         return null;
1152     }
1153 
1154     @Override
1155     public String findItem(Map<String, String> map) {
1156         List<String> itemIds = new ArrayList<>();
1157         map.put(BibConstants.DOC_TYPE, "item");
1158         SearchParams searchParams = buildSearchParamsFromMap(map);
1159         SearchResponse searchResponse = search(searchParams);
1160         for (SearchResult searchResult : searchResponse.getSearchResults()) {
1161             for (SearchResultField searchResultField : searchResult.getSearchResultFields()) {
1162                 itemIds.add(searchResultField.getFieldValue());
1163             }
1164         }
1165         if (!CollectionUtils.isEmpty(itemIds)) {
1166             return itemIds.get(0);
1167         }
1168         return null;
1169     }
1170 
1171     @Override
1172     public String findHoldingsTree(Map<String, String> map) {
1173         return findHoldings(map);
1174     }
1175 
1176     @Override
1177     public String findBibTree(Map<String, String> map) {
1178         return findBib(map);
1179     }
1180 
1181 }