001package org.kuali.ole.serviceimpl; 002 003import org.kuali.ole.OleSRUConstants; 004import org.kuali.ole.bo.cql.CQLResponseBO; 005import org.kuali.ole.bo.diagnostics.OleSRUDiagnostics; 006import org.kuali.ole.bo.serachRetrieve.OleSRUData; 007import org.kuali.ole.bo.serachRetrieve.OleSRUSearchRetrieveResponse; 008import org.kuali.ole.docstore.common.client.DocstoreClient; 009import org.kuali.ole.docstore.common.document.BibTree; 010import org.kuali.ole.docstore.common.document.HoldingsTree; 011import org.kuali.ole.docstore.common.search.*; 012import org.kuali.ole.docstore.engine.client.DocstoreLocalClient; 013import org.kuali.ole.docstore.engine.service.index.solr.BibConstants; 014import org.kuali.ole.docstore.model.enums.DocType; 015import org.kuali.ole.handler.OleSRUOpacXMLResponseHandler; 016import org.kuali.ole.service.OleCQLQueryParserService; 017import org.kuali.ole.service.OleDiagnosticsService; 018import org.kuali.ole.service.OleSRUDataService; 019import org.kuali.ole.service.OleSearchRetrieveOperationService; 020import org.kuali.rice.core.api.config.property.Config; 021import org.kuali.rice.core.api.config.property.ConfigContext; 022import org.slf4j.Logger; 023import org.slf4j.LoggerFactory; 024import java.util.ArrayList; 025import java.util.List; 026import java.util.Map; 027 028/** 029 * Created with IntelliJ IDEA. 030 * User: ? 031 * Date: 7/9/12 032 * Time: 6:50 PM 033 * To change this template use File | Settings | File Templates. 034 */ 035public class OleSearchRetrieveOperationServiceImpl implements OleSearchRetrieveOperationService { 036 037 private Logger LOG = LoggerFactory.getLogger(this.getClass()); 038 public OleSRUDataService oleSRUDataService; 039 public OleDiagnosticsService oleDiagnosticsService; 040 public OleCQLQueryParserService oleCQLQueryParserService; 041 private Config currentContextConfig; 042 private SearchParams searchParams = new SearchParams(); 043 private SearchCondition searchCondition = null; 044 private SearchField searchField = null; 045 private DocstoreClient docstoreClient; 046 private SearchResultField searchResultFields = null; 047 048 public OleSearchRetrieveOperationServiceImpl() { 049 oleSRUDataService = new OleSRUDataServiceImpl(); 050 oleDiagnosticsService = new OleDiagnosticsServiceImpl(); 051 oleCQLQueryParserService = new OleCQLQueryParserServiceImpl(); 052 } 053 054 /** 055 * it will return a OPAC response xml ( overall xml ) 056 * 057 * @param reqParamMap 058 * @param cqlParseBO 059 * @return OPAC xml response 060 */ 061 public String getSearchRetriveResponse(Map reqParamMap, CQLResponseBO cqlParseBO) { 062 063 SearchParams searchParams = createSearchParams(cqlParseBO, true); 064 buildSearchConditions(searchParams); 065 /*SearchCondition condition = new SearchCondition(); 066 condition.setOperator("AND"); 067 SearchField field = new SearchField(); 068 field.setFieldName("DocFormat"); 069 String format = (String)reqParamMap.get(OleSRUConstants.RECORD_SCHEMA); 070 if(format.equalsIgnoreCase("OPAC")){ 071 format = "marc"; 072 } 073 field.setFieldValue(format); 074 condition.setSearchField(field); 075 searchParams.getSearchConditions().add(condition);*/ 076 searchParams.setStartIndex(Integer.parseInt(reqParamMap.get("startRecord").toString())); 077 searchParams.setPageSize(Integer.parseInt(reqParamMap.get("maximumRecords").toString())); 078 if (searchParams == null) { 079 OleSRUDiagnostics oleSRUDiagnostics = oleDiagnosticsService.getDiagnosticResponse(getCurrentContextConfig().getProperty(OleSRUConstants.INVALID_QUERY_DIAGNOSTIC_MSG)); 080 OleSRUSearchRetrieveResponse oleSRUSearchRetrieveResponse = new OleSRUSearchRetrieveResponse(); 081 oleSRUSearchRetrieveResponse.setVersion((String) reqParamMap.get(OleSRUConstants.VERSION)); 082 oleSRUSearchRetrieveResponse.setOleSRUDiagnostics(oleSRUDiagnostics); 083 OleSRUOpacXMLResponseHandler oleSRUOpacXMLResponseHandler = new OleSRUOpacXMLResponseHandler(); 084 return oleSRUOpacXMLResponseHandler.toXML(oleSRUSearchRetrieveResponse, (String) reqParamMap.get("recordSchema")); 085 086 } 087 // add q=staffOnlyFlag:false to search 088 FacetCondition staffOnlyFacet = new FacetCondition(); 089 staffOnlyFacet.setFieldName(BibConstants.STAFF_ONLY_FLAG); 090 staffOnlyFacet.setFieldValue(OleSRUConstants.SRU_STAFF_ONLY_FLAG); 091 searchParams.getFacetConditions().add(staffOnlyFacet); 092 093 // add fq=DocType:bibliographic to search 094 FacetCondition docTypeFacet = new FacetCondition(); 095 docTypeFacet.setFieldName(BibConstants.DOC_TYPE); 096 docTypeFacet.setFieldValue(OleSRUConstants.BIBLIOGRAPHIC); 097 searchParams.getFacetConditions().add(docTypeFacet); 098 099 OleSRUSearchRetrieveResponse oleSRUSearchRetrieveResponse = new OleSRUSearchRetrieveResponse(); 100 oleSRUSearchRetrieveResponse.setVersion((String) reqParamMap.get(OleSRUConstants.VERSION)); 101 OleSRUOpacXMLResponseHandler oleSRUOpacXMLResponseHandler = new OleSRUOpacXMLResponseHandler(); 102 List oleSRUBibIdList = getBibIds(reqParamMap, searchParams); 103 /*if(oleSRUBibIdList!=null && oleSRUBibIdList.size()>0 && oleSRUBibIdList.get(0) instanceof String){ 104 if(oleSRUBibIdList.get(0).equals("Invalid Local Id")){ 105 OleSRUDiagnostics oleSRUDiagnostics = oleDiagnosticsService.getDiagnosticResponse("Local Id Value Should be a Number"); 106 oleSRUSearchRetrieveResponse.setOleSRUDiagnostics(oleSRUDiagnostics); 107 return oleSRUOpacXMLResponseHandler.toXML(oleSRUSearchRetrieveResponse,(String)reqParamMap.get("recordSchema")); 108 } 109 OleSRUDiagnostics oleSRUDiagnostics = oleDiagnosticsService.getDiagnosticResponse(getCurrentContextConfig().getProperty(OleSRUConstants.INVALID_QUERY_DIAGNOSTIC_MSG)); 110 oleSRUSearchRetrieveResponse.setOleSRUDiagnostics(oleSRUDiagnostics); 111 return oleSRUOpacXMLResponseHandler.toXML(oleSRUSearchRetrieveResponse,(String)reqParamMap.get("recordSchema")); 112 }*/ 113 if (oleSRUBibIdList == null) { 114 OleSRUDiagnostics oleSRUDiagnostics = oleDiagnosticsService.getDiagnosticResponse(getCurrentContextConfig().getProperty(OleSRUConstants.SERVER_DIAGNOSTIC_MSG)); 115 oleSRUSearchRetrieveResponse.setOleSRUDiagnostics(oleSRUDiagnostics); 116 return oleSRUOpacXMLResponseHandler.toXML(oleSRUSearchRetrieveResponse, (String) reqParamMap.get("recordSchema")); 117 118 } 119 120 String opacXML = oleSRUDataService.getOPACXMLSearchRetrieveResponse(oleSRUBibIdList, reqParamMap); 121 String styleSheet = (String) reqParamMap.get(OleSRUConstants.STYLE_SHEET); 122 if (styleSheet != null) { 123 opacXML = opacXML.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \n <?xml-stylesheet type=\"text/xsl\" href=\"" + styleSheet + "\"?>"); 124 } 125 opacXML = opacXML.replace("<collection xmlns=\"http://www.loc.gov/MARC21/slim\">", ""); 126 opacXML = opacXML.replace("<collection>",""); 127 opacXML = opacXML.replace("</collection>", ""); 128 LOG.info("opac xml response ----> " + opacXML); 129 return opacXML; 130 } 131 132 133 private void buildSearchConditions(SearchParams searchParams) { 134 135 List<SearchCondition> searchConditions = searchParams.getSearchConditions(); 136 if (searchConditions.size() >1 && searchConditions.size() <= 2) { 137 if(searchConditions.get(0)!=null && searchConditions.get(1)!=null){ 138 searchConditions.get(0).setOperator(searchConditions.get(1).getOperator()); 139 } 140 } else if (searchConditions.size() > 2) { 141 for (int i = 0; i < searchConditions.size() - 1; i++) { 142 if(searchConditions.get(i)!=null && searchConditions.get(i)!=null){ 143 SearchCondition sc1 = searchConditions.get(i); 144 SearchCondition sc2 = searchConditions.get(i + 1); 145 sc1.setOperator(sc2.getOperator()); 146 } 147 } 148 } 149 } 150 151 private Config getCurrentContextConfig() { 152 if (null == currentContextConfig) { 153 currentContextConfig = ConfigContext.getCurrentContextConfig(); 154 } 155 return currentContextConfig; 156 } 157 158 public void setCurrentContextConfig(Config currentContextConfig) { 159 this.currentContextConfig = currentContextConfig; 160 } 161 162 /** 163 * . 164 * this will get the proper query from the oleCQLQueryParserService 165 * 166 * @param cqlResponseBO object 167 * @return query as a string 168 */ 169 /*public String getSolrQueryFromCQLParseBO(CQLResponseBO cqlResponseBO) { 170 String solrQuery = null; 171 solrQuery = oleCQLQueryParserService.getSolrQueryFromCQLBO(cqlResponseBO); 172 LOG.info("solr Query ------> " + solrQuery); 173 return "(" + solrQuery + ")"; 174 }*/ 175 private SearchParams createSearchParams(CQLResponseBO cqlResponseBO, boolean flag) { 176 searchResultFields = new SearchResultField(); 177 if (cqlResponseBO.getLeftOperand() != null) { 178 CQLResponseBO leftOperand = cqlResponseBO.getLeftOperand(); 179 createSearchParams(leftOperand, false); 180 searchField = setSearchField(cqlResponseBO.getLeftOperand()); 181 if (searchField != null) { 182 searchCondition = setSearchCondition(cqlResponseBO.getLeftOperand(), searchField); 183 } 184 if (null != cqlResponseBO.getLeftOperand().getBooleanTagValue() && null != cqlResponseBO.getLeftOperand().getBooleanTagValue().getValue()) { 185 searchCondition.setOperator(cqlResponseBO.getBooleanTagValue().getValue()); 186 } 187 if (searchCondition != null && searchField != null) { 188 searchParams.getSearchConditions().add(searchCondition); 189 } 190 } 191 if (cqlResponseBO.getRightOperand() != null) { 192 CQLResponseBO rightOperand = cqlResponseBO.getRightOperand(); 193 createSearchParams(rightOperand, false); 194 searchField = setSearchField(cqlResponseBO.getRightOperand()); 195 if (searchField != null) { 196 searchCondition = setSearchCondition(cqlResponseBO.getRightOperand(), searchField); 197 } 198 if (null != cqlResponseBO.getBooleanTagValue() && null != cqlResponseBO.getBooleanTagValue().getValue()) { 199 searchCondition.setOperator(cqlResponseBO.getBooleanTagValue().getValue()); 200 } 201 if (searchCondition != null && searchField != null) { 202 searchParams.getSearchConditions().add(searchCondition); 203 } 204 } 205 if (cqlResponseBO.getTriple() != null) { 206 CQLResponseBO triple = cqlResponseBO.getTriple(); 207 if (triple != null) { 208 createSearchParams(triple, false); 209 searchField = setSearchField(triple); 210 if (searchField != null) 211 searchCondition = setSearchCondition(triple, searchField); 212 } 213 if (null != cqlResponseBO.getBooleanTagValue() && null != triple.getBooleanTagValue().getValue()) { 214 searchCondition.setOperator(triple.getBooleanTagValue().getValue()); 215 } 216 if (searchCondition != null && searchField != null) { 217 searchParams.getSearchConditions().add(searchCondition); 218 } 219 } 220 if (cqlResponseBO.getSearchClauseTag() != null) { 221 SearchField searchField = setSearchField(cqlResponseBO); 222 SearchCondition searchCondition = setSearchCondition(cqlResponseBO, searchField); 223 SearchParams searchParams = new SearchParams(); 224 searchResultFields.setDocType(OleSRUConstants.BIBLIOGRAPHIC); 225 searchResultFields.setFieldName("id"); 226 searchParams.getSearchResultFields().add(searchResultFields); 227 searchParams.getSearchConditions().add(searchCondition); 228 return searchParams; 229 } 230 231 if (flag) { 232 searchResultFields.setDocType(OleSRUConstants.BIBLIOGRAPHIC); 233 searchResultFields.setFieldName("id"); 234 searchParams.getSearchResultFields().add(searchResultFields); 235 return searchParams; 236 } 237 return null; 238 } 239 240 private List getBibIds(Map reqParamMap, SearchParams searchParams) { 241 SearchResponse searchResponse = getDocstoreClient().search(searchParams); 242 List bibIds = new ArrayList(); 243 List<OleSRUData> oleSRUDataList = new ArrayList<>(); 244 for (SearchResult searchResult : searchResponse.getSearchResults()) { 245 OleSRUData oleSRUData ; 246 for (SearchResultField searchResultField : searchResult.getSearchResultFields()) { 247 if (searchResultField.getDocType().equalsIgnoreCase(DocType.BIB.getCode())) { 248 if (searchResultField.getFieldName().equalsIgnoreCase("id")) { 249 bibIds.add(searchResultField.getFieldValue()); 250 oleSRUData = new OleSRUData(); 251 oleSRUData.setBibId(searchResultField.getFieldValue()); 252 BibTree bib = getDocstoreClient().retrieveBibTree(searchResultField.getFieldValue()); 253 List<HoldingsTree> holdingsTrees = bib.getHoldingsTrees(); 254 List<String> ids = new ArrayList<>(); 255 for(HoldingsTree holdingsTree:holdingsTrees){ 256 ids.add(holdingsTree.getHoldings().getId()); 257 } 258 /*ListIterator<HoldingsTree> holdingsTreeListIterator = holdingsTrees.listIterator(); 259 List<String> ids = new ArrayList<>(); 260 while(holdingsTreeListIterator.hasNext()){ 261 ids.add(holdingsTreeListIterator.next().getId()); 262 }*/ 263 oleSRUData.setInstanceIds(ids); 264 oleSRUDataList.add(oleSRUData); 265 } 266 } 267 } 268 } 269 Integer size = searchResponse.getTotalRecordCount(); 270 reqParamMap.put("numberOfRecords", size.longValue()); 271 return oleSRUDataList; 272 } 273 274 private DocstoreClient getDocstoreClient() { 275 276 if (docstoreClient == null) { 277 docstoreClient = new DocstoreLocalClient(); 278 } 279 return docstoreClient; 280 } 281 282 private SearchField setSearchField(CQLResponseBO cqlResponseBO) { 283 searchField = null; 284 if (cqlResponseBO != null) { 285 if (cqlResponseBO.getSearchClauseTag() != null) { 286 searchField = new SearchField(); 287 if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.TITLE) || 288 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_TITLE)) { 289 searchField.setFieldName(OleSRUConstants.TITLE_SEARCH); 290 } else if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.AUTHOR) || 291 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_AUTHOR)) { 292 searchField.setFieldName(OleSRUConstants.AUTHOR_SEARCH); 293 } else if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.PUBLISHER) || 294 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_PUBLISHER)) { 295 searchField.setFieldName(OleSRUConstants.PUBLISHER_SEARCH); 296 } else if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.PUBLICATION_DATE) || 297 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.PUB_DATE) || 298 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_PUBLICATION_DATE) || 299 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_PUB_DATE)) { 300 searchField.setFieldName(OleSRUConstants.PUBLICATION_DATE_SEARCH); 301 } else if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.ISBN) || 302 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_ISBN)) { 303 searchField.setFieldName(OleSRUConstants.ISBN_SEARCH); 304 } else if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.ISSN) || 305 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_ISSN)) { 306 searchField.setFieldName(OleSRUConstants.ISSN_SEARCH); 307 } else if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.LOCALID) || 308 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_LOCALID)) { 309 searchField.setFieldName(OleSRUConstants.LOCALID_SEARCH); 310 } else if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.SUBJECT) || 311 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_SUBJECT)) { 312 searchField.setFieldName(OleSRUConstants.SUBJECT_SEARCH); 313 } else if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CHOICE) || 314 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_CHOICE)) { 315 searchField.setFieldName(OleSRUConstants.ALL_TEXT); 316 } 317 } 318 if (cqlResponseBO.getSearchClauseTag() != null && cqlResponseBO.getSearchClauseTag().getTerm() != null) { 319 searchField.setFieldValue(cqlResponseBO.getSearchClauseTag().getTerm()); 320 } 321 } 322 return searchField; 323 } 324 325 private SearchCondition setSearchCondition(CQLResponseBO cqlResponseBO, SearchField searchField) { 326 searchCondition = new SearchCondition(); 327 if (cqlResponseBO.getSearchClauseTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue().equalsIgnoreCase("any")) { 328 searchCondition.setSearchScope("or"); 329 } else if (cqlResponseBO.getSearchClauseTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue().equalsIgnoreCase("all")) { 330 searchCondition.setSearchScope("and"); 331 }else if (cqlResponseBO.getSearchClauseTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue().equalsIgnoreCase("adj")) { 332 searchCondition.setSearchScope("phrase"); 333 } else { 334 searchCondition.setSearchScope("and"); 335 } 336 if (null != searchField) 337 searchCondition.setSearchField(searchField); 338 if (null != cqlResponseBO && null != cqlResponseBO.getBooleanTagValue()) { 339 searchCondition.setOperator(cqlResponseBO.getBooleanTagValue().getValue()); 340 } 341 return searchCondition; 342 } 343}