1 package org.kuali.ole.serviceimpl;
2
3 import org.codehaus.plexus.util.StringUtils;
4 import org.kuali.ole.OleSRUConstants;
5 import org.kuali.ole.bo.cql.CQLResponseBO;
6 import org.kuali.ole.bo.diagnostics.OleSRUDiagnostics;
7 import org.kuali.ole.bo.serachRetrieve.OleSRUData;
8 import org.kuali.ole.bo.serachRetrieve.OleSRUSearchRetrieveResponse;
9 import org.kuali.ole.docstore.OleException;
10 import org.kuali.ole.docstore.common.client.DocstoreClient;
11 import org.kuali.ole.docstore.common.document.BibTree;
12 import org.kuali.ole.docstore.common.document.HoldingsTree;
13 import org.kuali.ole.docstore.common.search.*;
14 import org.kuali.ole.docstore.common.search.SearchCondition;
15 import org.kuali.ole.docstore.common.search.SearchParams;
16 import org.kuali.ole.docstore.discovery.model.*;
17 import org.kuali.ole.docstore.engine.client.DocstoreLocalClient;
18 import org.kuali.ole.docstore.engine.service.index.solr.BibConstants;
19 import org.kuali.ole.docstore.model.enums.DocType;
20 import org.kuali.ole.docstore.utility.ISBNUtil;
21 import org.kuali.ole.handler.OleSRUOpacXMLResponseHandler;
22 import org.kuali.ole.service.OleCQLQueryParserService;
23 import org.kuali.ole.service.OleDiagnosticsService;
24 import org.kuali.ole.service.OleSRUDataService;
25 import org.kuali.ole.service.OleSearchRetrieveOperationService;
26 import org.kuali.rice.core.api.config.property.Config;
27 import org.kuali.rice.core.api.config.property.ConfigContext;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30 import java.util.ArrayList;
31 import java.util.List;
32 import java.util.Map;
33
34
35
36
37
38
39
40
41 public class OleSearchRetrieveOperationServiceImpl implements OleSearchRetrieveOperationService {
42
43 private Logger LOG = LoggerFactory.getLogger(this.getClass());
44 public OleSRUDataService oleSRUDataService;
45 public OleDiagnosticsService oleDiagnosticsService;
46 public OleCQLQueryParserService oleCQLQueryParserService;
47 private Config currentContextConfig;
48 private SearchParams searchParams = new SearchParams();
49 private SearchCondition searchCondition = null;
50 private SearchField searchField = null;
51 private DocstoreClient docstoreClient;
52 private SearchResultField searchResultFields = null;
53
54 public OleSearchRetrieveOperationServiceImpl() {
55 oleSRUDataService = new OleSRUDataServiceImpl();
56 oleDiagnosticsService = new OleDiagnosticsServiceImpl();
57 oleCQLQueryParserService = new OleCQLQueryParserServiceImpl();
58 }
59
60
61
62
63
64
65
66
67 public String getSearchRetriveResponse(Map reqParamMap, CQLResponseBO cqlParseBO) {
68
69 SearchParams searchParams = createSearchParams(cqlParseBO, true);
70 buildSearchConditions(searchParams);
71 List<SearchCondition> searchConditions = new ArrayList<SearchCondition>();
72 for (SearchCondition condition:searchParams.getSearchConditions()){
73 if(condition.getSearchField().getFieldName().equals(OleSRUConstants.PUBLICATION_DATE_SEARCH) && StringUtils.isNotBlank(condition.getSearchScope())){
74 if((condition.getSearchScope().equalsIgnoreCase("GREATER THAN EQUALS") || condition.getSearchScope().equalsIgnoreCase("LESS THAN EQUALS"))){
75 condition.setSearchScope("none");
76 condition.setOperator("AND");
77 searchConditions.add(condition);
78 } else if(condition.getSearchScope().equalsIgnoreCase("LESS THAN") ||condition.getSearchScope().equalsIgnoreCase("GREATER THAN")) {
79 SearchCondition newCondition=new SearchCondition();
80 String textData=condition.getSearchField().getFieldValue();
81 if(StringUtils.isNotBlank(textData)&& textData.contains("[")&&textData.contains("]")){
82 textData=textData.replace("[","");
83 textData=textData.replace("]","");
84 textData=textData.replace("TO *","");
85 textData=textData.replace("* TO","");
86 textData=textData.trim();
87 }
88 SearchField newField=new SearchField();
89 newField.setDocType(condition.getSearchField().getDocType());
90 newField.setFieldName(condition.getSearchField().getFieldName());
91 newField.setFieldValue(textData);
92 newCondition.setSearchField(newField);
93 newCondition.setOperator("NOT");
94 newCondition.setSearchScope("none");
95 condition.setOperator("AND");
96 condition.setSearchScope("none");
97 searchConditions.add(condition);
98 searchConditions.add(newCondition);
99 } else {
100 searchConditions.add(condition);
101 }
102 } else {
103 searchConditions.add(condition);
104 }
105
106 }
107 searchParams.getSearchConditions().clear();
108 searchParams.getSearchConditions().addAll(searchConditions);
109
110
111
112
113
114
115
116
117
118
119
120 searchParams.setStartIndex(Integer.parseInt(reqParamMap.get("startRecord").toString()));
121 searchParams.setPageSize(Integer.parseInt(reqParamMap.get("maximumRecords").toString()));
122 if (searchParams == null) {
123 OleSRUDiagnostics oleSRUDiagnostics = oleDiagnosticsService.getDiagnosticResponse(getCurrentContextConfig().getProperty(OleSRUConstants.INVALID_QUERY_DIAGNOSTIC_MSG));
124 OleSRUSearchRetrieveResponse oleSRUSearchRetrieveResponse = new OleSRUSearchRetrieveResponse();
125 oleSRUSearchRetrieveResponse.setVersion((String) reqParamMap.get(OleSRUConstants.VERSION));
126 oleSRUSearchRetrieveResponse.setOleSRUDiagnostics(oleSRUDiagnostics);
127 OleSRUOpacXMLResponseHandler oleSRUOpacXMLResponseHandler = new OleSRUOpacXMLResponseHandler();
128 return oleSRUOpacXMLResponseHandler.toXML(oleSRUSearchRetrieveResponse, (String) reqParamMap.get("recordSchema"));
129
130 }
131
132 FacetCondition staffOnlyFacet = new FacetCondition();
133 staffOnlyFacet.setFieldName(BibConstants.STAFF_ONLY_FLAG);
134 staffOnlyFacet.setFieldValue(OleSRUConstants.SRU_STAFF_ONLY_FLAG);
135 searchParams.getFacetConditions().add(staffOnlyFacet);
136
137
138 FacetCondition docTypeFacet = new FacetCondition();
139 docTypeFacet.setFieldName(BibConstants.DOC_TYPE);
140 docTypeFacet.setFieldValue(OleSRUConstants.BIBLIOGRAPHIC);
141 searchParams.getFacetConditions().add(docTypeFacet);
142
143 OleSRUSearchRetrieveResponse oleSRUSearchRetrieveResponse = new OleSRUSearchRetrieveResponse();
144 oleSRUSearchRetrieveResponse.setVersion((String) reqParamMap.get(OleSRUConstants.VERSION));
145 OleSRUOpacXMLResponseHandler oleSRUOpacXMLResponseHandler = new OleSRUOpacXMLResponseHandler();
146 List oleSRUBibIdList = getBibIds(reqParamMap, searchParams);
147
148
149
150
151
152
153
154
155
156
157 if (oleSRUBibIdList == null) {
158 OleSRUDiagnostics oleSRUDiagnostics = oleDiagnosticsService.getDiagnosticResponse(getCurrentContextConfig().getProperty(OleSRUConstants.SERVER_DIAGNOSTIC_MSG));
159 oleSRUSearchRetrieveResponse.setOleSRUDiagnostics(oleSRUDiagnostics);
160 return oleSRUOpacXMLResponseHandler.toXML(oleSRUSearchRetrieveResponse, (String) reqParamMap.get("recordSchema"));
161
162 }
163
164 String opacXML = oleSRUDataService.getOPACXMLSearchRetrieveResponse(oleSRUBibIdList, reqParamMap);
165 String styleSheet = (String) reqParamMap.get(OleSRUConstants.STYLE_SHEET);
166 if (styleSheet != null) {
167 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 + "\"?>");
168 }
169 opacXML = opacXML.replace("<collection xmlns=\"http://www.loc.gov/MARC21/slim\">", "");
170 opacXML = opacXML.replace("<collection>","");
171 opacXML = opacXML.replace("</collection>", "");
172 LOG.info("opac xml response ----> " + opacXML);
173 return opacXML;
174 }
175
176
177 private void buildSearchConditions(SearchParams searchParams) {
178
179 List<SearchCondition> searchConditions = searchParams.getSearchConditions();
180 if (searchConditions.size() >1 && searchConditions.size() <= 2) {
181 if(searchConditions.get(0)!=null && searchConditions.get(1)!=null){
182 searchConditions.get(0).setOperator(searchConditions.get(1).getOperator());
183 }
184 } else if (searchConditions.size() > 2) {
185 for (int i = 0; i < searchConditions.size() - 1; i++) {
186 if(searchConditions.get(i)!=null && searchConditions.get(i)!=null){
187 SearchCondition sc1 = searchConditions.get(i);
188 SearchCondition sc2 = searchConditions.get(i + 1);
189 sc1.setOperator(sc2.getOperator());
190 }
191 }
192 }
193 }
194
195 private Config getCurrentContextConfig() {
196 if (null == currentContextConfig) {
197 currentContextConfig = ConfigContext.getCurrentContextConfig();
198 }
199 return currentContextConfig;
200 }
201
202 public void setCurrentContextConfig(Config currentContextConfig) {
203 this.currentContextConfig = currentContextConfig;
204 }
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219 private SearchParams createSearchParams(CQLResponseBO cqlResponseBO, boolean flag) {
220 searchResultFields = new SearchResultField();
221 if (cqlResponseBO.getLeftOperand() != null) {
222 CQLResponseBO leftOperand = cqlResponseBO.getLeftOperand();
223 createSearchParams(leftOperand, false);
224 searchField = setSearchField(cqlResponseBO.getLeftOperand());
225 if (searchField != null) {
226 searchCondition = setSearchCondition(cqlResponseBO.getLeftOperand(), searchField);
227 }
228 if (null != cqlResponseBO.getLeftOperand().getBooleanTagValue() && null != cqlResponseBO.getLeftOperand().getBooleanTagValue().getValue()) {
229 searchCondition.setOperator(cqlResponseBO.getBooleanTagValue().getValue());
230 }
231 if (searchCondition != null && searchField != null) {
232 searchParams.getSearchConditions().add(searchCondition);
233 }
234 }
235 if (cqlResponseBO.getRightOperand() != null) {
236 CQLResponseBO rightOperand = cqlResponseBO.getRightOperand();
237 createSearchParams(rightOperand, false);
238 searchField = setSearchField(cqlResponseBO.getRightOperand());
239 if (searchField != null) {
240 searchCondition = setSearchCondition(cqlResponseBO.getRightOperand(), searchField);
241 }
242 if (null != cqlResponseBO.getBooleanTagValue() && null != cqlResponseBO.getBooleanTagValue().getValue()) {
243 searchCondition.setOperator(cqlResponseBO.getBooleanTagValue().getValue());
244 }
245 if (searchCondition != null && searchField != null) {
246 searchParams.getSearchConditions().add(searchCondition);
247 }
248 }
249 if (cqlResponseBO.getTriple() != null) {
250 CQLResponseBO triple = cqlResponseBO.getTriple();
251 if (triple != null) {
252 createSearchParams(triple, false);
253 searchField = setSearchField(triple);
254 if (searchField != null)
255 searchCondition = setSearchCondition(triple, searchField);
256 }
257 if (null != cqlResponseBO.getBooleanTagValue() && null != triple.getBooleanTagValue().getValue()) {
258 searchCondition.setOperator(triple.getBooleanTagValue().getValue());
259 }
260 if (searchCondition != null && searchField != null) {
261 searchParams.getSearchConditions().add(searchCondition);
262 }
263 }
264 if (cqlResponseBO.getSearchClauseTag() != null) {
265 SearchField searchField = setSearchField(cqlResponseBO);
266 SearchCondition searchCondition = setSearchCondition(cqlResponseBO, searchField);
267 SearchParams searchParams = new SearchParams();
268 searchResultFields.setDocType(OleSRUConstants.BIBLIOGRAPHIC);
269 searchResultFields.setFieldName("id");
270 searchParams.getSearchResultFields().add(searchResultFields);
271 searchParams.getSearchConditions().add(searchCondition);
272 return searchParams;
273 }
274
275 if (flag) {
276 searchResultFields.setDocType(OleSRUConstants.BIBLIOGRAPHIC);
277 searchResultFields.setFieldName("id");
278 searchParams.getSearchResultFields().add(searchResultFields);
279 return searchParams;
280 }
281 return null;
282 }
283
284 private List getBibIds(Map reqParamMap, SearchParams searchParams) {
285 SearchResponse searchResponse = getDocstoreClient().search(searchParams);
286 List bibIds = new ArrayList();
287 List<OleSRUData> oleSRUDataList = new ArrayList<>();
288 for (SearchResult searchResult : searchResponse.getSearchResults()) {
289 OleSRUData oleSRUData ;
290 for (SearchResultField searchResultField : searchResult.getSearchResultFields()) {
291 if (searchResultField.getDocType().equalsIgnoreCase(DocType.BIB.getCode())) {
292 if (searchResultField.getFieldName().equalsIgnoreCase("id")) {
293 bibIds.add(searchResultField.getFieldValue());
294 oleSRUData = new OleSRUData();
295 oleSRUData.setBibId(searchResultField.getFieldValue());
296 BibTree bib = getDocstoreClient().retrieveBibTree(searchResultField.getFieldValue());
297 List<HoldingsTree> holdingsTrees = bib.getHoldingsTrees();
298 List<String> ids = new ArrayList<>();
299 for(HoldingsTree holdingsTree:holdingsTrees){
300 ids.add(holdingsTree.getHoldings().getId());
301 }
302
303
304
305
306
307 oleSRUData.setInstanceIds(ids);
308 oleSRUDataList.add(oleSRUData);
309 }
310 }
311 }
312 }
313 Integer size = searchResponse.getTotalRecordCount();
314 reqParamMap.put("numberOfRecords", size.longValue());
315 return oleSRUDataList;
316 }
317
318 private DocstoreClient getDocstoreClient() {
319
320 if (docstoreClient == null) {
321 docstoreClient = new DocstoreLocalClient();
322 }
323 return docstoreClient;
324 }
325
326 private SearchField setSearchField(CQLResponseBO cqlResponseBO) {
327 searchField = null;
328 if (cqlResponseBO != null) {
329 if (cqlResponseBO.getSearchClauseTag() != null) {
330 searchField = new SearchField();
331 if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.TITLE) ||
332 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_TITLE)) {
333 searchField.setFieldName(OleSRUConstants.TITLE_SEARCH);
334 } else if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.AUTHOR) ||
335 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_AUTHOR)) {
336 searchField.setFieldName(OleSRUConstants.AUTHOR_SEARCH);
337 } else if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.PUBLISHER) ||
338 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_PUBLISHER)) {
339 searchField.setFieldName(OleSRUConstants.PUBLISHER_SEARCH);
340 } else if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.PUBLICATION_DATE) ||
341 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.PUB_DATE) ||
342 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_PUBLICATION_DATE) ||
343 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_PUB_DATE)) {
344 searchField.setFieldName(OleSRUConstants.PUBLICATION_DATE_SEARCH);
345 } else if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.ISBN) ||
346 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_ISBN)) {
347 searchField.setFieldName(OleSRUConstants.ISBN_SEARCH);
348 } else if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.ISSN) ||
349 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_ISSN)) {
350 searchField.setFieldName(OleSRUConstants.ISSN_SEARCH);
351 } else if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.LOCALID) ||
352 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_LOCALID)) {
353 searchField.setFieldName(OleSRUConstants.LOCALID_SEARCH);
354 } else if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.SUBJECT) ||
355 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_SUBJECT)) {
356 searchField.setFieldName(OleSRUConstants.SUBJECT_SEARCH);
357 } else if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CHOICE) ||
358 cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.CS_CHOICE)) {
359 searchField.setFieldName(OleSRUConstants.ALL_TEXT);
360 }
361 searchField.setDocType(OleSRUConstants.BIBLIOGRAPHIC);
362 }
363 if (cqlResponseBO.getSearchClauseTag() != null && cqlResponseBO.getSearchClauseTag().getTerm() != null) {
364 String fieldValue=cqlResponseBO.getSearchClauseTag().getTerm().replaceAll("-","");
365 if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.ISBN)){
366 ISBNUtil isbnUtil = new ISBNUtil();
367 try {
368 fieldValue = isbnUtil.normalizeISBN(fieldValue);
369 } catch (OleException e) {
370 e.printStackTrace();
371 }
372 searchField.setFieldValue(fieldValue);
373 } else if(cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.PUBLICATION_DATE)){
374 if(cqlResponseBO.getSearchClauseTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue() != null && (cqlResponseBO.getSearchClauseTag().getRelationTag().getValue().equalsIgnoreCase("<=")||cqlResponseBO.getSearchClauseTag().getRelationTag().getValue().equalsIgnoreCase("<"))){
375 searchField.setFieldValue("[ * TO "+cqlResponseBO.getSearchClauseTag().getTerm()+" ]");
376 } else if(cqlResponseBO.getSearchClauseTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue() != null && (cqlResponseBO.getSearchClauseTag().getRelationTag().getValue().equalsIgnoreCase(">=")||cqlResponseBO.getSearchClauseTag().getRelationTag().getValue().equalsIgnoreCase(">"))){
377 searchField.setFieldValue("[ "+cqlResponseBO.getSearchClauseTag().getTerm()+" TO * ]");
378 } else{
379 searchField.setFieldValue(cqlResponseBO.getSearchClauseTag().getTerm());
380 }
381 } else{
382 searchField.setFieldValue(cqlResponseBO.getSearchClauseTag().getTerm());
383 }
384 }
385 }
386 return searchField;
387 }
388
389 private SearchCondition setSearchCondition(CQLResponseBO cqlResponseBO, SearchField searchField) {
390 searchCondition = new SearchCondition();
391 if (cqlResponseBO.getSearchClauseTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue().equalsIgnoreCase("any")) {
392 searchCondition.setSearchScope("or");
393 } else if (cqlResponseBO.getSearchClauseTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue().equalsIgnoreCase("all")) {
394 searchCondition.setSearchScope("and");
395 }else if (cqlResponseBO.getSearchClauseTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue().equalsIgnoreCase("adj")) {
396 searchCondition.setSearchScope("phrase");
397 } else {
398 searchCondition.setSearchScope("phrase");
399 }
400 if (null != searchField)
401 searchCondition.setSearchField(searchField);
402 if (null != cqlResponseBO && null != cqlResponseBO.getBooleanTagValue()) {
403 searchCondition.setOperator(cqlResponseBO.getBooleanTagValue().getValue());
404 } else {
405 searchCondition.setOperator("AND");
406 }
407 if (cqlResponseBO.getSearchClauseTag().getIndex().equalsIgnoreCase(OleSRUConstants.PUBLICATION_DATE)) {
408 if (cqlResponseBO.getSearchClauseTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue() != null && (cqlResponseBO.getSearchClauseTag().getRelationTag().getValue().equalsIgnoreCase("<="))) {
409 searchCondition.setSearchScope("LESS THAN EQUALS");
410 } else if (cqlResponseBO.getSearchClauseTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue() != null && (cqlResponseBO.getSearchClauseTag().getRelationTag().getValue().equalsIgnoreCase(">="))) {
411 searchCondition.setSearchScope("GREATER THAN EQUALS");
412 } else if (cqlResponseBO.getSearchClauseTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue() != null && (cqlResponseBO.getSearchClauseTag().getRelationTag().getValue().equalsIgnoreCase("<"))) {
413 searchCondition.setSearchScope("LESS THAN");
414 } else if (cqlResponseBO.getSearchClauseTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag() != null && cqlResponseBO.getSearchClauseTag().getRelationTag().getValue() != null && (cqlResponseBO.getSearchClauseTag().getRelationTag().getValue().equalsIgnoreCase(">"))) {
415 searchCondition.setSearchScope("GREATER THAN");
416 }
417 }
418 return searchCondition;
419 }
420 }