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