Adds beans and configs
authorNiels Erik G. Nielsen <nielserik@indexdata.com>
Thu, 28 Feb 2013 21:51:52 +0000 (16:51 -0500)
committerNiels Erik G. Nielsen <nielserik@indexdata.com>
Thu, 28 Feb 2013 21:51:52 +0000 (16:51 -0500)
34 files changed:
src/META-INF/beans.xml [new file with mode: 0644]
src/META-INF/context.xml [new file with mode: 0644]
src/META-INF/faces-config.xml [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/config/FacesModuleConfiguration.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/config/JsfdemoModuleConfiguration.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/config/JsfdemoPazpar2ClientConfiguration.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/controls/PageLink.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/controls/ResultsPager.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/exceptions/CustomExceptionHandler.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/exceptions/CustomExceptionHandlerFactory.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/CommandParameter.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/CommandThread.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Expression.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Pazpar2Command.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Pz2Bean.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Pz2Interface.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Pz2Session.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/TargetFilter.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/ByTarget.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Hit.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Location.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Pazpar2ResponseData.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Pazpar2ResponseParser.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/RecordResponse.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/ShowResponse.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/StatResponse.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Target.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/TermListResponse.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/TermListsResponse.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/TermResponse.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/TermXTargetResponse.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/state/QueryState.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/state/QueryStates.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pz2utils/ListenerFieldIds.java [new file with mode: 0644]

diff --git a/src/META-INF/beans.xml b/src/META-INF/beans.xml
new file mode 100644 (file)
index 0000000..b87599c
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://java.sun.com/xml/ns/javaee"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="
+      http://java.sun.com/xml/ns/javaee 
+      http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
+</beans>
\ No newline at end of file
diff --git a/src/META-INF/context.xml b/src/META-INF/context.xml
new file mode 100644 (file)
index 0000000..7f18535
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<Context>\r
+    <Resource name="BeanManager"\r
+              auth="Container"\r
+              type="javax.enterprise.inject.spi.BeanManager"\r
+              factory="org.jboss.weld.resources.ManagerObjectFactory"/>\r
+    <WatchedResource>WEB-INF/web.xml</WatchedResource>\r
+    <WatchedResource>META-INF/context.xml</WatchedResource>\r
+</Context>
\ No newline at end of file
diff --git a/src/META-INF/faces-config.xml b/src/META-INF/faces-config.xml
new file mode 100644 (file)
index 0000000..8e033da
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd"
+  version="2.1">
+
+  <factory>
+       <exception-handler-factory>com.indexdata.pz2utils4jsf.exceptions.CustomExceptionHandlerFactory</exception-handler-factory>
+  </factory>
+</faces-config>
\ No newline at end of file
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/config/FacesModuleConfiguration.java b/src/main/java/com/indexdata/pz2utils4jsf/config/FacesModuleConfiguration.java
new file mode 100644 (file)
index 0000000..055ca0e
--- /dev/null
@@ -0,0 +1,50 @@
+package com.indexdata.pz2utils4jsf.config;\r
+\r
+import java.io.IOException;\r
+import java.io.Serializable;\r
+\r
+import javax.faces.context.ExternalContext;\r
+import javax.faces.context.FacesContext;\r
+import javax.servlet.ServletContext;\r
+import javax.servlet.http.HttpServletRequest;\r
+\r
+import com.indexdata.masterkey.config.MasterkeyConfiguration;\r
+import com.indexdata.masterkey.config.ModuleConfiguration;\r
+import com.indexdata.masterkey.config.ModuleConfigurationGetter;\r
+\r
+public abstract class FacesModuleConfiguration implements ModuleConfigurationGetter, Serializable {\r
+\r
+  private static final long serialVersionUID = -7225977088088592928L;\r
+  private ModuleConfiguration config;\r
+\r
+  public FacesModuleConfiguration() {\r
+    if (FacesContext.getCurrentInstance() != null) {\r
+      ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();\r
+      HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();\r
+      ServletContext servletContext = (ServletContext) externalContext.getContext();\r
+      String host = request.getServerName();\r
+      try {\r
+        config = MasterkeyConfiguration.getModuleConfiguration(servletContext, host, getComponentName(), getModuleName());\r
+      } catch (IOException ioe) {\r
+        ioe.printStackTrace();\r
+      }\r
+    }\r
+  }\r
+\r
+  public String get(String name) {\r
+    return config.get(name);\r
+  }\r
+\r
+  public String get(String name, String defaultValue) {\r
+    return config.get(name, defaultValue);\r
+  }\r
+  \r
+  public ModuleConfiguration getModuleConfiguration () {\r
+    return config;\r
+  }\r
+  \r
+  public abstract String getModuleName();\r
+  \r
+  public abstract String getComponentName();\r
+\r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/config/JsfdemoModuleConfiguration.java b/src/main/java/com/indexdata/pz2utils4jsf/config/JsfdemoModuleConfiguration.java
new file mode 100644 (file)
index 0000000..1d4b8bd
--- /dev/null
@@ -0,0 +1,17 @@
+package com.indexdata.pz2utils4jsf.config;\r
+\r
+import com.indexdata.pz2utils4jsf.config.FacesModuleConfiguration;\r
+\r
+public abstract class JsfdemoModuleConfiguration extends FacesModuleConfiguration {\r
+\r
+  private static final long serialVersionUID = -2936339728016978922L;\r
+\r
+  @Override\r
+  public abstract String getModuleName();\r
+\r
+  @Override\r
+  public String getComponentName() {\r
+    return "jsfdemo";\r
+  }\r
+\r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/config/JsfdemoPazpar2ClientConfiguration.java b/src/main/java/com/indexdata/pz2utils4jsf/config/JsfdemoPazpar2ClientConfiguration.java
new file mode 100644 (file)
index 0000000..a19a95f
--- /dev/null
@@ -0,0 +1,19 @@
+package com.indexdata.pz2utils4jsf.config;\r
+\r
+import javax.enterprise.context.SessionScoped;\r
+import javax.inject.Named;\r
+\r
+import com.indexdata.pz2utils4jsf.config.JsfdemoModuleConfiguration;\r
+\r
+@Named("pz2clientConfig")\r
+@SessionScoped\r
+public class JsfdemoPazpar2ClientConfiguration extends JsfdemoModuleConfiguration {\r
+\r
+  private static final long serialVersionUID = 8865086878660568870L;\r
+  \r
+  @Override\r
+  public String getModuleName() {\r
+    return "pz2client";\r
+  }\r
+\r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/controls/PageLink.java b/src/main/java/com/indexdata/pz2utils4jsf/controls/PageLink.java
new file mode 100644 (file)
index 0000000..e9c4ac0
--- /dev/null
@@ -0,0 +1,38 @@
+package com.indexdata.pz2utils4jsf.controls;\r
+\r
+import java.io.Serializable;\r
+\r
+import com.indexdata.pz2utils4jsf.controls.ResultsPager;\r
+\r
+public class PageLink implements Serializable {\r
+\r
+  private static final long serialVersionUID = -468888598965842949L;\r
+  String text = "";\r
+  int page = 0;\r
+  ResultsPager pager;\r
+  public PageLink(String text, int page, ResultsPager pager) {\r
+    this.text = text;\r
+    this.page = page;\r
+    this.pager = pager;\r
+  }\r
+  \r
+  public boolean isLink() {\r
+    return page>0;\r
+  }\r
+  \r
+  public boolean isCurrent() {\r
+    return (pager.getCurrentPageNum()==page);\r
+  }\r
+  \r
+  public String getText() {\r
+    return text;\r
+  }\r
+  \r
+  public int getPage() {\r
+    return page;\r
+  }\r
+  \r
+  public int getStart() {\r
+    return pager.getPageSize()*(page-1);\r
+  }\r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/controls/ResultsPager.java b/src/main/java/com/indexdata/pz2utils4jsf/controls/ResultsPager.java
new file mode 100644 (file)
index 0000000..95a2048
--- /dev/null
@@ -0,0 +1,145 @@
+package com.indexdata.pz2utils4jsf.controls;\r
+\r
+import java.io.Serializable;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import com.indexdata.pz2utils4jsf.controls.PageLink;\r
+import com.indexdata.pz2utils4jsf.pazpar2.Pz2Session;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.ShowResponse;\r
+\r
+public class ResultsPager implements Serializable {\r
+\r
+  private static final long serialVersionUID = 8854795222615583071L;\r
+  private Pz2Session pz2session = null;\r
+  private int pageRangeLength = 13;\r
+  \r
+  public ResultsPager(Pz2Session session) {\r
+    this.pz2session = session;     \r
+  }\r
+  \r
+  public ResultsPager(Pz2Session session, int pageRange) {\r
+    this.pz2session = session;\r
+    this.pageRangeLength = pageRange;\r
+  }\r
+  \r
+  private boolean hasHits () {\r
+    return (getShow().getMerged()>0);\r
+  }\r
+  \r
+  public int getCurrentPageNum () {\r
+    if (hasHits() && getShow().getNum()>0) {      \r
+      return (getShow().getStart()/getShow().getNum())+1;\r
+    } else {\r
+      return 0;\r
+    }\r
+  }\r
+  \r
+  public int getPageSize() {\r
+    return getShow().getNum();\r
+  }\r
+    \r
+  public int getFirstDisplayedPageNum () {\r
+    if (hasHits()) {\r
+      if (getCurrentPageNum() - (pageRangeLength/2) < 1) {\r
+        return 1;\r
+      } else {\r
+        return (getCurrentPageNum()-(pageRangeLength/2));\r
+      }\r
+    } else {\r
+      return 0;\r
+    }\r
+  }\r
+    \r
+  public int getLastDisplayedPageNum () {\r
+    if (hasHits()) {\r
+      if ((getFirstDisplayedPageNum() + pageRangeLength-1) > getLastPageNum()) {\r
+        return getLastPageNum();\r
+      } else {\r
+        return getFirstDisplayedPageNum() + pageRangeLength - 1;\r
+      }\r
+    } else {\r
+      return 0;\r
+    }\r
+  }\r
+  \r
+  public int getLastPageNum () {\r
+    if (hasHits()) {\r
+      return (int) Math.ceil(new Double(getShow().getMerged())/new Double(getShow().getNum()));\r
+    } else {\r
+      return 0;\r
+    }\r
+  }\r
+  \r
+  public List<PageLink> setPageLinks (int rangeLength) {\r
+    this.pageRangeLength = rangeLength;\r
+    return getPageLinks();\r
+  }\r
+  \r
+  public List<PageLink> getPageLinks () {    \r
+    ArrayList<PageLink> range = new ArrayList<PageLink>();\r
+    if (hasHits()) {\r
+      for (int i = getFirstDisplayedPageNum(); i>0 && i<=getLastDisplayedPageNum();i++) {\r
+        range.add(new PageLink(i+"",i,this));\r
+      }\r
+    }\r
+    return range;\r
+  }\r
+\r
+  \r
+  public PageLink getPreviousPageLink (String text) {    \r
+    String linkText = (text!=null && text.length()>0 ? text : "Prev");\r
+    if (hasHits() && getCurrentPageNum()>1) {      \r
+      return new PageLink(linkText,getCurrentPageNum()-1,this);\r
+    } else {\r
+      return new PageLink(linkText,0,this);\r
+    }\r
+  }\r
+  \r
+  public PageLink getNextPageLink (String text) {    \r
+    String linkText = (text!=null && text.length()>0 ? text : "Next");\r
+    if (hasHits() && getCurrentPageNum()<getLastPageNum()) {\r
+      return new PageLink(linkText,getCurrentPageNum()+1,this);\r
+    } else {\r
+      return new PageLink(linkText,0,this);\r
+    }    \r
+  }\r
+  \r
+  public int getCurrentPage() {\r
+    return (getShow().getStart()/getPageSize()+1);\r
+  }\r
+  \r
+  public void goToPage(int page) {    \r
+    pz2session.setStart((page-1)*getPageSize());\r
+  }\r
+  \r
+  public void goToPreviousPage() {\r
+    if (hasPreviousPage()) {\r
+      goToPage(getCurrentPage()-1);  \r
+    }    \r
+  }\r
+  \r
+  public void goToNextPage() {\r
+    if (hasNextPage()) {\r
+      goToPage(getCurrentPage()+1);\r
+    }\r
+  }\r
+  \r
+  public boolean hasPreviousPage() {\r
+    return getCurrentPage()>1;\r
+  }\r
+      \r
+  public boolean hasNextPage () {\r
+    return getCurrentPage() < getLastPageNum();\r
+  }\r
+  \r
+  public boolean hasPageAfterLastDisplayed() {\r
+    return getLastDisplayedPageNum() < getLastPageNum();\r
+  }\r
+\r
+  \r
+  private ShowResponse getShow() {\r
+    return pz2session.getShow();\r
+  }\r
+    \r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/exceptions/CustomExceptionHandler.java b/src/main/java/com/indexdata/pz2utils4jsf/exceptions/CustomExceptionHandler.java
new file mode 100644 (file)
index 0000000..048ef05
--- /dev/null
@@ -0,0 +1,49 @@
+package com.indexdata.pz2utils4jsf.exceptions;\r
+\r
+import java.util.Iterator;\r
+\r
+import javax.faces.FacesException;\r
+import javax.faces.application.NavigationHandler;\r
+import javax.faces.application.ViewExpiredException;\r
+import javax.faces.context.ExceptionHandler;\r
+import javax.faces.context.ExceptionHandlerWrapper;\r
+import javax.faces.context.FacesContext;\r
+import javax.faces.event.ExceptionQueuedEvent;\r
+import javax.faces.event.ExceptionQueuedEventContext;\r
+\r
+public class CustomExceptionHandler extends ExceptionHandlerWrapper {\r
+\r
+  private ExceptionHandler wrapped;\r
+  \r
+  public CustomExceptionHandler (ExceptionHandler wrapped) {\r
+    this.wrapped = wrapped;\r
+  }\r
+    \r
+  @Override\r
+  public ExceptionHandler getWrapped() {\r
+    return this.wrapped;\r
+  }\r
+\r
+  @Override\r
+  public void handle() throws FacesException {\r
+    for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {\r
+      ExceptionQueuedEvent event = i.next();\r
+      ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();\r
+      Throwable t = context.getException();\r
+      if (t instanceof ViewExpiredException) {\r
+        // ViewExpiredException vee = (ViewExpiredException) t;\r
+        FacesContext fc = FacesContext.getCurrentInstance();\r
+        // Map<String, Object> requestMap = fc.getExternalContext().getRequestMap();\r
+        NavigationHandler nav = fc.getApplication().getNavigationHandler();\r
+        context.getContext().getPartialViewContext().setRenderAll(true);        \r
+        try {\r
+          nav.handleNavigation(fc, null, "search");\r
+          fc.renderResponse();\r
+        } finally {\r
+          i.remove();\r
+        }\r
+      }\r
+    }\r
+    getWrapped().handle();\r
+  }\r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/exceptions/CustomExceptionHandlerFactory.java b/src/main/java/com/indexdata/pz2utils4jsf/exceptions/CustomExceptionHandlerFactory.java
new file mode 100644 (file)
index 0000000..ee60210
--- /dev/null
@@ -0,0 +1,20 @@
+package com.indexdata.pz2utils4jsf.exceptions;\r
+\r
+import javax.faces.context.ExceptionHandler;\r
+import javax.faces.context.ExceptionHandlerFactory;\r
+\r
+public class CustomExceptionHandlerFactory extends ExceptionHandlerFactory {\r
+\r
+  private ExceptionHandlerFactory parent;\r
+  \r
+  public CustomExceptionHandlerFactory (ExceptionHandlerFactory parent) {\r
+    this.parent = parent;\r
+  }\r
+  @Override\r
+  public ExceptionHandler getExceptionHandler() {\r
+    ExceptionHandler result = parent.getExceptionHandler();\r
+    result = new CustomExceptionHandler(result);\r
+    return result;\r
+  }\r
+\r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/CommandParameter.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/CommandParameter.java
new file mode 100644 (file)
index 0000000..d589160
--- /dev/null
@@ -0,0 +1,124 @@
+package com.indexdata.pz2utils4jsf.pazpar2;\r
+\r
+import java.io.Serializable;\r
+import java.io.UnsupportedEncodingException;\r
+import java.net.URLEncoder;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.apache.log4j.Logger;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.CommandParameter;\r
+import com.indexdata.pz2utils4jsf.pazpar2.Expression;\r
+\r
+public class CommandParameter implements Serializable {\r
+\r
+  private static Logger logger = Logger.getLogger(CommandParameter.class);\r
+  \r
+  private static final long serialVersionUID = 625502285668766749L;\r
+  String name = null;\r
+  String operator = null;\r
+  String value = null;\r
+  Map<String,Expression> expressions = new HashMap<String,Expression>();\r
+  \r
+  public CommandParameter (String name) {\r
+    logger.debug("Instantiating command parameter (1) " + name);\r
+    this.name = name;\r
+  }\r
+  \r
+  public CommandParameter (String name, String operator, String value, Expression... expressions) {\r
+    logger.debug("Instantiating command parameter (2) " + name + " with " + expressions);\r
+    this.name = name;\r
+    this.operator = operator;\r
+    this.value = value;\r
+    for (Expression expr : expressions) {\r
+      this.expressions.put(expr.toString(), expr);\r
+    }\r
+  }\r
+\r
+  public CommandParameter (String name, String operator, String value) {\r
+    logger.debug("Instantiating command parameter (3) " + name + " ("+this+") with " + name + " and " + value);\r
+    this.name = name;\r
+    this.operator = operator;\r
+    this.value = value;    \r
+  }\r
+  \r
+  public CommandParameter (String name, String operator, int value) {\r
+    logger.debug("Instantiating command parameter (4) " + name + " ("+this+") with " + name + " and " + value);\r
+    this.name = name;\r
+    this.operator = operator;\r
+    this.value = value+"";    \r
+  }\r
+\r
+  \r
+  public String getName () {\r
+    return name;\r
+  }\r
+  \r
+  public Map<String,Expression> getExpressions () {\r
+    return expressions;\r
+  }\r
+  \r
+  public void addExpression(Expression expression) {\r
+    logger.debug("Adding expression [" + expression + "] to " + this.getName() + " ("+this+")");\r
+    this.expressions.put(expression.toString(),expression);\r
+  }\r
+  \r
+  public void removeExpression(Expression expression) {\r
+    this.expressions.remove(expression.toString());\r
+  }\r
+  \r
+  \r
+  public boolean hasOperator() {\r
+    return operator != null;\r
+  }\r
+  \r
+  public String getEncodedQueryString () {\r
+    try {\r
+      return name + operator + URLEncoder.encode(getValueWithExpressions(),"UTF-8");\r
+    } catch (UnsupportedEncodingException e) {\r
+      e.printStackTrace();\r
+      return null;\r
+    }\r
+  }\r
+    \r
+  public String getSimpleValue() {    \r
+    return value; \r
+  }\r
+  \r
+  public String getValueWithExpressions () {\r
+    StringBuilder completeValue = new StringBuilder((value==null ? "" : value));    \r
+    for (String key : expressions.keySet()) {      \r
+      completeValue.append(" and " + expressions.get(key));\r
+    }\r
+    return completeValue.toString();\r
+    \r
+  }\r
+  \r
+  @Override\r
+  public boolean equals (Object otherParameter) {\r
+    return\r
+        ((otherParameter instanceof CommandParameter)\r
+         && this.getValueWithExpressions().equals(((CommandParameter) otherParameter).getValueWithExpressions()));\r
+  }\r
+  \r
+  @Override\r
+  public int hashCode () {\r
+    return getValueWithExpressions().hashCode();\r
+  }\r
+  \r
+  public String toString() {\r
+    return getValueWithExpressions();\r
+  }\r
+  \r
+  public CommandParameter copy() {\r
+    CommandParameter newParam = new CommandParameter(name);\r
+    newParam.value = this.value;\r
+    newParam.operator = this.operator;\r
+    for (String key : expressions.keySet()) {\r
+      newParam.addExpression(expressions.get(key).copy());      \r
+    }\r
+    return newParam;\r
+  }\r
+  \r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/CommandThread.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/CommandThread.java
new file mode 100644 (file)
index 0000000..902ccb4
--- /dev/null
@@ -0,0 +1,55 @@
+package com.indexdata.pz2utils4jsf.pazpar2;\r
+\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.IOException;\r
+\r
+import org.apache.log4j.Logger;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.CommandThread;\r
+import com.indexdata.pz2utils4jsf.pazpar2.Pazpar2Command;\r
+import com.indexdata.masterkey.pazpar2.client.ClientCommand;\r
+import com.indexdata.masterkey.pazpar2.client.Pazpar2Client;\r
+import com.indexdata.masterkey.pazpar2.client.exceptions.Pazpar2ErrorException;\r
+\r
+public class CommandThread extends Thread {\r
+\r
+  private static Logger logger = Logger.getLogger(CommandThread.class);\r
+  Pazpar2Command command;\r
+  Pazpar2Client client;\r
+  private ByteArrayOutputStream baos = new ByteArrayOutputStream();\r
+  private StringBuilder response = new StringBuilder("");\r
+  \r
+  public CommandThread (Pazpar2Command command, Pazpar2Client client) {\r
+    this.command = command;\r
+    this.client = client;\r
+  }\r
+  \r
+  public void run() {\r
+    ClientCommand clientCommand = new ClientCommand(command.getName(), command.getEncodedQueryString());\r
+    if (command.getName().equals("search")) {\r
+      client.setSearchCommand(clientCommand);\r
+    }\r
+    try {\r
+      long start = System.currentTimeMillis();\r
+      client.executeCommand(clientCommand, baos);\r
+      response.append(baos.toString("UTF-8"));\r
+      long end = System.currentTimeMillis();      \r
+      logger.debug("Executed " + command.getName() + " in " + (end-start) + " ms." );\r
+    } catch (IOException e) {\r
+      // TODO Auto-generated catch block\r
+      e.printStackTrace();\r
+    } catch (Pazpar2ErrorException e) {\r
+      // TODO Auto-generated catch block\r
+      e.printStackTrace();\r
+    }\r
+  }\r
+  \r
+  public String getResponse () {\r
+    return response.toString();\r
+  }\r
+  \r
+  public Pazpar2Command getCommand() {\r
+    return command;\r
+  }\r
+\r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Expression.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Expression.java
new file mode 100644 (file)
index 0000000..3b5260a
--- /dev/null
@@ -0,0 +1,25 @@
+package com.indexdata.pz2utils4jsf.pazpar2;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.Expression;\r
+\r
+public class Expression {\r
+  \r
+  String leftEntity;\r
+  String operator;\r
+  String rightEntity;\r
+  public Expression (String leftEntity, String operator, String rightEntity) {\r
+    this.leftEntity = leftEntity;\r
+    this.operator = operator;\r
+    this.rightEntity = rightEntity;    \r
+  }\r
+  \r
+  public Expression copy() {\r
+    return new Expression(leftEntity,operator,rightEntity);\r
+  }\r
+  \r
+  public String toString() {\r
+    return leftEntity + operator + rightEntity;\r
+  }\r
+  \r
+\r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Pazpar2Command.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Pazpar2Command.java
new file mode 100644 (file)
index 0000000..9d30f64
--- /dev/null
@@ -0,0 +1,93 @@
+package com.indexdata.pz2utils4jsf.pazpar2;\r
+\r
+import java.io.Serializable;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.apache.log4j.Logger;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.CommandParameter;\r
+import com.indexdata.pz2utils4jsf.pazpar2.Pazpar2Command;\r
+\r
+public class Pazpar2Command implements Serializable  {\r
+\r
+  private static Logger logger = Logger.getLogger(Pazpar2Command.class);\r
+  private static final long serialVersionUID = -6825491856480675917L;\r
+  public static List<String> allCommands = new ArrayList<String>(Arrays.asList("init","ping","settings","search","stat","show","record","termlist","bytarget"));\r
+\r
+  private String name = "";\r
+  private Map<String,CommandParameter> parameters = new HashMap<String,CommandParameter>();\r
+  \r
+  public Pazpar2Command (String name) {    \r
+    this.name = name;\r
+  }\r
+  \r
+  public Pazpar2Command copy () {\r
+    Pazpar2Command newCommand = new Pazpar2Command(name);\r
+    for (String parameterName : parameters.keySet()) {\r
+      newCommand.setParameter(parameters.get(parameterName).copy());      \r
+    }\r
+    return newCommand;\r
+  }\r
+  \r
+  public String getName() {\r
+    return name;\r
+  }\r
+    \r
+  public void setParameter (CommandParameter parameter) {\r
+    logger.debug("Setting parameter " + parameter.getName() + "=" + parameter.getValueWithExpressions() + " to " + this.getName());\r
+    parameters.put(parameter.getName(),parameter);\r
+  }\r
+  \r
+  public CommandParameter getParameter (String name) {\r
+    return parameters.get(name);\r
+  }\r
+  \r
+  public void removeParameter (String name) {\r
+    parameters.remove(name);    \r
+  }\r
+  \r
+  public void removeParameters() {\r
+    parameters = new HashMap<String,CommandParameter>();\r
+  }\r
+  \r
+  public boolean hasParameters () {\r
+    return (parameters.keySet().size()>0);\r
+  }\r
+  \r
+  public String getEncodedQueryString () {\r
+    StringBuilder queryString = new StringBuilder("command="+name);\r
+    for (CommandParameter parameter : parameters.values()) {\r
+       queryString.append("&"+parameter.getEncodedQueryString());       \r
+    }\r
+    return queryString.toString();\r
+  } \r
+    \r
+  public String getValueWithExpressions() {    \r
+    StringBuilder value = new StringBuilder("");\r
+    for (CommandParameter parameter : parameters.values()) {\r
+      value.append("&" + parameter.getName() + parameter.operator + parameter.getValueWithExpressions());       \r
+   }\r
+    return value.toString();\r
+  }\r
+  \r
+  @Override\r
+  public boolean equals (Object otherCommand) {\r
+    return\r
+        ((otherCommand instanceof Pazpar2Command)\r
+         && this.getValueWithExpressions().equals(((Pazpar2Command) otherCommand).getValueWithExpressions()));\r
+  }\r
+  \r
+  @Override\r
+  public int hashCode () {\r
+    return getValueWithExpressions().hashCode();\r
+  }\r
+  \r
+  public String toString () {\r
+    return parameters.toString();\r
+  }\r
+  \r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Pz2Bean.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Pz2Bean.java
new file mode 100644 (file)
index 0000000..73042fb
--- /dev/null
@@ -0,0 +1,261 @@
+package com.indexdata.pz2utils4jsf.pazpar2;\r
+\r
+import java.io.Serializable;\r
+import java.util.List;\r
+\r
+import javax.enterprise.context.SessionScoped;\r
+import javax.inject.Named;\r
+\r
+import com.indexdata.pz2utils4jsf.controls.ResultsPager;\r
+import com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface;\r
+import com.indexdata.pz2utils4jsf.pazpar2.Pz2Session;\r
+import com.indexdata.pz2utils4jsf.pazpar2.TargetFilter;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.ByTarget;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.RecordResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.ShowResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.StatResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.TermListsResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.TermResponse;\r
+\r
+@Named("pz2")\r
+@SessionScoped\r
+public class Pz2Bean implements Pz2Interface, Serializable {\r
+\r
+  private static final long serialVersionUID = 3440277287081557861L;\r
+  Pz2Session pz2;\r
+  \r
+  public Pz2Bean () {\r
+    pz2 = new Pz2Session();    \r
+  }\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#doSearch(java.lang.String)\r
+   */\r
+  public void doSearch(String query) {\r
+    pz2.doSearch(query);\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#doSearch()\r
+   */\r
+  public void doSearch() {\r
+    pz2.doSearch();\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#update()\r
+   */\r
+  public String update() {\r
+    return pz2.update();\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#update(java.lang.String)\r
+   */\r
+  public String update(String commands) {\r
+    return pz2.update(commands);\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#setQuery(java.lang.String)\r
+   */\r
+  public void setQuery(String query) {\r
+    pz2.setQuery(query);\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#getQuery()\r
+   */\r
+  public String getQuery() {\r
+    return pz2.getQuery();\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#setFacet(java.lang.String, java.lang.String)\r
+   */\r
+  public void setFacet(String facetKey, String term) {\r
+    pz2.setFacet(facetKey, term);\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#removeFacet(java.lang.String, java.lang.String)\r
+   */\r
+  public void removeFacet(String facetKey, String term) {\r
+    pz2.removeFacet(facetKey, term);\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#setFacetOnQuery(java.lang.String, java.lang.String)\r
+   */\r
+  public void setFacetOnQuery(String facetKey, String term) {\r
+    pz2.setFacetOnQuery(facetKey, term);\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#setTargetFilter(java.lang.String, java.lang.String)\r
+   */\r
+  public void setTargetFilter(String targetId, String targetName) {\r
+    pz2.setTargetFilter(targetId, targetName);\r
+  }\r
+  \r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#removeTargetFilter()\r
+   */\r
+  public void removeTargetFilter () {\r
+    pz2.removeTargetFilter();\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#getTargetFilter()\r
+   */\r
+  public TargetFilter getTargetFilter() {\r
+    return pz2.getTargetFilter();\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#hasTargetFilter()\r
+   */\r
+  public boolean hasTargetFilter() {\r
+    return pz2.hasTargetFilter();\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#setSort(java.lang.String)\r
+   */\r
+  public void setSort(String sortOption) {\r
+    pz2.setSort(sortOption);\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#getSort()\r
+   */\r
+  public String getSort() {\r
+    return pz2.getSort();\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#setPageSize(int)\r
+   */\r
+  public void setPageSize(int perPageOption) {\r
+    pz2.setPageSize(perPageOption);\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#getPageSize()\r
+   */\r
+  public int getPageSize() {\r
+    return pz2.getPageSize();\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#setStart(int)\r
+   */\r
+  public void setStart(int start) {\r
+    pz2.setStart(start);\r
+  }\r
+  \r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#getStart()\r
+   */\r
+  public int getStart() {\r
+    return pz2.getStart();\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#toggleRecord(java.lang.String)\r
+   */\r
+  public String toggleRecord(String recid) {\r
+    return pz2.toggleRecord(recid);\r
+  }\r
+  \r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#getShow()\r
+   */\r
+  public ShowResponse getShow() {\r
+    return pz2.getShow();\r
+  }\r
+  \r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#getStat()\r
+   */\r
+  public StatResponse getStat() {\r
+    return pz2.getStat();\r
+  }\r
+    \r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#hasRecord(java.lang.String)\r
+   */\r
+  public boolean hasRecord(String recId) {    \r
+    return pz2.hasRecord(recId);\r
+  }\r
+  \r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#getRecord()\r
+   */\r
+  public RecordResponse getRecord() {\r
+    return pz2.getRecord();\r
+  }\r
+  \r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#getTermLists()\r
+   */\r
+  public TermListsResponse getTermLists() {\r
+    return pz2.getTermLists();\r
+  }\r
+  \r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#getFacetTerms(java.lang.String, int)\r
+   */\r
+  public List<TermResponse> getFacetTerms(String facet, int count) {\r
+    return pz2.getFacetTerms(facet, count);\r
+  }\r
+  \r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#getFacetTerms(java.lang.String)\r
+   */\r
+  public List<TermResponse> getFacetTerms(String facet) {  \r
+    return pz2.getFacetTerms(facet);\r
+  }  \r
+  \r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#getByTarget()\r
+   */\r
+  public ByTarget getByTarget() {  \r
+    return pz2.getByTarget();\r
+  }\r
+  \r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#hasRecords()\r
+   */\r
+  public boolean hasRecords() {\r
+    return pz2.hasRecords();\r
+  }\r
+  \r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#setPager(int)\r
+   */\r
+  public ResultsPager setPager(int pageRange) {\r
+    return pz2.setPager(pageRange);\r
+  }\r
+\r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#getPager()\r
+   */\r
+  public ResultsPager getPager() {\r
+    return pz2.getPager();\r
+  }\r
+  \r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#getCurrentStateKey()\r
+   */\r
+  public String getCurrentStateKey() {\r
+    return pz2.getCurrentStateKey();\r
+  }\r
+    \r
+  /* (non-Javadoc)\r
+   * @see com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface#setCurrentStateKey(java.lang.String)\r
+   */\r
+  public void setCurrentStateKey(String key) {\r
+    pz2.setCurrentStateKey(key);    \r
+  }\r
+\r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Pz2Interface.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Pz2Interface.java
new file mode 100644 (file)
index 0000000..6aa1921
--- /dev/null
@@ -0,0 +1,300 @@
+package com.indexdata.pz2utils4jsf.pazpar2;\r
+\r
+import java.util.List;\r
+\r
+import com.indexdata.pz2utils4jsf.controls.ResultsPager;\r
+import com.indexdata.pz2utils4jsf.pazpar2.TargetFilter;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.ByTarget;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.RecordResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.ShowResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.StatResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.TermListsResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.TermResponse;\r
+\r
+public interface Pz2Interface {\r
+\r
+  /**\r
+   * Executes a Pazpar2 search using the given query string\r
+   * \r
+   * @param query\r
+   */\r
+  public void doSearch(String query);\r
+  \r
+  /**\r
+   * Executes a Pazpar2 search using the current query \r
+   */\r
+  public void doSearch();\r
+  \r
+  /**\r
+   * Updates display data objects by issuing the following pazpar2 commands: \r
+   * 'show', 'stat', 'termlist' and 'bytarget'.\r
+   *  \r
+   * Returns a count of the remaining active clients from the most recent search.\r
+   * \r
+   * After refreshing the data from pazpar2 the UI components displaying those \r
+   * data should be re-rendered.\r
+   * \r
+   * @return count of activeclients \r
+   */\r
+  public String update();\r
+  \r
+  /**\r
+   * Updates the data objects given by a comma separated list of one or more commands - \r
+   * i.e. "show,state,termlist,bytarget".\r
+   *  \r
+   * May not be useful for the UI directly. \r
+   *  \r
+   * @param commands Command separated list of pazpar2 commands.\r
+   * @return count of activeclients \r
+   * \r
+   */\r
+  public String update (String commands);\r
+  \r
+  /**\r
+   * Sets a query to used by the next search command\r
+   * \r
+   * @param query a query on pazpar2 query syntax\r
+   * \r
+   */\r
+  public void setQuery (String query);\r
+  \r
+  /**\r
+   * Gets the current query  \r
+   * @return a pazpar2 query string\r
+   */\r
+  public String getQuery ();\r
+  \r
+  /**\r
+   * Sets a facet to limit the current query by,\r
+   * then executes the search \r
+   * \r
+   * @param facetKey  i.e.  'au' for author\r
+   * @param term  i.e. 'Dickens, Charles'\r
+   */\r
+  public void setFacet(String facetKey, String term);\r
+  \r
+  /**\r
+   * Removes a facet set by setFacet(...), then executes\r
+   * the search.\r
+   * \r
+   * Will not remove facets set by setFacetOnQuery(...)\r
+   *  \r
+   * @param facetKey i.e. 'au' for author\r
+   * @param term i.e. 'Dickens, Charles'\r
+   */\r
+  public void removeFacet (String facetKey, String term);\r
+  \r
+  /**\r
+   * Sets a facet to limit the current query by. The \r
+   * facet is appended to the query string itself (rather\r
+   * as a separately managed entity. It will thus appear\r
+   * in a query field as retrieved by getQuery(). It will\r
+   * not be removed by removeFacet(...)\r
+   * \r
+   * @param facetKey  i.e. 'au' for author\r
+   * @param term i.e. 'Dickens, Charles'\r
+   */\r
+  public void setFacetOnQuery(String facetKey, String term);\r
+  \r
+  /**\r
+   * Adds a target filter to limit the current query by, then\r
+   * executes the current search.\r
+   * \r
+   * @param targetId pazpar2's ID for the target to limit by\r
+   * @param targetName a descriptive name for the target\r
+   */\r
+  public void setTargetFilter (String targetId, String targetName);\r
+  \r
+  /**\r
+   * Removes the current target filter from the search\r
+   * \r
+   */\r
+  public void removeTargetFilter ();\r
+  \r
+  /**\r
+   * \r
+   * @return The target filter set on the current search command\r
+   */\r
+  public TargetFilter getTargetFilter();\r
+  \r
+  /**\r
+   * Resolves if the current search command has a target filter - to\r
+   * be used by the UI for conditional rendering of target filter info.\r
+   * \r
+   * @return true if the current search command is limited by a target \r
+   * filter\r
+   */\r
+  public boolean hasTargetFilter();\r
+  \r
+  /**\r
+   * Sets the ordering of records (hits) in the 'show' display object\r
+   */\r
+  \r
+  /**\r
+   * Sets the sort order for results, the updates the 'show' data object\r
+   * from pazpar2. Set valid sort options in the documentation for pazpar2.\r
+   * \r
+   * The parts of the UI that display 'show' data should be rendered following\r
+   * this request.\r
+   * \r
+   * @param sortOption\r
+   */\r
+  public void setSort(String sortOption);\r
+  \r
+  /**\r
+   * Retrieves the current sort order for results\r
+   * @return sort order - i.e. 'relevance'\r
+   */\r
+  public String getSort();\r
+  \r
+  /**\r
+   * Sets the number of records that pazpar2 should show at a time. Is \r
+   * followed by an update of the show data object from pazpar2.  \r
+   * \r
+   * To be used by the UI for paging. After setting page size the parts\r
+   * of the UI that displays 'show' data should be rendered. \r
+   * \r
+   * @param perPageOption i.e. 10, default is 20.\r
+   */\r
+  public void setPageSize (int perPageOption);\r
+  \r
+  /**\r
+   * Retrieves the currently defined number of items to show at a time\r
+   * \r
+   * @return number of result records that will be shown from pazpar2\r
+   */\r
+  public int getPageSize();\r
+  \r
+  /**\r
+   * Sets the first record to show - starting at record '0'. After setting\r
+   * first record number, the 'show' data object will be updated from pazpar2,\r
+   * and the parts of the UI displaying show data should be re-rendered.\r
+   * \r
+   * To be used by the UI for paging.\r
+   * \r
+   * @param start first record to show\r
+   */\r
+  public void setStart (int start);\r
+  \r
+  /**\r
+   * Retrieves the sequence number of the record that pazpaz2 will return as\r
+   * the first record in 'show'\r
+   * \r
+   * @return sequence number of the first record to be shown (numbering starting at '0')\r
+   * \r
+   */\r
+  public int getStart();\r
+  \r
+  /**\r
+   * Will retrieve or remove the record with the given recid from memory.\r
+   * \r
+   * A pazpar2 'record' command will then be issued. The part of the UI \r
+   * showing record data should thus be re-rendered.\r
+   *  \r
+   * @param recid\r
+   * @return\r
+   */\r
+  public String toggleRecord(String recid);\r
+    \r
+  /**\r
+   * Returns the 'show' data as retrieved from pazpar2 by the most \r
+   * recent update request\r
+   * \r
+   * @return pazpar2 'show' response object\r
+   */\r
+  public ShowResponse getShow();\r
+  \r
+  /**\r
+   * Returns the 'stat' data as retrieved from pazpar2 by the most \r
+   * recent update request\r
+   * \r
+   * @return pazpar2 'stat' response object\r
+   */\r
+  public StatResponse getStat();\r
+  \r
+  /**\r
+   * Resolves whether the backend has a record with the given recid in memory \r
+   * \r
+   * @return true if the bean currently holds the record with recid\r
+   */  \r
+  public boolean hasRecord (String recId);\r
+  \r
+  /**\r
+   * Resolves whether the back-end has any records in memory (in 'show') for \r
+   * display in UI\r
+   * \r
+   * @return true if there are records to display\r
+   */\r
+  public boolean hasRecords ();\r
+        \r
+  /**\r
+   * Returns a pazpar2 record as retrieved by the most recent 'record'\r
+   * request \r
+   * @return record data object\r
+   */\r
+  public RecordResponse getRecord();\r
+  \r
+  /**\r
+   * Returns a set of term lists (targets and facets) as retrieved by the \r
+   * most recent 'termlist' command \r
+   * @return set of termlists\r
+   */\r
+  public TermListsResponse getTermLists ();\r
+  \r
+  /**\r
+   * Returns up to 'count' terms from the facet given by the 'facet' parameter\r
+   * @param facet  name of the facet\r
+   * @param count  maximum number of facet terms to return\r
+   * @return facet term list limited to 'count' terms\r
+   */\r
+  public List<TermResponse> getFacetTerms (String facet, int count);\r
+    \r
+  /**\r
+   * Returns all the terms of a given facet - or as many as pazpar2 returns\r
+   * @param facet name of the facet\r
+   * @return facet term list\r
+   */\r
+  public List<TermResponse> getFacetTerms (String facet);\r
+  \r
+  /**\r
+   * Returns a ByTarget data object as retrieved by the most recent 'bytarget' \r
+   * request to pazpar2\r
+   * \r
+   * @return ByTarget response data object\r
+   */\r
+  public ByTarget getByTarget();\r
+    \r
+  /**\r
+   * Initiates a pager object, a component holding the data to draw a sequence\r
+   * of page numbers to navigate by and mechanisms to navigate with\r
+   * \r
+   * @param pageRange number of pages to display in the pager\r
+   * @return ResultsPager the initiated pager component\r
+   */\r
+  public ResultsPager setPager(int pageRange);\r
+  \r
+  /**\r
+   * Gives a component for drawing a pager to navigate by.\r
+   * @return ResultsPager pager component\r
+   */\r
+  public ResultsPager getPager();\r
+  \r
+  /**\r
+   * Returns the current hash key used, as used for internal session state tracking\r
+   * and potentially for browser history entries as well\r
+   * \r
+   * A UI author would not normally be concerned with retrieving this. It's used by the\r
+   * framework internally\r
+   *  \r
+   * @return string that can be used for browsers window.location.hash\r
+   */\r
+  public String getCurrentStateKey ();\r
+      \r
+  /**\r
+   * Sets the current state key, i.e. when user clicks back or forward in browser history.\r
+   * Would normally be automatically handled by the frameworks components.\r
+   *  \r
+   * @param key corresponding to browsers hash string\r
+   */\r
+  public void setCurrentStateKey(String key);\r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Pz2Session.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Pz2Session.java
new file mode 100644 (file)
index 0000000..0d8cc3f
--- /dev/null
@@ -0,0 +1,387 @@
+package com.indexdata.pz2utils4jsf.pazpar2;\r
+\r
+import java.io.Serializable;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.StringTokenizer;\r
+import java.util.concurrent.ConcurrentHashMap;\r
+\r
+import org.apache.log4j.Logger;\r
+\r
+import com.indexdata.pz2utils4jsf.controls.ResultsPager;\r
+import com.indexdata.pz2utils4jsf.pazpar2.CommandParameter;\r
+import com.indexdata.pz2utils4jsf.pazpar2.CommandThread;\r
+import com.indexdata.pz2utils4jsf.pazpar2.Expression;\r
+import com.indexdata.pz2utils4jsf.pazpar2.Pazpar2Command;\r
+import com.indexdata.pz2utils4jsf.pazpar2.Pz2Interface;\r
+import com.indexdata.pz2utils4jsf.pazpar2.Pz2Session;\r
+import com.indexdata.pz2utils4jsf.pazpar2.TargetFilter;\r
+import com.indexdata.masterkey.pazpar2.client.Pazpar2Client;\r
+import com.indexdata.masterkey.pazpar2.client.Pazpar2ClientConfiguration;\r
+import com.indexdata.masterkey.pazpar2.client.Pazpar2ClientGeneric;\r
+import com.indexdata.masterkey.pazpar2.client.exceptions.ProxyErrorException;\r
+import com.indexdata.pz2utils4jsf.config.JsfdemoPazpar2ClientConfiguration;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.ByTarget;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseData;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseParser;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.RecordResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.ShowResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.StatResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.TermListsResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.TermResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.state.QueryStates;\r
+\r
+public class Pz2Session implements Serializable, Pz2Interface {\r
+  \r
+  private static Logger logger = Logger.getLogger(Pz2Session.class);\r
+  \r
+  private Map<String,Pazpar2ResponseData> dataObjects = new ConcurrentHashMap<String,Pazpar2ResponseData>();\r
+  private QueryStates queryStates = new QueryStates();\r
+  \r
+  private static final long serialVersionUID = 3947514708343320514L;  \r
+  private Pazpar2ClientConfiguration cfg = null;\r
+  private Pazpar2Client client = null;   \r
+  private TargetFilter targetFilter = null;  \r
+  private ResultsPager pager = null; \r
+\r
+  public Pz2Session () {\r
+    logger.debug("Instantiating pz2");    \r
+    try {\r
+      cfg = new Pazpar2ClientConfiguration(new JsfdemoPazpar2ClientConfiguration().getModuleConfiguration());\r
+      client = new Pazpar2ClientGeneric(cfg);\r
+      resetDataObjects();\r
+    } catch (ProxyErrorException e) {\r
+      e.printStackTrace();\r
+    }    \r
+  }\r
+\r
+  public void doSearch(String query) {\r
+    setCommandParameter("search",new CommandParameter("query","=",query));     \r
+    doSearch();\r
+  }\r
+\r
+  public void doSearch() { \r
+    queryStates.hasPendingStateChange("search",false);\r
+    resetDataObjects();\r
+    setCommandParameter("show",new CommandParameter("start","=",0));    \r
+    logger.info("Searching using "+getCommand("search").getParameter("query").getEncodedQueryString());\r
+    doCommand("search");    \r
+  }\r
+      \r
+  /**\r
+   * Refreshes 'show', 'stat', 'termlist', and 'bytarget' data object from pazpar2\r
+   * \r
+   * @return Number of activeclients at the time of the 'show' command.\r
+   */\r
+  public String update () {\r
+    logger.info("Updating show,stat,termlist, and bytarget data from pazpar2");\r
+    return update("show,stat,termlist,bytarget");\r
+  }\r
\r
+  /**\r
+   * Refreshes the data objects listed in 'commands' from pazpar2\r
+   * \r
+   * @param commands\r
+   * @return Number of activeclients at the time of the 'show' command\r
+   */\r
+  public String update (String commands) {\r
+    if (hasQuery()) {\r
+      handleQueryStateChanges(commands);\r
+      logger.debug("Processing request for " + commands); \r
+      List<CommandThread> threadList = new ArrayList<CommandThread>();\r
+      StringTokenizer tokens = new StringTokenizer(commands,",");\r
+      while (tokens.hasMoreElements()) {\r
+        threadList.add(new CommandThread(getCommand(tokens.nextToken()),client));            \r
+      }\r
+      for (CommandThread thread : threadList) {\r
+        thread.start();\r
+      }\r
+      for (CommandThread thread : threadList) {\r
+        try {\r
+          thread.join();\r
+        } catch (InterruptedException e) {\r
+          e.printStackTrace();\r
+        }\r
+      }\r
+      for (CommandThread thread : threadList) {\r
+        if (!thread.getCommand().getName().equals("search")) {\r
+          dataObjects.put(thread.getCommand().getName(), new Pazpar2ResponseParser().getObject(thread.getResponse()));\r
+        }\r
+      }\r
+      return getActiveClients();\r
+    } else {\r
+      logger.info("Skipped requests for " + commands + " as there's not yet a query."); \r
+      resetDataObjects();\r
+      return "0";\r
+    }\r
+    \r
+  }\r
+        \r
+  public void setQuery (String query) {\r
+    logger.debug("Creating new command parameter for " + query);\r
+    setCommandParameter("search",new CommandParameter("query","=",query));\r
+  }\r
+  \r
+  public String getQuery () {\r
+    return getCommandParameterValueSimple("search","query",null);\r
+  }\r
+  \r
+  public void setFacet (String facetKey, String term) {           \r
+    if (term != null && term.length()>0) {\r
+      queryStates.getCurrentState().setCommandParameterExpression("search","query",new Expression(facetKey,"=",term),queryStates);\r
+      doSearch();\r
+    }            \r
+  }\r
+  \r
+  public void setFacetOnQuery (String facetKey, String term) {\r
+    String facetExpression = facetKey + "=" + term;    \r
+    if (term != null && term.length()>0) {\r
+      setCommandParameter("search",new CommandParameter("query","=", getQuery() + " and " + facetExpression));\r
+      doSearch();        \r
+    }            \r
+  }\r
+      \r
+  public void removeFacet(String facetKey, String term) {\r
+    queryStates.getCurrentState().removeCommandParameterExpression("search","query",new Expression(facetKey,"=",term),queryStates);\r
+    doSearch();\r
+  }\r
+  \r
+  public void setTargetFilter (String targetId, String targetName) {    \r
+    if (hasTargetFilter(new TargetFilter(targetId,targetName))) {\r
+      logger.debug("Already using target filter " + this.targetFilter.getFilterExpression());\r
+    } else {      \r
+      this.targetFilter = new TargetFilter(targetId,targetName);\r
+      setCommandParameter("search",new CommandParameter("filter","=",this.targetFilter.getFilterExpression()));      \r
+      doSearch();\r
+    }    \r
+  }\r
+\r
+  public TargetFilter getTargetFilter () {\r
+    return targetFilter;\r
+  }\r
+    \r
+  public void removeTargetFilter () {\r
+    logger.debug("Removing target filter " + targetFilter.getFilterExpression());\r
+    this.targetFilter = null;\r
+    removeCommandParameter("search","filter");         \r
+    doSearch();\r
+  }\r
+  \r
+  public boolean hasTargetFilter() {\r
+    return targetFilter != null;    \r
+  }\r
+        \r
+  public void setSort (String sortOption) {\r
+    logger.debug("Setting sort option: " + sortOption);\r
+    setCommandParameter("show",new CommandParameter("sort","=",sortOption));\r
+    update("show");\r
+  }\r
+  \r
+  public String getSort () {\r
+    return getCommandParameterValue("show","sort","relevance");\r
+  }\r
+    \r
+  public void setPageSize (int perPageOption) {\r
+    if (getPageSize()!=perPageOption) {\r
+     logger.debug("Setting perpage option to " + perPageOption + " and resetting start page.");\r
+     setCommandParameter("show",new CommandParameter("num","=",perPageOption));\r
+     setCommandParameter("show",new CommandParameter("start","=",0));\r
+     update("show");\r
+    } else {\r
+      logger.debug("Not updating page size, already is " + perPageOption);\r
+    }\r
+  }\r
+  \r
+  public int getPageSize () {\r
+    return getCommandParameterValue("show","num",20);\r
+  }\r
+  \r
+  public void setStart (int start) {\r
+    logger.debug("Setting start num to " + start);\r
+    setCommandParameter("show", new CommandParameter("start","=",start));  \r
+    update("show");\r
+  }\r
+  \r
+  public int getStart() {\r
+    return getCommandParameterValue("show","start",0);\r
+  }\r
+        \r
+  public String toggleRecord (String recId) {\r
+    if (hasRecord(recId)) {\r
+      removeCommand("record");  \r
+      dataObjects.put("record", new RecordResponse());\r
+      return "";\r
+    } else {\r
+      return updateRecord(recId);\r
+    }\r
+  }\r
+  \r
+  private String updateRecord(String recId) {    \r
+    setCommandParameter("record",new CommandParameter("id","=",recId));    \r
+    return doCommand("record");    \r
+  }\r
+  \r
+  public boolean hasRecord (String recId) {\r
+    return getCommand("record").hasParameters() && getRecord().getRecId().equals(recId);\r
+  }\r
+      \r
+  public ShowResponse getShow () {\r
+    return ((ShowResponse) dataObjects.get("show"));\r
+  }\r
+  \r
+  public StatResponse getStat () {\r
+    return ((StatResponse) dataObjects.get("stat"));\r
+  }\r
+  \r
+  public RecordResponse getRecord() {\r
+    return ((RecordResponse) dataObjects.get("record"));\r
+  }\r
+  \r
+  public TermListsResponse getTermLists () {\r
+    return ((TermListsResponse) dataObjects.get("termlist"));\r
+  }\r
+  \r
+  public List<TermResponse> getFacetTerms (String facet, int count) {\r
+    return (getTermLists().getTermList(facet).getTerms(count));\r
+  }\r
+    \r
+  public List<TermResponse> getFacetTerms (String facet) {\r
+    return (getTermLists().getTermList(facet).getTerms());\r
+  }\r
+  \r
+  public ByTarget getByTarget() {\r
+    return ((ByTarget) dataObjects.get("bytarget"));\r
+  }\r
+  \r
+  \r
+  public String getCurrentStateKey () {    \r
+    return queryStates.getCurrentStateKey();\r
+  }\r
+      \r
+  public void setCurrentStateKey(String key) {\r
+    logger.debug("************** request to set state key to: [" + key + "]");    \r
+    queryStates.setCurrentStateKey(key);\r
+  }\r
+    \r
+  private boolean hasTargetFilter(TargetFilter targetFilter) {\r
+    return hasTargetFilter() && targetFilter.equals(this.targetFilter);\r
+  }\r
+  \r
+  private boolean hasQuery() {\r
+    return !(getCommand("search").getParameter("query") == null);\r
+  }\r
+    \r
+  public boolean hasRecords () {\r
+    return getStat().getRecords() > 0            \r
+           && getShow().getHits() != null \r
+           && getShow().getHits().size()>0;\r
+  }\r
+    \r
+  public ResultsPager getPager () {\r
+    if (pager == null) {\r
+      pager = new ResultsPager(this);      \r
+    } \r
+    return pager;      \r
+  }\r
+  \r
+  public ResultsPager setPager (int pageRange) {\r
+    pager =  new ResultsPager(this,pageRange);\r
+    return pager;\r
+  }\r
+  \r
+  private void handleQueryStateChanges (String commands) {\r
+    if (queryStates.hasPendingStateChange("search")) { \r
+      logger.debug("Found pending search change. Doing search before updating " + commands);\r
+      doSearch();\r
+    } \r
+    if (queryStates.hasPendingStateChange("record") && ! commands.equals("record")) {        \r
+      logger.debug("Found pending record ID change. Doing record before updating " + commands);\r
+      queryStates.hasPendingStateChange("record",false);\r
+      if (getCommand("record").hasParameters()) {\r
+        updateRecord(getCommand("record").getParameter("id").getSimpleValue());\r
+      } else {\r
+        removeCommand("record");  \r
+        dataObjects.put("record", new RecordResponse());\r
+      }\r
+    }    \r
+  }\r
+\r
+  private String getActiveClients() {\r
+    logger.debug("Active clients: "+getShow().getActiveClients());\r
+    if (getShow()!=null) {\r
+      return getShow().getActiveClients();\r
+    } else {\r
+      return "";\r
+    }\r
+  }\r
+\r
+  private Pazpar2Command getCommand(String name) {\r
+    return queryStates.getCurrentState().getCommand(name);\r
+  }\r
+  \r
+  private void setCommandParameter(String commandName, CommandParameter parameter) {\r
+    logger.debug("Setting parameter for " + commandName + ": " + parameter);\r
+    queryStates.getCurrentState().setCommandParameter(commandName, parameter, queryStates);    \r
+  }\r
+  \r
+  \r
+  private void removeCommandParameter(String commandName, String parameterName) {\r
+    queryStates.getCurrentState().removeCommandParameter(commandName,parameterName,queryStates);    \r
+  }\r
+  \r
+  private void removeCommand (String commandName) {\r
+    queryStates.getCurrentState().removeCommand(commandName, queryStates);\r
+  }\r
+    \r
+  private String getCommandParameterValue (String commandName, String parameterName, String defaultValue) {    \r
+    Pazpar2Command command = getCommand(commandName);\r
+    if (command != null) {\r
+      CommandParameter parameter = command.getParameter(parameterName);\r
+      if (parameter != null) {\r
+        return parameter.getValueWithExpressions();\r
+      }\r
+    }\r
+    return defaultValue;    \r
+  }\r
+  \r
+  private String getCommandParameterValueSimple (String commandName, String parameterName, String defaultValue) {    \r
+    Pazpar2Command command = getCommand(commandName);\r
+    if (command != null) {\r
+      CommandParameter parameter = command.getParameter(parameterName);\r
+      if (parameter != null) {\r
+        return parameter.getSimpleValue();\r
+      }\r
+    }\r
+    return defaultValue;    \r
+  }\r
+\r
+  \r
+  private int getCommandParameterValue (String commandName, String parameterName, int defaultValue) {\r
+    Pazpar2Command command = getCommand(commandName);\r
+    if (command != null) {\r
+      CommandParameter parameter = command.getParameter(parameterName);\r
+      if (parameter != null) {\r
+        return Integer.parseInt(parameter.getSimpleValue());\r
+      }\r
+    }\r
+    return defaultValue;    \r
+  }\r
+\r
+  private String doCommand(String commandName) {\r
+    Pazpar2Command command = getCommand(commandName);    \r
+    logger.debug(command.getEncodedQueryString() + ": Results for "+ getCommand("search").getEncodedQueryString());\r
+    return update(commandName);\r
+  }\r
+  \r
+  private void resetDataObjects() {\r
+    logger.debug("Resetting show,stat,termlist,bytarget response objects.");\r
+    dataObjects = new ConcurrentHashMap<String,Pazpar2ResponseData>();\r
+    dataObjects.put("show", new ShowResponse());\r
+    dataObjects.put("stat", new StatResponse());\r
+    dataObjects.put("termlist", new TermListsResponse());\r
+    dataObjects.put("bytarget", new ByTarget());\r
+    dataObjects.put("record", new RecordResponse());\r
+  }\r
+\r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/TargetFilter.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/TargetFilter.java
new file mode 100644 (file)
index 0000000..f4d117c
--- /dev/null
@@ -0,0 +1,47 @@
+package com.indexdata.pz2utils4jsf.pazpar2;\r
+\r
+import java.io.Serializable;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.TargetFilter;\r
+\r
+public class TargetFilter implements Serializable {\r
+\r
+  private static final long serialVersionUID = 2389085467202526537L;\r
+\r
+  private String targetName;\r
+  private String targetId;\r
+  \r
+  public TargetFilter (String targetId, String targetName) {\r
+    this.targetId = targetId;\r
+    this.targetName = targetName;\r
+  }\r
+  \r
+  public String getTargetName () {\r
+    return targetName;\r
+  }\r
+  \r
+  public String getTargetId () {\r
+    return targetId;    \r
+  }\r
+  \r
+  public String getFilterExpression () {\r
+    return "pz:id="+targetId;\r
+  }\r
+  \r
+  @Override\r
+  public boolean equals(Object o) {\r
+    if (o instanceof TargetFilter) {\r
+      return targetName.equals(((TargetFilter) o).getTargetName()) && \r
+             targetId.equals(((TargetFilter) o).getTargetId());\r
+    } else {\r
+      return false;\r
+    }\r
+  }\r
+  \r
+  @Override\r
+  public int hashCode () {\r
+    return (targetId+targetName).hashCode();\r
+  }\r
+  \r
+  \r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/ByTarget.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/ByTarget.java
new file mode 100644 (file)
index 0000000..39ccac0
--- /dev/null
@@ -0,0 +1,22 @@
+package com.indexdata.pz2utils4jsf.pazpar2.data;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseData;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Target;\r
+\r
+public class ByTarget extends Pazpar2ResponseData {\r
+\r
+  private static final long serialVersionUID = 3960644950805644518L;\r
+  \r
+  public List<Target> getTargets() {\r
+    List<Target> targets = new ArrayList<Target>();\r
+    if (getElements("target") != null) {\r
+      for (Pazpar2ResponseData element : getElements("target")) {\r
+        targets.add((Target)element);\r
+      }\r
+    }\r
+    return targets;\r
+  }\r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Hit.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Hit.java
new file mode 100644 (file)
index 0000000..6c2504e
--- /dev/null
@@ -0,0 +1,47 @@
+package com.indexdata.pz2utils4jsf.pazpar2.data;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Location;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseData;\r
+\r
+public class Hit extends Pazpar2ResponseData {\r
+\r
+  \r
+  private static final long serialVersionUID = 9039281987691623220L;\r
+\r
+  public List<Location> getLocations() {\r
+    List<Location> locations = new ArrayList<Location>();\r
+    for (Pazpar2ResponseData element : getElements("location")) {\r
+      locations.add((Location)element);\r
+    }\r
+    return locations;\r
+  }\r
+  \r
+  public String getTitle () {\r
+    return getOneElementValue("md-title");\r
+  }\r
+  \r
+  public String getTitleRemainder() {\r
+    return getOneElementValue("md-title-remainder");\r
+  }\r
+  \r
+  public String getAuthor (String prefix) {\r
+    return getOneElement("md-author") != null ? prefix + getOneElement("md-author").getValue() : "";\r
+  }\r
+  \r
+  public String getAuthor () {\r
+    return getOneElementValue("md-author");\r
+  }\r
+  \r
+  public String getTitleResponsibility() {\r
+    return getOneElementValue("md-title-responsibility");\r
+  }\r
+  \r
+  public String getRecId() {\r
+    return getOneElementValue("recid");\r
+  }\r
+\r
+  \r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Location.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Location.java
new file mode 100644 (file)
index 0000000..526dda0
--- /dev/null
@@ -0,0 +1,54 @@
+package com.indexdata.pz2utils4jsf.pazpar2.data;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseData;\r
+\r
+\r
+public class Location extends Pazpar2ResponseData {\r
+    \r
+  private static final long serialVersionUID = -1386527442857478225L;\r
+\r
+  public String getId() {\r
+    return getAttribute("id");\r
+  }\r
+  \r
+  public String getName () {\r
+    return getAttribute("name");\r
+  }\r
+  \r
+  public String getSubject() {\r
+    return getOneElementValue("md-subject");\r
+  }\r
+  \r
+  public String getSubjects() {\r
+    StringBuilder builder = new StringBuilder("");\r
+    for (Pazpar2ResponseData data : getElements("md-subject")) {\r
+      if (builder.length()==0) {\r
+        builder.append(data.getValue());\r
+      } else {\r
+        builder.append(", ");\r
+        builder.append(data.getValue());\r
+      }\r
+    }\r
+    return builder.toString();\r
+  }\r
+\r
+  public String getAuthor() {\r
+    return getOneElementValue("md-author");\r
+  }\r
+  \r
+  public String getAuthors() {\r
+    StringBuilder builder = new StringBuilder("");\r
+    if (getElements("md-author") != null) {\r
+      for (Pazpar2ResponseData data : getElements("md-author")) {\r
+        if (builder.length()==0) {\r
+          builder.append(data.getValue());\r
+        } else {\r
+          builder.append(", ");\r
+          builder.append(data.getValue());\r
+        }\r
+      }\r
+    }\r
+    return builder.toString();\r
+  }\r
+  \r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Pazpar2ResponseData.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Pazpar2ResponseData.java
new file mode 100644 (file)
index 0000000..9412f90
--- /dev/null
@@ -0,0 +1,91 @@
+package com.indexdata.pz2utils4jsf.pazpar2.data;\r
+\r
+import java.io.Serializable;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseData;\r
+\r
+public class Pazpar2ResponseData implements Serializable {\r
+  \r
+  private static final long serialVersionUID = -3909755656714679959L;\r
+  String type = null;\r
+  HashMap<String,String> attributes = new HashMap<String,String>();\r
+  HashMap<String,List<Pazpar2ResponseData>> elements = new HashMap<String,List<Pazpar2ResponseData>>();\r
+  String textContent = "";\r
+        \r
+  public void setType (String type) {\r
+    this.type = type;\r
+  }\r
+  \r
+  public String getType () {\r
+    return type;\r
+  }\r
+  \r
+  public void setAttribute (String name, String value) {\r
+    attributes.put(name, value);\r
+  }\r
+  \r
+  public String getAttribute (String name) {\r
+    return attributes.get(name);\r
+  }\r
+    \r
+  public void addElement (String name, Pazpar2ResponseData value) {    \r
+    if (elements.containsKey(name)) {\r
+      elements.get(name).add(value);\r
+    } else {\r
+      List<Pazpar2ResponseData> list = new ArrayList<Pazpar2ResponseData>();\r
+      list.add(value);\r
+      elements.put(name,list);\r
+    }\r
+  }\r
+  \r
+  public List<Pazpar2ResponseData> getElements (String name) {\r
+    return elements.get(name);\r
+  }\r
+  \r
+  public Pazpar2ResponseData getOneElement (String name) {\r
+    if (elements.get(name) != null) {\r
+      return elements.get(name).get(0);\r
+    } else {\r
+      return null;\r
+    }\r
+  }\r
+  \r
+  public String getOneElementValue (String name) {\r
+    if (getOneElement(name)!=null && getOneElement(name).getValue().length()>0) {\r
+      return getOneElement(name).getValue();\r
+    } else {\r
+      return "";\r
+    }\r
+  }\r
+  \r
+  public void appendContent (String content) {\r
+    textContent = textContent + content;\r
+  }\r
+  \r
+  public String getValue () {\r
+    return textContent;\r
+  }\r
+  \r
+  public String getProperty(String name) {\r
+    List<Pazpar2ResponseData> els = elements.get(name);\r
+    if (els != null) {\r
+      return els.get(0).getValue();\r
+    } else {     \r
+      return null;\r
+    }\r
+  }\r
+  \r
+  public int getIntValue(String name) {\r
+    String val = getOneElementValue(name);\r
+    if (val.length()==0) {\r
+      return 0;\r
+    } else {\r
+      return Integer.parseInt(val);\r
+    }\r
+  }\r
+\r
+      \r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Pazpar2ResponseParser.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Pazpar2ResponseParser.java
new file mode 100644 (file)
index 0000000..a08fdbc
--- /dev/null
@@ -0,0 +1,141 @@
+package com.indexdata.pz2utils4jsf.pazpar2.data;\r
+\r
+import java.io.ByteArrayInputStream;\r
+import java.io.IOException;\r
+import java.io.UnsupportedEncodingException;\r
+import java.util.Arrays;\r
+import java.util.List;\r
+import java.util.Stack;\r
+\r
+import javax.xml.parsers.ParserConfigurationException;\r
+import javax.xml.parsers.SAXParser;\r
+import javax.xml.parsers.SAXParserFactory;\r
+\r
+import org.xml.sax.Attributes;\r
+import org.xml.sax.InputSource;\r
+import org.xml.sax.SAXException;\r
+import org.xml.sax.XMLReader;\r
+import org.xml.sax.helpers.DefaultHandler;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.ByTarget;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Hit;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Location;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseData;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.RecordResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.ShowResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.StatResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Target;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.TermListResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.TermListsResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.TermResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.TermXTargetResponse;\r
+\r
+public class Pazpar2ResponseParser extends DefaultHandler {\r
+\r
+  private XMLReader xmlReader = null;\r
+  private Pazpar2ResponseData currentElement = null;\r
+  private Stack<Pazpar2ResponseData> dataElements = new Stack<Pazpar2ResponseData>();\r
+  private Pazpar2ResponseData result = null;\r
+\r
+  private static final List<String> docTypes = \r
+      Arrays.asList("bytarget","termlist","show","stat","record");\r
+  \r
+  public Pazpar2ResponseParser() {    \r
+    try {\r
+      initSax();\r
+    } catch (ParserConfigurationException e) {\r
+      // TODO Auto-generated catch block\r
+      e.printStackTrace();\r
+    } catch (SAXException e) {\r
+      // TODO Auto-generated catch block\r
+      e.printStackTrace();\r
+    }\r
+  }\r
+  \r
+  private void initSax() throws ParserConfigurationException, SAXException {\r
+    SAXParserFactory spf = SAXParserFactory.newInstance();\r
+    spf.setNamespaceAware(true);\r
+    SAXParser saxParser = spf.newSAXParser();\r
+    xmlReader = saxParser.getXMLReader();\r
+    xmlReader.setContentHandler(this);         \r
+  }\r
+  \r
+  public Pazpar2ResponseData getObject (String response) {\r
+    try {\r
+      xmlReader.parse(new InputSource(new ByteArrayInputStream(response.getBytes("UTF-8"))));\r
+    } catch (UnsupportedEncodingException e) {\r
+      // TODO Auto-generated catch block\r
+      e.printStackTrace();\r
+    } catch (IOException e) {\r
+      // TODO Auto-generated catch block\r
+      e.printStackTrace();\r
+    } catch (SAXException e) {\r
+      // TODO Auto-generated catch block\r
+      e.printStackTrace();\r
+    }\r
+    return result;\r
+  }\r
+\r
+  /** \r
+   * Receive notification at the start of element \r
+   * \r
+   */\r
+  @Override\r
+  public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {\r
+    if (localName.equals("show")) {\r
+      currentElement = new ShowResponse();\r
+    } else if (localName.equals("hit")) {\r
+      currentElement = new Hit();\r
+    } else if (localName.equals("location")) {\r
+      currentElement = new Location();\r
+    } else if (localName.equals("bytarget")) {\r
+      currentElement = new ByTarget();\r
+    } else if (localName.equals("target")) {\r
+      currentElement = new Target();\r
+    } else if (localName.equals("stat")) {\r
+      currentElement = new StatResponse();\r
+    } else if (localName.equals("termlist")) {\r
+      currentElement = new TermListsResponse();\r
+    } else if (localName.equals("list")) {\r
+      currentElement = new TermListResponse();\r
+      ((TermListResponse)currentElement).setName(atts.getValue("name"));\r
+      ((TermListsResponse)dataElements.peek()).addTermList((TermListResponse)currentElement);\r
+    } else if (localName.equals("term")) {\r
+      if (dataElements.peek().getAttribute("name").equals("xtargets")) {\r
+        currentElement = new TermXTargetResponse();        \r
+      } else {\r
+        currentElement = new TermResponse();\r
+      }\r
+      ((TermListResponse)dataElements.peek()).addTerm((TermResponse)currentElement);\r
+    } else if (localName.equals("record")) {\r
+      currentElement = new RecordResponse();\r
+    } else {\r
+      currentElement = new Pazpar2ResponseData();\r
+    }\r
+    currentElement.setType(localName);\r
+    for (int i=0; i< atts.getLength(); i++) {\r
+       currentElement.setAttribute(atts.getLocalName(i), atts.getValue(i));\r
+    }\r
+    if (!docTypes.contains(localName)) {\r
+      dataElements.peek().addElement(localName, currentElement);\r
+    }\r
+    dataElements.push(currentElement);    \r
+  }\r
\r
+  @Override\r
+  public void characters(char[] ch, int start, int length) throws SAXException {\r
+    String data = new String(ch, start, length);        \r
+    dataElements.peek().appendContent(data);    \r
+  }\r
+  \r
+  @Override\r
+  public void endElement(String namespaceURI, String localName, String qName) throws SAXException {\r
+    if (dataElements.size()==1) {\r
+      result = dataElements.pop();\r
+    } else {\r
+      dataElements.pop();\r
+    }\r
+  }\r
+\r
+\r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/RecordResponse.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/RecordResponse.java
new file mode 100644 (file)
index 0000000..d1af720
--- /dev/null
@@ -0,0 +1,59 @@
+package com.indexdata.pz2utils4jsf.pazpar2.data;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Location;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseData;\r
+\r
+public class RecordResponse extends Pazpar2ResponseData {\r
+\r
+  private static final long serialVersionUID = 6682722004285796002L;\r
+\r
+  public String getRecId () {\r
+    return getOneElementValue("recid");\r
+  }\r
+  \r
+  public List<Location> getLocations() {\r
+    List<Location> locations = new ArrayList<Location>();\r
+    for (Pazpar2ResponseData element : getElements("location")) {\r
+      locations.add((Location)element);\r
+    }\r
+    return locations;\r
+  }\r
+\r
+  public String getTitle() {\r
+    return getOneElementValue("md-title");\r
+  }\r
+  \r
+  public String getDate() {\r
+    return getOneElementValue("md-date");\r
+  }\r
+  \r
+  public String getAuthor() {\r
+    return getOneElementValue("md-author");\r
+  }\r
+  \r
+  public String getSubject() {\r
+    return getOneElementValue("md-subject");\r
+  }\r
+  \r
+  public String getSubjects() {\r
+    StringBuilder builder = new StringBuilder("");\r
+    for (Pazpar2ResponseData data : getElements("md-subject")) {\r
+      if (builder.length()==0) {\r
+        builder.append(data.getValue());\r
+      } else {\r
+        builder.append(", ");\r
+        builder.append(data.getValue());\r
+      }\r
+    }\r
+    return builder.toString();\r
+  }\r
+    \r
+  public Location getFirstLocation () {\r
+    return getLocations().size()>0 ? getLocations().get(0) : null;\r
+  }\r
+  \r
+  \r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/ShowResponse.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/ShowResponse.java
new file mode 100644 (file)
index 0000000..6c6af92
--- /dev/null
@@ -0,0 +1,49 @@
+package com.indexdata.pz2utils4jsf.pazpar2.data;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Hit;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseData;\r
+\r
+public class ShowResponse extends Pazpar2ResponseData {\r
+\r
+  private static final long serialVersionUID = 7103554232106330370L;\r
+  \r
+\r
+  public String getStatus() {\r
+    return getOneElement("status").getValue();\r
+  }\r
+  \r
+  public String getActiveClients () {\r
+    return getOneElementValue("activeclients");\r
+  }\r
+  \r
+  public int getMerged () {\r
+    return getIntValue("merged");\r
+  }\r
+  \r
+  public String getTotal () {\r
+    return getOneElementValue("total");    \r
+  }\r
+  \r
+  public int getStart () {\r
+    return getIntValue("start");\r
+  }\r
+\r
+  public int getNum () {\r
+    return getIntValue("num");\r
+  }\r
\r
+  public List<Hit> getHits() {\r
+    List<Hit> hits = new ArrayList<Hit>();\r
+    if (getElements("hit") != null) {\r
+      for (Pazpar2ResponseData element : getElements("hit")) {\r
+        hits.add((Hit)element);\r
+      }\r
+    } \r
+    return hits;\r
+  }\r
+  \r
+\r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/StatResponse.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/StatResponse.java
new file mode 100644 (file)
index 0000000..c0df51d
--- /dev/null
@@ -0,0 +1,53 @@
+package com.indexdata.pz2utils4jsf.pazpar2.data;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseData;\r
+\r
+public class StatResponse extends Pazpar2ResponseData {\r
+  \r
+  private static final long serialVersionUID = -6578979787689458761L;\r
+\r
+  public int getHits() {    \r
+    return getProperty("hits")==null ? 0 : Integer.parseInt(getProperty("hits"));\r
+  }\r
+  \r
+  public int getClients () {\r
+    return getIntValue("clients");\r
+  }\r
+  \r
+  public int getActiveClients () {\r
+    return getIntValue("activeclients");\r
+  }\r
+\r
+  public int getRecords () {\r
+    return getIntValue("records");\r
+  }\r
+  \r
+  public String getUnconnected() {\r
+    return getOneElementValue("unconnected");\r
+  }\r
+  \r
+  public String getConnecting() {\r
+    return getOneElementValue("connecting");\r
+  }\r
+  \r
+  public String getWorking() {\r
+    return getOneElementValue("working");\r
+  }\r
+  \r
+  public String getIdle() {\r
+    return getOneElementValue("idle");\r
+  }\r
+  \r
+  public String getFailed() {\r
+    return getOneElementValue("failed");\r
+  }\r
+  \r
+  public String getError() {\r
+    return getOneElementValue("error");\r
+  }\r
+  \r
+  public String getProgress() {\r
+    return getOneElementValue("progress");\r
+  }\r
+  \r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Target.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Target.java
new file mode 100644 (file)
index 0000000..11526f3
--- /dev/null
@@ -0,0 +1,33 @@
+package com.indexdata.pz2utils4jsf.pazpar2.data;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseData;\r
+\r
+public class Target extends Pazpar2ResponseData {\r
+\r
+  private static final long serialVersionUID = 3343881183545520108L;\r
+\r
+  public String getId () {\r
+    return getOneElementValue("id");\r
+  }\r
+  \r
+  public String getName() {\r
+    return getOneElementValue("name");\r
+  }\r
+  \r
+  public String getHits() {\r
+    return getOneElementValue("hits");\r
+  }\r
+  \r
+  public String getDiagnostic() {\r
+    return getOneElementValue("diagnostic");\r
+  }\r
+  \r
+  public String getRecords() {\r
+    return getOneElementValue("records");\r
+  }\r
+  \r
+  public String getState () {\r
+    return getOneElementValue("state");\r
+  }\r
+    \r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/TermListResponse.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/TermListResponse.java
new file mode 100644 (file)
index 0000000..a4a33fb
--- /dev/null
@@ -0,0 +1,52 @@
+package com.indexdata.pz2utils4jsf.pazpar2.data;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.apache.log4j.Logger;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseData;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.TermListResponse;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.TermResponse;\r
+\r
+public class TermListResponse extends Pazpar2ResponseData {\r
+\r
+  private static Logger logger = Logger.getLogger(TermListResponse.class);\r
+  private static final long serialVersionUID = 3838585739723097393L;\r
+  String name = "";\r
+  List<TermResponse> terms = new ArrayList<TermResponse>();\r
+  \r
+  public String getName() {\r
+    return name;\r
+  }\r
+  \r
+  public void setName(String name) {\r
+    this.name = name;\r
+  }\r
+  \r
+  public List<TermResponse> getTerms() {    \r
+    return terms;\r
+  }\r
+  \r
+  public List<TermResponse> getTerms(int count) {\r
+    List<TermResponse> firstTerms = new ArrayList<TermResponse>();\r
+    for (int i=0; i<count && i<terms.size(); i++) {\r
+      firstTerms.add(terms.get(i));\r
+    }\r
+    logger.trace("Returning " + count + " " + name + " terms: " + firstTerms);\r
+    return firstTerms;\r
+  }\r
+  \r
+  public void setTerms(List<TermResponse> terms) {\r
+    this.terms = terms;\r
+  }\r
+  \r
+  public void addTerm(TermResponse term) {\r
+    terms.add(term);\r
+  }  \r
+  \r
+  public String toString () {\r
+    return terms.toString();\r
+  }\r
+  \r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/TermListsResponse.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/TermListsResponse.java
new file mode 100644 (file)
index 0000000..c060579
--- /dev/null
@@ -0,0 +1,30 @@
+package com.indexdata.pz2utils4jsf.pazpar2.data;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseData;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.TermListResponse;\r
+\r
+public class TermListsResponse extends Pazpar2ResponseData {\r
+\r
+  private static final long serialVersionUID = -1370643625715834978L;\r
+  private int activeClients = -1;\r
+  private Map<String,TermListResponse> termLists = new HashMap<String,TermListResponse>(); \r
+  \r
+  public int getActiveClients() {\r
+    return activeClients;\r
+  }\r
+  public void setActiveClients(int activeClients) {\r
+    this.activeClients = activeClients;\r
+  }\r
+\r
+  public void addTermList(TermListResponse termList) {    \r
+    this.termLists.put(termList.getName(),termList);\r
+  }\r
+  public TermListResponse getTermList(String name) {    \r
+    return termLists.get(name);\r
+  }\r
+  \r
+  \r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/TermResponse.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/TermResponse.java
new file mode 100644 (file)
index 0000000..5b2e90e
--- /dev/null
@@ -0,0 +1,22 @@
+package com.indexdata.pz2utils4jsf.pazpar2.data;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseData;\r
+\r
+public class TermResponse extends Pazpar2ResponseData {\r
+\r
+  private static final long serialVersionUID = -8323959763575180678L;\r
+  \r
+  protected int frequency = -1;\r
+  \r
+  public String getName() {\r
+    return getProperty("name");\r
+  }\r
+  public int getFrequency() {\r
+    return Integer.parseInt(getProperty("frequency"));\r
+  }\r
+  \r
+  public String toString() {\r
+    return getProperty("name");\r
+  }\r
+  \r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/TermXTargetResponse.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/TermXTargetResponse.java
new file mode 100644 (file)
index 0000000..a435b34
--- /dev/null
@@ -0,0 +1,28 @@
+package com.indexdata.pz2utils4jsf.pazpar2.data;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.TermResponse;\r
+\r
+public class TermXTargetResponse extends TermResponse {\r
+\r
+  private static final long serialVersionUID = 5201902652960804977L;\r
+  \r
+  public String getId() {\r
+    return getOneElement("id").getValue();\r
+  }\r
+  public int getApproximation () {\r
+    return Integer.parseInt(getOneElement("approximation").getValue());\r
+  }\r
+  public int getRecords () {\r
+    return Integer.parseInt(getOneElement("records").getValue());\r
+  }\r
+  public int getFiltered () {\r
+    return Integer.parseInt(getOneElement("filtered").getValue());\r
+  }\r
+  public String getState () {\r
+    return getOneElement("state").getValue();\r
+  }\r
+  public String getDiagnostic () {\r
+    return getOneElement("diagnostic").getValue();\r
+  }\r
+\r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/state/QueryState.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/state/QueryState.java
new file mode 100644 (file)
index 0000000..5f8ef23
--- /dev/null
@@ -0,0 +1,147 @@
+package com.indexdata.pz2utils4jsf.pazpar2.state;\r
+\r
+import java.io.Serializable;\r
+import java.util.Arrays;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.apache.log4j.Logger;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.CommandParameter;\r
+import com.indexdata.pz2utils4jsf.pazpar2.Expression;\r
+import com.indexdata.pz2utils4jsf.pazpar2.Pazpar2Command;\r
+import com.indexdata.pz2utils4jsf.pazpar2.state.QueryState;\r
+import com.indexdata.pz2utils4jsf.pazpar2.state.QueryStates;\r
+\r
+public class QueryState implements Serializable {\r
+  \r
+  private static final long serialVersionUID = -1465676392610954168L;\r
+  private static Logger logger = Logger.getLogger(QueryState.class);\r
+  private Map<String,Pazpar2Command> pz2commands = new HashMap<String,Pazpar2Command>();\r
+  private String key = null;  \r
+  \r
+  public QueryState () {\r
+    for (String command : Arrays.asList("init","ping","settings","search","stat","show","record","termlist","bytarget")) {\r
+      pz2commands.put(command, new Pazpar2Command(command));\r
+    }\r
+  }    \r
+  \r
+  private QueryState copy() {    \r
+    QueryState newState = new QueryState();\r
+    for (String commandName : pz2commands.keySet()) {\r
+      newState.setCommand(pz2commands.get(commandName).copy());\r
+    }\r
+    return newState;\r
+  }\r
+    \r
+  public void setCommandParameter(String commandName, CommandParameter parameter, QueryStates queryStates) {\r
+    CommandParameter current = getCommand(commandName).getParameter(parameter.getName());\r
+    if (current != null && current.equals(parameter)) {\r
+      logger.debug("Recieved parameter but already have " + parameter.getValueWithExpressions() + " in this state. No state change.");\r
+    } else {\r
+      logger.debug("New command parameter received: " + parameter.getValueWithExpressions() + ". Initiating new state.");\r
+      QueryState newState = this.copy();\r
+      newState._setCommandParameter(commandName,parameter);\r
+      logger.debug("Old state: " + this);\r
+      logger.debug("New state: " + newState);        \r
+      queryStates.setCurrentState(newState);\r
+    }\r
+  }\r
+  \r
+  public void removeCommandParameter(String commandName, String parameterName, QueryStates queryStates) {\r
+    QueryState newState = this.copy();\r
+    newState._removeCommandParameter(commandName, parameterName);\r
+    queryStates.setCurrentState(newState);\r
+  }\r
+  \r
+  public void setCommandParameterExpression (String commandName, String parameterName, Expression expression, QueryStates queryStates) {\r
+    QueryState newState = this.copy();\r
+    newState._setCommandParameterExpression(commandName, parameterName, expression);\r
+    queryStates.setCurrentState(newState);\r
+  }\r
+  \r
+  public void _setCommandParameterExpression (String commandName, String parameterName, Expression expression) {\r
+    getCommand(commandName).getParameter(parameterName).addExpression(expression);\r
+  }\r
+  \r
+  public void removeCommandParameterExpression (String commandName, String parameterName, Expression expression, QueryStates queryStates) {\r
+    QueryState newState = this.copy();\r
+    newState._removeCommandParameterExpression(commandName, parameterName, expression);\r
+    queryStates.setCurrentState(newState);\r
+  }\r
+  \r
+  public void _removeCommandParameterExpression (String commandName, String parameterName, Expression expression) {\r
+    getCommand(commandName).getParameter(parameterName).removeExpression(expression);\r
+    \r
+  }\r
+\r
+  public void _setCommandParameter(String commandName, CommandParameter parameter) {\r
+    getCommand(commandName).setParameter(parameter);\r
+  }\r
+  \r
+  public void _removeCommandParameter(String commandName, String parameterName) {\r
+    getCommand(commandName).removeParameter(parameterName);\r
+  }\r
+  \r
+  public void _removeCommand(String commandName) {\r
+    getCommand(commandName).removeParameters();    \r
+  }\r
+\r
+  \r
+  public void removeCommand (String commandName, QueryStates queryStates) {\r
+    QueryState newState = this.copy();\r
+    newState._removeCommand(commandName);\r
+    queryStates.setCurrentState(newState);\r
+    \r
+  }\r
+\r
+  public Pazpar2Command getCommand(String name) {\r
+    return pz2commands.get(name);\r
+  }\r
+  \r
+  private void setCommand(Pazpar2Command command) {\r
+    pz2commands.put(command.getName(), command);\r
+  }\r
+  \r
+  public String getKey() {\r
+    if (key == null) {\r
+      StringBuilder querystatebuilder = new StringBuilder("#");\r
+      for (Pazpar2Command command : pz2commands.values()) {\r
+        if (command.hasParameters()) {\r
+          querystatebuilder.append("||"+command.getName()+"::");\r
+          querystatebuilder.append(command.getValueWithExpressions());\r
+        }      \r
+      }            \r
+      key = querystatebuilder.toString();\r
+      return key;\r
+    } else {      \r
+      return key;\r
+    }\r
+  }\r
+  \r
+  public void setKey(String key) {\r
+    logger.debug("Setting key on demand to: " + key);\r
+    this.key = key;\r
+  }\r
+  \r
+  public String toString () {\r
+    return pz2commands.toString();\r
+  }\r
+  \r
+  public boolean searchEquals(Object otherQueryState) {\r
+    if (otherQueryState instanceof QueryState) {\r
+      return getCommand("search").equals(((QueryState) otherQueryState).getCommand("search"));\r
+    } else {\r
+      return false;\r
+    }\r
+  }\r
+  \r
+  public boolean equals (Object otherQueryState) {\r
+    if (otherQueryState instanceof QueryState) {\r
+      return this.toString().equals(otherQueryState.toString());              \r
+    } else {\r
+      return false;\r
+    }\r
+  }\r
+\r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/state/QueryStates.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/state/QueryStates.java
new file mode 100644 (file)
index 0000000..ea1264d
--- /dev/null
@@ -0,0 +1,76 @@
+package com.indexdata.pz2utils4jsf.pazpar2.state;\r
+\r
+import java.io.Serializable;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.apache.log4j.Logger;\r
+\r
+import com.indexdata.pz2utils4jsf.pazpar2.Pazpar2Command;\r
+import com.indexdata.pz2utils4jsf.pazpar2.state.QueryState;\r
+import com.indexdata.pz2utils4jsf.pazpar2.state.QueryStates;\r
+\r
+public class QueryStates implements Serializable {\r
+  \r
+  private static final long serialVersionUID = 6131720167974584659L;\r
+  private static Logger logger = Logger.getLogger(QueryStates.class);\r
+    \r
+  Map<String, QueryState> queryStates = new HashMap<String, QueryState>();\r
+  String currentStateKey = "";\r
+  Map<String,Boolean> pendingStateChanges = new HashMap<String,Boolean>();  \r
+\r
+  public QueryStates () {\r
+    queryStates.put("#initial", new QueryState());\r
+    currentStateKey = "#initial";\r
+    for (String command : Pazpar2Command.allCommands) {\r
+      pendingStateChanges.put(command, new Boolean(false));\r
+    }\r
+  }\r
+  \r
+  public String getCurrentStateKey() {\r
+    return currentStateKey;\r
+  }\r
+\r
+  public void setCurrentStateKey(String key) {\r
+    \r
+    if (currentStateKey.equals(key)) {\r
+      logger.debug("setCurrentStateKey: no key change detected");\r
+    } else {\r
+      logger.debug("State key change. Was: [" + currentStateKey + "]. Will be ["+key+"]");\r
+      if (queryStates.get(key).getCommand("search").equals(getCurrentState().getCommand("search"))) {\r
+        logger.debug("No search change detected");\r
+      } else {\r
+        hasPendingStateChange("search",true);\r
+      }\r
+      if (queryStates.get(key).getCommand("record").equals(getCurrentState().getCommand("record"))) {\r
+        logger.debug("No record change detected");\r
+      } else {\r
+        hasPendingStateChange("record",true);\r
+      }\r
+      currentStateKey = key;\r
+    }\r
+  }\r
+    \r
+  public QueryState getCurrentState() {\r
+    if (queryStates.get(currentStateKey) == null) {      \r
+      return new QueryState();\r
+    } else {            \r
+      return queryStates.get(currentStateKey);\r
+    }\r
+  }\r
+  \r
+  public void setCurrentState(QueryState queryState) {\r
+    logger.debug("Setting current state: " + queryState.getKey());\r
+    queryStates.put(queryState.getKey(), queryState);\r
+    setCurrentStateKey(queryState.getKey());\r
+  }\r
+    \r
+  public void hasPendingStateChange(String command, boolean bool) {\r
+    pendingStateChanges.put(command, new Boolean(bool));\r
+  }\r
+  \r
+  public boolean hasPendingStateChange (String command) {\r
+    return pendingStateChanges.get(command).booleanValue();\r
+  }\r
+  \r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pz2utils/ListenerFieldIds.java b/src/main/java/com/indexdata/pz2utils4jsf/pz2utils/ListenerFieldIds.java
new file mode 100644 (file)
index 0000000..02776f8
--- /dev/null
@@ -0,0 +1,22 @@
+package com.indexdata.pz2utils4jsf.pz2utils;\r
+\r
+import java.io.Serializable;\r
+\r
+import javax.enterprise.context.ApplicationScoped;\r
+import javax.inject.Named;\r
+\r
+@Named("pz2watch")\r
+@ApplicationScoped\r
+public class ListenerFieldIds implements Serializable {\r
+  \r
+  private static final long serialVersionUID = -57079241763914538L;\r
+      \r
+  public String getHistory () {\r
+    return ":pz2watch:stateForm:windowlocationhash";\r
+  }\r
+    \r
+  public String getActiveclients () {\r
+    return ":pz2watch:activeclientsForm:activeclientsField";\r
+  }\r
+\r
+}\r