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