Fixes cce with new QueryParameter type
[mkjsf-moved-to-github.git] / src / main / java / com / indexdata / mkjsf / pazpar2 / commands / SearchCommand.java
1 package com.indexdata.mkjsf.pazpar2.commands;\r
2 \r
3 import java.util.Arrays;\r
4 import java.util.List;\r
5 \r
6 import javax.enterprise.context.SessionScoped;\r
7 import javax.inject.Named;\r
8 \r
9 import org.apache.log4j.Logger;\r
10 \r
11 import com.indexdata.mkjsf.pazpar2.Pz2Service;\r
12 import com.indexdata.mkjsf.pazpar2.commands.sp.ServiceProxyCommand;\r
13 import com.indexdata.mkjsf.pazpar2.data.ResponseDataObject;\r
14 \r
15 /**\r
16  * Represents a Pazpar2 <code>search</code> command. \r
17  * \r
18  * @author Niels Erik\r
19  *\r
20  */\r
21 @SessionScoped @Named\r
22 public class SearchCommand extends Pazpar2Command implements ServiceProxyCommand {\r
23   \r
24   private static final long serialVersionUID = -1888520867838597236L;\r
25   private static Logger logger = Logger.getLogger(SearchCommand.class);  \r
26     \r
27   public SearchCommand() {\r
28     super("search");\r
29   }\r
30   \r
31   public ResponseDataObject run() {\r
32     logger.info("Running " + getCommandName());\r
33     Pz2Service.get().getStateMgr().hasPendingStateChange("search",false);\r
34     Pz2Service.get().getPzresp().resetSearchAndBeyond();\r
35     Pz2Service.get().getPzreq().getRecord().removeParametersInState();        \r
36     Pz2Service.get().getPzreq().getShow().setParameterInState(new CommandParameter("start","=",0));    \r
37     Pz2Service.get().getSearchClient().setSearchCommand(this);\r
38     return super.run();\r
39   }\r
40 \r
41   /**\r
42    * Sets the <code>query</code> parameter. See Pazpar2 documentation for details.\r
43    */  \r
44   public void setQuery(String query) {    \r
45     setParameter(new QueryParameter("query","=",query));\r
46   }\r
47   \r
48   public void setBooleanOperatorForQuery(String operator) {\r
49     Pazpar2Command copy = this.copy();\r
50     ((QueryParameter) getParameter("query")).setBooleanOperator(operator);\r
51     checkInState(copy);\r
52   }\r
53   \r
54   /** \r
55    * Returns the simple part of the <code>query</code> parameter value, excluding parts that \r
56    * were added as expressions (that is, not set with <code>setQuery()</code>).\r
57    */\r
58   public String getQuery () {    \r
59     return getParameter("query") == null ? null  : ((QueryParameter)getParameter("query")).getSimpleValue();\r
60   }\r
61 \r
62   /** \r
63    * Returns the complete <code>query</code> parameter value, including expressions.\r
64    */\r
65   public String getExtendedQuery () {    \r
66     return getParameter("query") == null ? null  : ((QueryParameter)getParameter("query")).getValueWithExpressions();\r
67   }\r
68     \r
69   /**\r
70    * Sets the <code>filter</code> parameter. See Pazpar2 documentation for details.\r
71    */  \r
72   public void setFilter(String filterExpression) {\r
73     if (filterExpression != null && filterExpression.length()>0) {\r
74       if (filterExpression.split("[=~]").length==1) {\r
75         removeFilters(filterExpression.split("[=~]")[0]);\r
76       } else if (filterExpression.split("[=~]").length==2) {\r
77         setParameter(new FilterParameter(new Expression(filterExpression)));\r
78       } else {\r
79         logger.error("Could not parse filter expression [" + filterExpression + "]");\r
80       }\r
81     }\r
82   }\r
83   \r
84   /**\r
85    * Sets the <code>filter</code> parameter. See Pazpar2 documentation for details.\r
86    */  \r
87   public void setFilter(String field, String operator, String value, String label) {\r
88     setParameter(new FilterParameter(new Expression(field,operator,value,label)));\r
89   }\r
90 \r
91   /**\r
92    * Checks if there are any filter expressions matching any of the given expressionFields\r
93    * @param expressionFields expression fields (left-of-operator entities) to look for\r
94    * @return true if expression(s) found with any of <code>expressionFields</code> \r
95    */\r
96   public boolean hasFilterExpression(String... expressionFields) {\r
97     logger.trace("Checking for filter expression for " + Arrays.deepToString(expressionFields));\r
98     for (String field : expressionFields) {\r
99       if (getFilterExpressions(field) != null && getFilterExpressions(field).size()>0) {\r
100         logger.trace("Filter expression found (" + field + ")");\r
101         return true;\r
102       }  \r
103     }\r
104     logger.trace("No filter expressions found");\r
105     return false;\r
106   }\r
107 \r
108   \r
109   /** \r
110    * Returns the <code>filter</code> parameter value.\r
111    */\r
112   public String getFilter() {\r
113     return getParameter("filter") == null ? null : ((FilterParameter)getParameter("filter")).getValueWithExpressions();\r
114   }\r
115   \r
116   /**\r
117    * Returns the first filter expression of the given type\r
118    * @param expressionField expression field (left-of-operator entity) to look for\r
119    * @return the first filter expression found with the field <code>expressionField</code> or null if none found \r
120    */\r
121   public Expression getOneFilterExpression(String expressionField) {\r
122     List<Expression> exprs = getFilterExpressions(expressionField);\r
123     if (exprs != null && exprs.size()>0) {\r
124       if (exprs.size()>1) {\r
125         logger.warn("More that one filter expression found for [" + expressionField + "] but only asked to return the first one");\r
126       }\r
127       return exprs.get(0);\r
128     } else {\r
129       return null;\r
130     }    \r
131   }\r
132 \r
133   \r
134   /**\r
135    * Returns list of all filter expressions \r
136    */\r
137   public List<Expression> getFilterExpressions() {\r
138     return getParameter("filter").getExpressions();\r
139   }\r
140     \r
141   \r
142   public List<Expression> getFilterExpressions(String... expressionFields) {\r
143     logger.trace("Checking for filter parameter");\r
144     if (parameters.get("filter")!=null) {\r
145       logger.trace("Found");\r
146       return getParameter("filter").getExpressions(expressionFields);\r
147     } else {\r
148       logger.trace("Not found");\r
149       return null;\r
150     }\r
151   }\r
152   \r
153   public boolean hasFilter () {\r
154     return getFilter().length()>0;\r
155   }\r
156 \r
157   /**\r
158    * Adds a filter expression with a label for display. The filter is added to the end\r
159    * of an ordered list.  \r
160    * \r
161    * @param field\r
162    * @param operator\r
163    * @param value\r
164    * @param label\r
165    */\r
166   public void addFilter(String field, String operator, String value, String label) {\r
167     if (getParameter("filter") == null) {\r
168       setFilter(field + operator + value);\r
169     } else {\r
170       addExpression("filter",new Expression(field,operator,value,(label != null ? label : value)));\r
171     }\r
172   }\r
173 \r
174   /**\r
175    * Clears the filter parameter\r
176    */\r
177   public void removeFilters () {\r
178     removeParameter("filter");\r
179   }\r
180 \r
181   /**\r
182    * Removes a filter expression by exact attributes\r
183    * \r
184    * @param field\r
185    * @param operator\r
186    * @param value\r
187    */\r
188   public void removeFilter(String field, String operator, String value) {\r
189     removeExpression("filter",new Expression(field, operator, value, null));\r
190   }\r
191   \r
192   /**\r
193    * Removes all filter expressions matching a field listed in <code>fieldsToRemove</code>\r
194    * @param fieldsToRemove\r
195    */\r
196   public void removeFilters(String... fieldsToRemove) {    \r
197     removeExpressions("filter",fieldsToRemove);    \r
198   }  \r
199 \r
200   /**\r
201    * Removes filter expressions coming after the expression matching the provided filter expression, \r
202    * if they have a field listed in <code>fieldsToRemove</code>. To be used for bread crumb like UI \r
203    * controls.\r
204    * \r
205    * @param field\r
206    * @param operator\r
207    * @param value\r
208    * @param fieldsToRemove\r
209    */\r
210   public void removeFiltersAfter(String field, String operator, String value, String... fieldsToRemove) {     \r
211     removeExpressionsAfter("filter",new Expression(field,operator,value,null),fieldsToRemove);    \r
212   }\r
213 \r
214   /**\r
215    * Sets the <code>limit</code> parameter. See Pazpar2 documentation for details.\r
216    */  \r
217   public void setLimit (String limitExpression) {   \r
218     if (limitExpression != null && limitExpression.length()>0) {\r
219       setParameter(new LimitParameter(new Expression(limitExpression)));\r
220     }\r
221   }\r
222   \r
223   /**\r
224    * Sets the <code>limit</code> parameter including a label. See Pazpar2 documentation for details.\r
225    */  \r
226   public void setLimit(String field, String operator, String value, String label) {\r
227     setParameter(new LimitParameter(new Expression(field,operator,value,label)));\r
228   }\r
229       \r
230   /** \r
231    * Returns the <code>limit</code> parameter value.\r
232    */\r
233   public String getLimit () {\r
234     return getParameter("limit") == null ? null : ((FilterParameter)getParameter("limit")).getValueWithExpressions();    \r
235   }\r
236     \r
237   /**\r
238    * Checks if there are any limit expressions matching any of the given expressionFields\r
239    * @param expressionFields expression fields (left-of-operator entities) to look for\r
240    * @return true if expression(s) found with any of <code>expressionFields</code> \r
241    */\r
242   public boolean hasLimitExpression(String... expressionFields) {\r
243     logger.trace("Checking for limit expression for " + Arrays.deepToString(expressionFields));\r
244     for (String field : expressionFields) {\r
245       if (getLimitExpressions(field) != null && getLimitExpressions(field).size()>0) {\r
246         logger.trace("Limit expression found (" + field + ")");\r
247         return true;\r
248       }  \r
249     }\r
250     logger.trace("No limit expressions found");\r
251     return false;\r
252   }\r
253   \r
254   /**\r
255    * Returns the first limit expression of the given type\r
256    * @param expressionField expression field (left-of-operator entity) to look for\r
257    * @return the first limit expression found with the field <code>expressionField</code> or null if none found \r
258    */\r
259   public Expression getOneLimitExpression(String expressionField) {\r
260     List<Expression> exprs = getLimitExpressions(expressionField);\r
261     if (exprs != null && exprs.size()>0) {\r
262       if (exprs.size()>1) {\r
263         logger.warn("More that one limit expression found for [" + expressionField + "] but only asked to return the first one");\r
264       }\r
265       return exprs.get(0);\r
266     } else {\r
267       return null;\r
268     }    \r
269   }\r
270   \r
271   /**\r
272    * Return a list of all current limit expressions\r
273    */\r
274   public List<Expression> getLimitExpressions() {\r
275     return getParameter("limit").getExpressions();\r
276   }\r
277   \r
278   /**\r
279    * Returns a list of limit expressions with fields that matches on of <code>expressionFields</code>\r
280    * \r
281    * @param expressionFields limit expressions to look for\r
282    */\r
283   public List<Expression> getLimitExpressions(String... expressionFields) {\r
284     logger.trace("Checking for limit parameter");\r
285     if (parameters.get("limit")!=null) {\r
286       logger.trace("Found");\r
287       return getParameter("limit").getExpressions(expressionFields);\r
288     } else {\r
289       logger.trace("Not found");\r
290       return null;\r
291     }\r
292   }\r
293   \r
294   /**\r
295    * Adds a limit expression with a label for display. The limit is added to the end\r
296    * of an ordered list.  \r
297    * \r
298    * @param field\r
299    * @param operator\r
300    * @param value\r
301    * @param label\r
302    */\r
303   public void addLimit(String field, String operator, String value, String label) {\r
304     if (getParameter("limit") == null) {\r
305       setLimit(field, operator, value, label);\r
306     } else {\r
307       addExpression("limit",new Expression(field,operator,value,label));      \r
308     }\r
309   }\r
310   \r
311   /**\r
312    * Clears the limit parameter\r
313    */\r
314   public void removeLimits() {\r
315     removeParameter("limit");\r
316   }\r
317   \r
318   /**\r
319    * Removes all limit expressions that have fields as listed in <code>fieldsToRemove</code>\r
320    * @param fieldsToRemove\r
321    */\r
322   public void removeLimits(String... fieldsToRemove) {    \r
323     removeExpressions("limit",fieldsToRemove);    \r
324   }\r
325   \r
326   /**\r
327    * Removes a limit expression by exact attributes\r
328    * \r
329    * @param field\r
330    * @param operator\r
331    * @param value\r
332    */\r
333   public void removeLimit(String field, String operator, String value) {\r
334     removeExpression("limit",new Expression(field, operator, value, null));    \r
335   }\r
336   \r
337   /**\r
338    * Removes limit expressions coming after the provided limit expression, if they have a field listed in\r
339    * <code>fieldsToRemove</code>. To be used for bread crumb like UI controls.\r
340    * \r
341    * @param field\r
342    * @param operator\r
343    * @param value\r
344    * @param fieldsToRemove\r
345    */\r
346   public void removeLimitsAfter(String field, String operator, String value, String... fieldsToRemove) {     \r
347     removeExpressionsAfter("limit",new Expression(field,operator,value,null),fieldsToRemove);    \r
348   }\r
349 \r
350         \r
351   /**\r
352    * Sets the <code>startrecs</code> parameter. See Pazpar2 documentation for details.\r
353    */  \r
354   public void setStartrecs (String startrecs) {\r
355     setParameter(new CommandParameter("startrecs","=",startrecs));\r
356   }\r
357   \r
358   /** \r
359    * Returns the <code>startrecs</code> parameter value.\r
360    */\r
361   public String getStartrecs () {\r
362     return getParameterValue("startrecs");\r
363   }\r
364   \r
365   /**\r
366    * Sets the <code>maxrecs</code> parameter. See Pazpar2 documentation for details.\r
367    */  \r
368   public void setMaxrecs (String maxrecs) {\r
369     setParameter(new CommandParameter("maxrecs","=",maxrecs));\r
370   }\r
371   \r
372   /** \r
373    * Returns the <code>maxrecs</code> parameter value.\r
374    */\r
375   public String getMaxrecs () {\r
376     return getParameterValue("maxrecs");\r
377   }\r
378   \r
379   /**\r
380    * Sets the <code>sort</code> parameter. See Pazpar2 documentation for details.\r
381    */  \r
382   public void setSort (String sort) {\r
383     setParameter(new CommandParameter("sort","=",sort));\r
384   }\r
385   \r
386   /** \r
387    * Returns the <code>sort</code> parameter value.\r
388    */\r
389   public String getSort () {\r
390     return getParameterValue("sort");\r
391   }\r
392   \r
393   /**\r
394    * Sets the <code>rank</code> parameter. See Pazpar2 documentation for details.\r
395    */  \r
396   public void setRank (String rank) {\r
397     setParameter(new CommandParameter("rank","=",rank));\r
398   }\r
399   \r
400   /** \r
401    * Returns the <code>rank</code> parameter value.\r
402    */\r
403   public String getRank () {\r
404     return getParameterValue("rank");\r
405   }\r
406   \r
407   /**\r
408    * Sets the <code>mergekey</code> parameter. See Pazpar2 documentation for details.\r
409    */  \r
410   public void setMergekey (String mergekey) {\r
411     setParameter(new CommandParameter("mergekey","=",mergekey));\r
412   }\r
413   \r
414   /** \r
415    * Returns the <code>mergekey</code> parameter value.\r
416    */\r
417   public String getMergekey () {\r
418     return getParameterValue("mergekey");\r
419   }\r
420   \r
421   \r
422   /**\r
423    * Adds an expression - for instance a facet criterion, with an optional label - to the query parameter\r
424    * \r
425    * <p>Example:</p>\r
426    * <ul>\r
427    *  <li><code>{au}{=}{"Steinbeck, John"}{Steinbeck, John}</code>\r
428    * </ul>\r
429    */\r
430   public void addQueryExpression(String field, String operator, String term, String label) {\r
431     if (term != null && term.length()>0) { \r
432       addExpression("query", new Expression(field,operator,term,label));                  \r
433     }            \r
434   }\r
435   \r
436   /**\r
437    * Removes a query expression - for instance a facet criterion - by its exact attributes\r
438    * \r
439    * @param field\r
440    * @param operator\r
441    * @param value\r
442    */\r
443   public void removeQueryExpression(String field, String operator, String value) {\r
444     removeExpression("query",new Expression(field, operator, value, null));    \r
445   }\r
446 \r
447   \r
448   /**\r
449    * Sets a facet to limit the current query by. The \r
450    * facet is appended to the query string itself (rather\r
451    * as a separately managed entity. It will thus appear\r
452    * in a query field as retrieved by getQuery(). It will\r
453    * not be removed by removeFacet(...)\r
454    * \r
455    * @param facetKey  i.e. 'au' for author\r
456    * @param term i.e. 'Dickens, Charles'\r
457    */\r
458   public void setFacetOnQuery (String facetKey, String term) {\r
459     String facetExpression = facetKey + "=" + term;    \r
460     if (term != null && term.length()>0) {\r
461       String currentQuery= getQuery();\r
462       setParameter(new QueryParameter("query","=", currentQuery + " and " + facetExpression));      \r
463     }            \r
464   }\r
465       \r
466   /**\r
467    * Removes a facet set by setFacet(...)\r
468    * \r
469    * Will not remove facets set by setFacetOnQuery(...)\r
470    *  \r
471    * @param facetKey i.e. 'au' for author\r
472    * @param term i.e. 'Dickens, Charles'\r
473    */\r
474   public void removeFacet(String facetKey, String term) {\r
475     if (getParameter("query") != null) {\r
476       removeExpression("query",new Expression(facetKey,"=",term,null));\r
477     }\r
478   }\r
479       \r
480   public SearchCommand copy () {\r
481     SearchCommand newCommand = new SearchCommand();\r
482     for (String parameterName : parameters.keySet()) {\r
483       newCommand.setParameterInState(parameters.get(parameterName).copy());      \r
484     }\r
485     return newCommand;\r
486   }\r
487 \r
488   @Override\r
489   public ServiceProxyCommand getSp() {\r
490     return this;\r
491   }\r
492 \r
493   @Override\r
494   public boolean spOnly() {\r
495     return false;\r
496   }\r
497 \r
498 }\r