Work-in-progress on interchangeable config mechanisms
[mkjsf-moved-to-github.git] / src / main / java / com / indexdata / pz2utils4jsf / pazpar2 / Pz2Session.java
1 package com.indexdata.pz2utils4jsf.pazpar2;\r
2 \r
3 import java.io.Serializable;\r
4 import java.util.ArrayList;\r
5 import java.util.List;\r
6 import java.util.Map;\r
7 import java.util.StringTokenizer;\r
8 import java.util.concurrent.ConcurrentHashMap;\r
9 \r
10 import org.apache.log4j.Logger;\r
11 \r
12 import com.indexdata.masterkey.pazpar2.client.exceptions.ProxyErrorException;\r
13 import com.indexdata.pz2utils4jsf.config.Pz2Configurator;\r
14 import com.indexdata.pz2utils4jsf.controls.ResultsPager;\r
15 import com.indexdata.pz2utils4jsf.pazpar2.data.ByTarget;\r
16 import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseData;\r
17 import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseParser;\r
18 import com.indexdata.pz2utils4jsf.pazpar2.data.RecordResponse;\r
19 import com.indexdata.pz2utils4jsf.pazpar2.data.ShowResponse;\r
20 import com.indexdata.pz2utils4jsf.pazpar2.data.StatResponse;\r
21 import com.indexdata.pz2utils4jsf.pazpar2.data.TermListsResponse;\r
22 import com.indexdata.pz2utils4jsf.pazpar2.data.TermResponse;\r
23 import com.indexdata.pz2utils4jsf.pazpar2.state.QueryStates;\r
24 \r
25 public class Pz2Session implements Serializable, Pz2Interface {\r
26   \r
27   private static Logger logger = Logger.getLogger(Pz2Session.class);\r
28   \r
29   private Map<String,Pazpar2ResponseData> dataObjects = new ConcurrentHashMap<String,Pazpar2ResponseData>();\r
30   private QueryStates queryStates = new QueryStates();\r
31   \r
32   private static final long serialVersionUID = 3947514708343320514L;  \r
33   private com.indexdata.masterkey.pazpar2.client.Pazpar2ClientConfiguration cfg = null;\r
34   private com.indexdata.masterkey.pazpar2.client.Pazpar2Client client = null;   \r
35   private TargetFilter targetFilter = null;  \r
36   private ResultsPager pager = null; \r
37   \r
38   public Pz2Session (Pz2Configurator pz2conf) {\r
39     logger.debug("Instantiating pz2");  \r
40     if (pz2conf == null) {logger.error("conf is null!!!!!!!!!!!!!!!"); }\r
41     try {\r
42       cfg = new com.indexdata.masterkey.pazpar2.client.Pazpar2ClientConfiguration(pz2conf.getConfig());\r
43       client = new com.indexdata.masterkey.pazpar2.client.Pazpar2ClientGeneric(cfg);\r
44       resetDataObjects();\r
45     } catch (ProxyErrorException e) {\r
46       e.printStackTrace();\r
47     }    \r
48   }\r
49 \r
50   public void doSearch(String query) {\r
51     setCommandParameter("search",new CommandParameter("query","=",query));     \r
52     doSearch();\r
53   }\r
54 \r
55   public void doSearch() { \r
56     queryStates.hasPendingStateChange("search",false);\r
57     resetDataObjects();\r
58     setCommandParameter("show",new CommandParameter("start","=",0));    \r
59     logger.info("Searching using "+getCommand("search").getParameter("query").getEncodedQueryString());\r
60     doCommand("search");    \r
61   }\r
62       \r
63   /**\r
64    * Refreshes 'show', 'stat', 'termlist', and 'bytarget' data object from pazpar2\r
65    * \r
66    * @return Number of activeclients at the time of the 'show' command.\r
67    */\r
68   public String update () {\r
69     logger.info("Updating show,stat,termlist, and bytarget data from pazpar2");\r
70     return update("show,stat,termlist,bytarget");\r
71   }\r
72  \r
73   /**\r
74    * Refreshes the data objects listed in 'commands' from pazpar2\r
75    * \r
76    * @param commands\r
77    * @return Number of activeclients at the time of the 'show' command\r
78    */\r
79   public String update (String commands) {\r
80     if (hasQuery()) {\r
81       handleQueryStateChanges(commands);\r
82       logger.debug("Processing request for " + commands); \r
83       List<CommandThread> threadList = new ArrayList<CommandThread>();\r
84       StringTokenizer tokens = new StringTokenizer(commands,",");\r
85       while (tokens.hasMoreElements()) {\r
86         threadList.add(new CommandThread(getCommand(tokens.nextToken()),client));            \r
87       }\r
88       for (CommandThread thread : threadList) {\r
89         thread.start();\r
90       }\r
91       for (CommandThread thread : threadList) {\r
92         try {\r
93           thread.join();\r
94         } catch (InterruptedException e) {\r
95           e.printStackTrace();\r
96         }\r
97       }\r
98       for (CommandThread thread : threadList) {\r
99         if (!thread.getCommand().getName().equals("search")) {\r
100           dataObjects.put(thread.getCommand().getName(), new Pazpar2ResponseParser().getObject(thread.getResponse()));\r
101         }\r
102       }\r
103       return getActiveClients();\r
104     } else {\r
105       logger.info("Skipped requests for " + commands + " as there's not yet a query."); \r
106       resetDataObjects();\r
107       return "0";\r
108     }\r
109     \r
110   }\r
111         \r
112   public void setQuery (String query) {\r
113     logger.debug("Creating new command parameter for " + query);\r
114     setCommandParameter("search",new CommandParameter("query","=",query));\r
115   }\r
116   \r
117   public String getQuery () {\r
118     return getCommandParameterValueSimple("search","query",null);\r
119   }\r
120   \r
121   public void setFacet (String facetKey, String term) {           \r
122     if (term != null && term.length()>0) {\r
123       queryStates.getCurrentState().setCommandParameterExpression("search","query",new Expression(facetKey,"=",term),queryStates);\r
124       doSearch();\r
125     }            \r
126   }\r
127   \r
128   public void setFacetOnQuery (String facetKey, String term) {\r
129     String facetExpression = facetKey + "=" + term;    \r
130     if (term != null && term.length()>0) {\r
131       setCommandParameter("search",new CommandParameter("query","=", getQuery() + " and " + facetExpression));\r
132       doSearch();        \r
133     }            \r
134   }\r
135       \r
136   public void removeFacet(String facetKey, String term) {\r
137     queryStates.getCurrentState().removeCommandParameterExpression("search","query",new Expression(facetKey,"=",term),queryStates);\r
138     doSearch();\r
139   }\r
140   \r
141   public void setTargetFilter (String targetId, String targetName) {    \r
142     if (hasTargetFilter(new TargetFilter(targetId,targetName))) {\r
143       logger.debug("Already using target filter " + this.targetFilter.getFilterExpression());\r
144     } else {      \r
145       this.targetFilter = new TargetFilter(targetId,targetName);\r
146       setCommandParameter("search",new CommandParameter("filter","=",this.targetFilter.getFilterExpression()));      \r
147       doSearch();\r
148     }    \r
149   }\r
150 \r
151   public TargetFilter getTargetFilter () {\r
152     return targetFilter;\r
153   }\r
154     \r
155   public void removeTargetFilter () {\r
156     logger.debug("Removing target filter " + targetFilter.getFilterExpression());\r
157     this.targetFilter = null;\r
158     removeCommandParameter("search","filter");         \r
159     doSearch();\r
160   }\r
161   \r
162   public boolean hasTargetFilter() {\r
163     return targetFilter != null;    \r
164   }\r
165         \r
166   public void setSort (String sortOption) {\r
167     logger.debug("Setting sort option: " + sortOption);\r
168     setCommandParameter("show",new CommandParameter("sort","=",sortOption));\r
169     update("show");\r
170   }\r
171   \r
172   public String getSort () {\r
173     return getCommandParameterValue("show","sort","relevance");\r
174   }\r
175     \r
176   public void setPageSize (int perPageOption) {\r
177     if (getPageSize()!=perPageOption) {\r
178      logger.debug("Setting perpage option to " + perPageOption + " and resetting start page.");\r
179      setCommandParameter("show",new CommandParameter("num","=",perPageOption));\r
180      setCommandParameter("show",new CommandParameter("start","=",0));\r
181      update("show");\r
182     } else {\r
183       logger.debug("Not updating page size, already is " + perPageOption);\r
184     }\r
185   }\r
186   \r
187   public int getPageSize () {\r
188     return getCommandParameterValue("show","num",20);\r
189   }\r
190   \r
191   public void setStart (int start) {\r
192     logger.debug("Setting start num to " + start);\r
193     setCommandParameter("show", new CommandParameter("start","=",start));  \r
194     update("show");\r
195   }\r
196   \r
197   public int getStart() {\r
198     return getCommandParameterValue("show","start",0);\r
199   }\r
200         \r
201   public String toggleRecord (String recId) {\r
202     if (hasRecord(recId)) {\r
203       removeCommand("record");  \r
204       dataObjects.put("record", new RecordResponse());\r
205       return "";\r
206     } else {\r
207       return updateRecord(recId);\r
208     }\r
209   }\r
210   \r
211   private String updateRecord(String recId) {    \r
212     setCommandParameter("record",new CommandParameter("id","=",recId));    \r
213     return doCommand("record");    \r
214   }\r
215   \r
216   public boolean hasRecord (String recId) {\r
217     return getCommand("record").hasParameters() && getRecord().getRecId().equals(recId);\r
218   }\r
219       \r
220   public ShowResponse getShow () {\r
221     return ((ShowResponse) dataObjects.get("show"));\r
222   }\r
223   \r
224   public StatResponse getStat () {\r
225     return ((StatResponse) dataObjects.get("stat"));\r
226   }\r
227   \r
228   public RecordResponse getRecord() {\r
229     return ((RecordResponse) dataObjects.get("record"));\r
230   }\r
231   \r
232   public TermListsResponse getTermLists () {\r
233     return ((TermListsResponse) dataObjects.get("termlist"));\r
234   }\r
235   \r
236   public List<TermResponse> getFacetTerms (String facet, int count) {\r
237     return (getTermLists().getTermList(facet).getTerms(count));\r
238   }\r
239     \r
240   public List<TermResponse> getFacetTerms (String facet) {\r
241     return (getTermLists().getTermList(facet).getTerms());\r
242   }\r
243   \r
244   public ByTarget getByTarget() {\r
245     return ((ByTarget) dataObjects.get("bytarget"));\r
246   }\r
247   \r
248   \r
249   public String getCurrentStateKey () {    \r
250     return queryStates.getCurrentStateKey();\r
251   }\r
252       \r
253   public void setCurrentStateKey(String key) {\r
254     logger.debug("************** request to set state key to: [" + key + "]");    \r
255     queryStates.setCurrentStateKey(key);\r
256   }\r
257     \r
258   private boolean hasTargetFilter(TargetFilter targetFilter) {\r
259     return hasTargetFilter() && targetFilter.equals(this.targetFilter);\r
260   }\r
261   \r
262   private boolean hasQuery() {\r
263     return !(getCommand("search").getParameter("query") == null);\r
264   }\r
265     \r
266   public boolean hasRecords () {\r
267     return getStat().getRecords() > 0            \r
268            && getShow().getHits() != null \r
269            && getShow().getHits().size()>0;\r
270   }\r
271     \r
272   public ResultsPager getPager () {\r
273     if (pager == null) {\r
274       pager = new ResultsPager(this);      \r
275     } \r
276     return pager;      \r
277   }\r
278   \r
279   public ResultsPager setPager (int pageRange) {\r
280     pager =  new ResultsPager(this,pageRange);\r
281     return pager;\r
282   }\r
283   \r
284   private void handleQueryStateChanges (String commands) {\r
285     if (queryStates.hasPendingStateChange("search")) { \r
286       logger.debug("Found pending search change. Doing search before updating " + commands);\r
287       doSearch();\r
288     } \r
289     if (queryStates.hasPendingStateChange("record") && ! commands.equals("record")) {        \r
290       logger.debug("Found pending record ID change. Doing record before updating " + commands);\r
291       queryStates.hasPendingStateChange("record",false);\r
292       if (getCommand("record").hasParameters()) {\r
293         updateRecord(getCommand("record").getParameter("id").getSimpleValue());\r
294       } else {\r
295         removeCommand("record");  \r
296         dataObjects.put("record", new RecordResponse());\r
297       }\r
298     }    \r
299   }\r
300 \r
301   private String getActiveClients() {\r
302     logger.debug("Active clients: "+getShow().getActiveClients());\r
303     if (getShow()!=null) {\r
304       return getShow().getActiveClients();\r
305     } else {\r
306       return "";\r
307     }\r
308   }\r
309 \r
310   private Pazpar2Command getCommand(String name) {\r
311     return queryStates.getCurrentState().getCommand(name);\r
312   }\r
313   \r
314   private void setCommandParameter(String commandName, CommandParameter parameter) {\r
315     logger.debug("Setting parameter for " + commandName + ": " + parameter);\r
316     queryStates.getCurrentState().setCommandParameter(commandName, parameter, queryStates);    \r
317   }\r
318   \r
319   \r
320   private void removeCommandParameter(String commandName, String parameterName) {\r
321     queryStates.getCurrentState().removeCommandParameter(commandName,parameterName,queryStates);    \r
322   }\r
323   \r
324   private void removeCommand (String commandName) {\r
325     queryStates.getCurrentState().removeCommand(commandName, queryStates);\r
326   }\r
327     \r
328   private String getCommandParameterValue (String commandName, String parameterName, String defaultValue) {    \r
329     Pazpar2Command command = getCommand(commandName);\r
330     if (command != null) {\r
331       CommandParameter parameter = command.getParameter(parameterName);\r
332       if (parameter != null) {\r
333         return parameter.getValueWithExpressions();\r
334       }\r
335     }\r
336     return defaultValue;    \r
337   }\r
338   \r
339   private String getCommandParameterValueSimple (String commandName, String parameterName, String defaultValue) {    \r
340     Pazpar2Command command = getCommand(commandName);\r
341     if (command != null) {\r
342       CommandParameter parameter = command.getParameter(parameterName);\r
343       if (parameter != null) {\r
344         return parameter.getSimpleValue();\r
345       }\r
346     }\r
347     return defaultValue;    \r
348   }\r
349 \r
350   \r
351   private int getCommandParameterValue (String commandName, String parameterName, int defaultValue) {\r
352     Pazpar2Command command = getCommand(commandName);\r
353     if (command != null) {\r
354       CommandParameter parameter = command.getParameter(parameterName);\r
355       if (parameter != null) {\r
356         return Integer.parseInt(parameter.getSimpleValue());\r
357       }\r
358     }\r
359     return defaultValue;    \r
360   }\r
361 \r
362   private String doCommand(String commandName) {\r
363     Pazpar2Command command = getCommand(commandName);    \r
364     logger.debug(command.getEncodedQueryString() + ": Results for "+ getCommand("search").getEncodedQueryString());\r
365     return update(commandName);\r
366   }\r
367   \r
368   private void resetDataObjects() {\r
369     logger.debug("Resetting show,stat,termlist,bytarget response objects.");\r
370     dataObjects = new ConcurrentHashMap<String,Pazpar2ResponseData>();\r
371     dataObjects.put("show", new ShowResponse());\r
372     dataObjects.put("stat", new StatResponse());\r
373     dataObjects.put("termlist", new TermListsResponse());\r
374     dataObjects.put("bytarget", new ByTarget());\r
375     dataObjects.put("record", new RecordResponse());\r
376   }\r
377 \r
378 }\r