View Javadoc
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   * Created with IntelliJ IDEA.
29   * User: sambasivam
30   * Date: 12/13/13
31   * Time: 6:42 PM
32   * To change this template use File | Settings | File Templates.
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 //                else {
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             //SolrDocument holdingsSolrDocument = null;
251             //SolrDocument itemSolrDocument = null;
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                 //newSearchResultField.setFieldValue(searchResultField.getFieldValue());
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                 //newSearchResultField.setFieldValue(searchResultField.getFieldValue());
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                         //newSearchResultField.setFieldValue(searchResultField.getFieldValue());
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             //newSearchResultField.setFieldValue(searchResultField.getFieldValue());
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                     //newSearchResultField.setFieldValue(searchResultField.getFieldValue());
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                     //newSearchResultField.setFieldValue(searchResultField.getFieldValue());
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                             //newSearchResultField1.setFieldValue(searchResultField.getFieldValue());
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                 //newSearchResultField.setFieldValue(searchResultField.getFieldValue());
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                         //newSearchResultField.setFieldValue(searchResultField.getFieldValue());
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()) /*+ buildQueryWithSortConditions(searchParams.getSortConditions())*/;
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         //resultFieldsBuffer.append("&");
734         //resultFieldsBuffer.append("fl=");
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             } /*else {
744                 resultFieldsBuffer.append(BIB_FIELDS + "," + HOLDINGS_FIELDS + "," + ITEM_FIELDS);
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             } /*else {
756                 resultFieldsBuffer.append(BIB_FIELDS);
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             } /*else {
768                 resultFieldsBuffer.append(HOLDINGS_FIELDS);
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             } /*else {
781                 resultFieldsBuffer.append(ITEM_FIELDS);
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             } /*else {
793                 resultFieldsBuffer.append(ITEM_FIELDS);
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 //    public String buildQueryWithSearchConditions(List<SearchCondition> searchConditions) {
903 //        boolean searchConditionCheck = false;
904 //        SearchCondition searchCondition = null;
905 //        String docType = null;
906 //        StringBuffer queryStringBuffer = new StringBuffer();
907 //        if (searchConditions != null && searchConditions.size() > 0) {
908 //            for (int i = 0; i < searchConditions.size(); i++) {
909 //                int searchScopeAddLimit = i;
910 //                searchCondition = searchConditions.get(i);
911 //                if (searchCondition.getSearchField() != null) {
912 //                    if (StringUtils.isBlank(docType) && searchScopeAddLimit == 0) {
913 //                        docType = searchCondition.getSearchField().getDocType();
914 //                        if (StringUtils.isNotBlank(docType)) {
915 //                            queryStringBuffer.append("(");
916 //                            queryStringBuffer.append("DocType:" + docType);
917 //                            queryStringBuffer.append(")");
918 //                        }
919 //                    }
920 //                    String searchScope = searchCondition.getSearchScope();
921 //                    String searchOperator = searchCondition.getOperator();
922 //                    String searchText = searchCondition.getSearchField().getFieldValue();
923 //                    if (StringUtils.isBlank(docType) || docType.equalsIgnoreCase(searchCondition.getSearchField().getDocType())) {
924 //                        if (StringUtils.isNotBlank(searchCondition.getSearchField().getFieldName()) || StringUtils.isNotBlank(searchCondition.getSearchField().getFieldValue())) {
925 //                            if (StringUtils.isNotBlank(docType) && searchScopeAddLimit == 0) {
926 //                                queryStringBuffer.append("AND");
927 //                                queryStringBuffer.append("(");
928 //                            }
929 //                            queryStringBuffer.append("(");
930 //                            if (StringUtils.isNotBlank(searchCondition.getSearchField().getFieldName())) {
931 //                                if (searchCondition.getSearchField().getFieldName().equalsIgnoreCase("all")) {
932 //                                    queryStringBuffer.append("all_text");
933 //                                } else {
934 //                                    queryStringBuffer.append(searchFieldsMap.get(searchCondition.getSearchField().getFieldName().toUpperCase()) != null ? searchFieldsMap.get(searchCondition.getSearchField().getFieldName().toUpperCase()) : searchCondition.getSearchField().getFieldName());
935 //                                }
936 //                                queryStringBuffer.append(":");
937 //                            }
938 //
939 //                            if (StringUtils.isNotBlank(searchText)) {
940 //                                String searchTextVal = getModifiedText(searchText);
941 //                                if (searchText.length() > 0) {
942 //                                    queryStringBuffer.append("(");
943 //                                    if (StringUtils.isNotBlank(searchScope)) {
944 //                                        if (searchScope.equalsIgnoreCase("AND")) {
945 //                                            searchTextVal = searchTextVal.trim().replaceAll("\\s+", "+ AND +");
946 //                                        } else if (searchScope.equalsIgnoreCase("OR")) {
947 //                                            searchTextVal = searchTextVal.trim().replaceAll("\\s+", "+ OR +");
948 //                                        } else if (searchScope.equalsIgnoreCase("phrase")) {
949 //                                            searchTextVal = "\"" + searchText + "\"";
950 //                                        } else if (searchScope.equalsIgnoreCase("none")) {
951 //                                            searchTextVal = searchText;
952 //                                        }
953 //                                    }
954 //                                    queryStringBuffer.append(searchTextVal);
955 //                                    queryStringBuffer.append(")");
956 //                                }
957 //                                queryStringBuffer.append(")");
958 //                                searchConditionCheck = true;
959 //                            } else {
960 //                                queryStringBuffer.append("(*:*)");
961 //                                queryStringBuffer.append(")");
962 //                                searchConditionCheck = true;
963 //                            }
964 //                        }
965 //                    }
966 //                    ++searchScopeAddLimit;
967 //                    if (StringUtils.isBlank(searchOperator)) {
968 //                        break;
969 //                    }
970 //                    if (searchScopeAddLimit != searchConditions.size()) {
971 //                        if (StringUtils.isBlank(docType) || StringUtils.isNotBlank(docType) && docType.equalsIgnoreCase(searchConditions.get(searchScopeAddLimit).getSearchField().getDocType())) {
972 //                            queryStringBuffer.append(searchOperator);
973 //                        }
974 //                    }
975 //                }
976 //                if (StringUtils.isBlank(docType) && StringUtils.isBlank(searchCondition.getSearchField().getFieldName()) && StringUtils.isBlank(searchCondition.getSearchField().getFieldValue())) {
977 //                    queryStringBuffer.append("*:*");
978 //                }
979 //            }
980 //        } else {
981 //            queryStringBuffer.append("*:*");
982 //        }
983 //        if (searchConditionCheck && StringUtils.isNotBlank(docType)) {
984 //            queryStringBuffer.append(")");
985 //        }
986 //        return queryStringBuffer.toString();
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                 // the char is not a special one
1037                 // add it to the result as is
1038                 modifiedText.append(character);
1039             }
1040             character = stringCharacterIterator.next();
1041         }
1042         return modifiedText.toString();
1043     }
1044 
1045     /*public String buildQueryWithSortConditions(List<SortCondition> sortConditions) {
1046         StringBuffer sortFieldsQuery = new StringBuffer();
1047         for (SortCondition sortCondition : sortConditions) {
1048             String sortField = sortCondition.getSortField();
1049             String sortOrder = sortCondition.getSortOrder();
1050             if (StringUtils.isNotBlank(sortField) && StringUtils.isNotBlank(getSolrSortField(sortField.toUpperCase())) && StringUtils.isNotBlank(sortOrder)) {
1051                 sortFieldsQuery.append("&");
1052                 sortFieldsQuery.append("sort=");
1053                 sortFieldsQuery.append(getSolrSortField(sortField.toUpperCase()));
1054                 sortFieldsQuery.append(" ");
1055                 sortFieldsQuery.append(sortOrder);
1056             }
1057         }
1058         return sortFieldsQuery.toString();
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 }