Work in progress on error detect,report,troubleshoot
authorNiels Erik G. Nielsen <nielserik@indexdata.com>
Fri, 8 Mar 2013 22:38:11 +0000 (17:38 -0500)
committerNiels Erik G. Nielsen <nielserik@indexdata.com>
Fri, 8 Mar 2013 22:38:11 +0000 (17:38 -0500)
Adds configuration errors (had command errors)
Resolves more errors
Adds more suggestions

14 files changed:
src/META-INF/resources/pz2utils/pz2watch.xhtml
src/main/java/com/indexdata/pz2utils4jsf/config/Pz2ConfigureByMk2Config.java
src/main/java/com/indexdata/pz2utils4jsf/errors/ApplicationError.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/errors/ConfigurationError.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/errors/ErrorHelper.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/ApplicationTroubleshooter.java [deleted file]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/CommandThread.java
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Pz2Bean.java
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Pz2Interface.java
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Pz2Session.java
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/ApplicationError.java [deleted file]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/CommandError.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Pazpar2ResponseData.java
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Pazpar2ResponseParser.java

index dfa628d..de46cc7 100644 (file)
       <h:outputText id="activeClientsLabel" value="Active clients: " style="${cc.attrs.debug == 'true' ? '' : 'display:none;'}"/> \r
       <h:outputText id="activeclientsField" value="${pz2.update()}"  style="${cc.attrs.debug == 'true' ? '' : 'display:none;'}"/>\r
       <h:panelGrid id="errorMessages" style="${pz2.hasErrors() ? 'display: block;' : 'display: none;'}">\r
-        <p><h:outputText id="messages" value="Error: #{pz2.oneError.errorMessage}" style="color: red;"/></p>\r
-        <h:dataTable value="#{pz2.oneError.suggestions}" var="suggestion" cellspacing="0" cellpadding="0">       \r
-         <h:column>\r
-           #{suggestion}        \r
-         </h:column>      \r
-        </h:dataTable>                \r
+        <h:dataTable value="#{pz2.configurationErrors}" var="error" cellspace="0" cellpadding="0" style="${pz2.hasConfigurationErrors() ? 'display: block;' : 'display: none;'}">\r
+          <h:column valign="top">\r
+            #{error.label}\r
+          </h:column>\r
+          <h:column valign="top">\r
+            <h:outputText value="#{error.message}" style="color: red;"/>\r
+          </h:column>\r
+          <h:column>\r
+            <h:dataTable value="#{error.suggestions}" var="suggestion" cellspacing="0" cellpadding="0">       \r
+             <h:column>\r
+               #{suggestion}        \r
+             </h:column>      \r
+            </h:dataTable>                            \r
+          </h:column>\r
+        </h:dataTable>\r
+        <h:panelGrid  style="${pz2.hasCommandErrors() ? 'display: block;' : 'display: none;'}">\r
+          <p><h:outputText id="messages" value="#{pz2.commandError.message}" style="color: red;"/></p>\r
+          <h:dataTable value="#{pz2.commandError.suggestions}" var="suggestion" cellspacing="0" cellpadding="0">       \r
+           <h:column>\r
+             #{suggestion}        \r
+           </h:column>      \r
+          </h:dataTable>\r
+        </h:panelGrid>                \r
       </h:panelGrid>                      \r
     </h:form>\r
 \r
index f10aa1e..dccda3b 100644 (file)
@@ -18,8 +18,6 @@ import com.indexdata.masterkey.config.MasterkeyConfiguration;
 import com.indexdata.masterkey.config.ModuleConfiguration;\r
 import com.indexdata.pz2utils4jsf.utils.Utils;\r
 \r
-import static com.indexdata.pz2utils4jsf.utils.Utils.nl;\r
-\r
 @Named @SessionScoped @Alternative\r
 public class Pz2ConfigureByMk2Config implements Pz2Configurator  {\r
 \r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/errors/ApplicationError.java b/src/main/java/com/indexdata/pz2utils4jsf/errors/ApplicationError.java
new file mode 100644 (file)
index 0000000..450df7a
--- /dev/null
@@ -0,0 +1,19 @@
+package com.indexdata.pz2utils4jsf.errors;\r
+\r
+import java.io.Serializable;\r
+import java.util.List;\r
+\r
+import com.indexdata.pz2utils4jsf.errors.ErrorHelper.ErrorCode;\r
+\r
+\r
+public interface ApplicationError extends Serializable {\r
+  \r
+  public String getLabel();\r
+  public String getMessage(); \r
+  public String getException();\r
+  public void setApplicationErrorCode(ErrorCode code);\r
+  public ErrorCode getApplicationErrorCode();\r
+  public List<String> getSuggestions();\r
+  public void setErrorHelper(ErrorHelper helper);\r
+    \r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/errors/ConfigurationError.java b/src/main/java/com/indexdata/pz2utils4jsf/errors/ConfigurationError.java
new file mode 100644 (file)
index 0000000..c27f3a3
--- /dev/null
@@ -0,0 +1,60 @@
+package com.indexdata.pz2utils4jsf.errors;\r
+\r
+import java.util.List;\r
+\r
+import com.indexdata.pz2utils4jsf.errors.ErrorHelper.ErrorCode;\r
+\r
+\r
+public class ConfigurationError implements ApplicationError {\r
+\r
+  private static final long serialVersionUID = -6599667223782130838L;\r
+  private String label;\r
+  private String message;\r
+  private String exception;\r
+  private ErrorHelper helper;\r
+  private ErrorCode applicationErrorCode;\r
+  \r
+  public ConfigurationError(String label, String exception, String message, ErrorHelper helper) {\r
+    this.label = label;\r
+    this.message = message;\r
+    this.helper = helper;  \r
+    this.exception = exception;\r
+  }\r
+  \r
+  public List<String> getSuggestions() {\r
+    return helper.getSuggestions(this);\r
+  }\r
+\r
+  @Override\r
+  public String getLabel() {\r
+    return label;\r
+  }\r
+\r
+  @Override\r
+  public String getMessage() {\r
+    return message;\r
+  }\r
+  \r
+  @Override\r
+  public String getException() {\r
+    return exception;\r
+  }\r
+  \r
+  @Override\r
+  public void setErrorHelper (ErrorHelper helper) {\r
+    this.helper = helper;\r
+  }\r
+\r
+  @Override\r
+  public void setApplicationErrorCode(ErrorCode code) {\r
+    this.applicationErrorCode = code;\r
+  }\r
+\r
+  @Override\r
+  public ErrorCode getApplicationErrorCode() {\r
+    return applicationErrorCode;\r
+  }\r
+  \r
+\r
+  \r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/errors/ErrorHelper.java b/src/main/java/com/indexdata/pz2utils4jsf/errors/ErrorHelper.java
new file mode 100644 (file)
index 0000000..9aa8fec
--- /dev/null
@@ -0,0 +1,83 @@
+package com.indexdata.pz2utils4jsf.errors;\r
+\r
+import java.io.Serializable;\r
+import java.util.ArrayList;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+import org.apache.log4j.Logger;\r
+\r
+import com.indexdata.pz2utils4jsf.config.Pz2Configurator;\r
+import com.indexdata.pz2utils4jsf.utils.Utils;\r
+import static com.indexdata.pz2utils4jsf.utils.Utils.nl;\r
+\r
+public class ErrorHelper implements Serializable {\r
+\r
+  public enum ErrorCode {PAZPAR2_404, \r
+                         PAZPAR2_UNEXPECTED_RESPONSE,\r
+                         LOCAL_SERVICE_DEF_FILE_NOT_FOUND,\r
+                         REMOTE_SERVICE_DEF_NOT_FOUND,\r
+                         LOCAL_SETTINGS_FILE_NOT_FOUND,\r
+                         NOT_RESOLVED};\r
+\r
+  private static final long serialVersionUID = 2860804561068279131L;\r
+  private static Pattern httpResponsePattern = Pattern.compile("Unexpected HTTP response code \\(([0-9]*)\\).*");\r
+  private static Pattern missingLocalServiceDefFile = Pattern.compile(".*Error reading service definition XML.*");\r
+  private static Logger logger = Logger.getLogger(ErrorHelper.class);\r
+  \r
+  private Pz2Configurator configurator = null;\r
+  \r
+  public ErrorHelper(Pz2Configurator configurator) {\r
+    this.configurator = configurator;\r
+  }\r
+  \r
+  public ErrorHelper.ErrorCode getErrorCode(ApplicationError error) {    \r
+    if (error.getMessage().startsWith("Unexpected HTTP response")) {\r
+      Matcher m = httpResponsePattern.matcher(error.getMessage());\r
+      if (m.matches()) {\r
+        String errorCode = m.group(1);\r
+        if (errorCode.equals("404")) {\r
+          return ErrorCode.PAZPAR2_404;\r
+        } else {\r
+          return ErrorCode.PAZPAR2_UNEXPECTED_RESPONSE;\r
+        }\r
+      }       \r
+    } else if (error.getMessage().contains("Error reading service definition XML")) {\r
+      return ErrorCode.LOCAL_SERVICE_DEF_FILE_NOT_FOUND;\r
+    }\r
+    return ErrorCode.NOT_RESOLVED;\r
+  }\r
+    \r
+  public ArrayList<String> getSuggestions(ApplicationError error) {\r
+    ArrayList<String> suggestions = new ArrayList<String>();\r
+    ErrorCode code = getErrorCode(error);\r
+    switch (code) {\r
+    case PAZPAR2_404:\r
+      suggestions.add("Pazpar2 service not found (404). ");\r
+      suggestions.add("Please check the PAZPAR2_URL configuration and verify "\r
+          + "that a pazpar2 service is running at the given address.");\r
+      suggestions.add("The application was configured using " + Utils.baseObjectName(configurator));\r
+      suggestions.add("The configurator reports following configuration was used: ");\r
+      suggestions.addAll(configurator.document());\r
+      break;\r
+    case PAZPAR2_UNEXPECTED_RESPONSE:\r
+      suggestions.add("Unexpected response code from Pazpar2. " + nl\r
+          + "Please check the PAZPAR2_URL configuration and verify "\r
+          + "that a pazpar2 service is running at the given address." + nl);\r
+      break;\r
+    case LOCAL_SERVICE_DEF_FILE_NOT_FOUND:\r
+      suggestions.add("The service definition file could not be loaded.");\r
+      suggestions.add("Please check the configuration and verify that the file exists");\r
+      suggestions.add("The configurator reports following configuration was used: ");\r
+      suggestions.addAll(configurator.document());    \r
+      break;\r
+    case REMOTE_SERVICE_DEF_NOT_FOUND:\r
+      break;\r
+    case LOCAL_SETTINGS_FILE_NOT_FOUND:\r
+      break;\r
+    case NOT_RESOLVED:\r
+      break;\r
+    }\r
+    return suggestions;\r
+  }\r
+}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/ApplicationTroubleshooter.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/ApplicationTroubleshooter.java
deleted file mode 100644 (file)
index a30bc54..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.indexdata.pz2utils4jsf.pazpar2;\r
-\r
-import java.util.ArrayList;\r
-import java.util.regex.Matcher;\r
-import java.util.regex.Pattern;\r
-\r
-import org.apache.log4j.Logger;\r
-\r
-import com.indexdata.pz2utils4jsf.config.Pz2Configurator;\r
-import com.indexdata.pz2utils4jsf.utils.Utils;\r
-import static com.indexdata.pz2utils4jsf.utils.Utils.nl;\r
-\r
-public class ApplicationTroubleshooter {\r
-\r
-  private static Pattern httpResponsePattern = Pattern.compile("Unexpected HTTP response code \\(([0-9]*)\\).*");\r
-  private static Logger logger = Logger.getLogger(ApplicationTroubleshooter.class);\r
-  \r
-  private Pz2Configurator configurator = null;\r
-  \r
-  public ApplicationTroubleshooter(Pz2Configurator configurator) {\r
-    this.configurator = configurator;\r
-  }\r
-    \r
-  public ArrayList<String> getSuggestions(String commandName, String errorMessage) {\r
-    ArrayList<String> suggestions = new ArrayList<String>();\r
-    if (errorMessage.startsWith("Unexpected HTTP response")) {\r
-      Matcher m = httpResponsePattern.matcher(errorMessage);\r
-      if (m.matches()) {\r
-        String errorCode = m.group(1);\r
-        if (errorCode.equals("404")) {\r
-          suggestions.add("Pazpar2 service not found (response code 404). ");\r
-          suggestions.add("Please check the PAZPAR2_URL configuration and verify " +\r
-                       "that a pazpar2 service is running at the given address."); \r
-          suggestions.add("The application was configured using " + Utils.baseObjectName(configurator));\r
-          suggestions.add("The configurator reports following configuration was used: ");\r
-          suggestions.addAll(configurator.document());          \r
-        } else {\r
-          suggestions.add("Response code was " + errorCode + ". " + nl +\r
-              "Please check the PAZPAR2_URL configuration and verify " + \r
-              "that a pazpar2 service is running at the given address." + nl);           \r
-        }        \r
-      } else {\r
-        logger.warn("Found message but no pattern match");        \r
-      }      \r
-    }\r
-    if (errorMessage == null || errorMessage.length()==0) {\r
-      logger.debug("No error message found, no suggestions made.");\r
-    } else {\r
-      logger.info("No suggestions yet for message " + errorMessage);\r
-    }\r
-    return suggestions;\r
-  }\r
-}\r
index 50ec2b6..ea52988 100644 (file)
@@ -7,8 +7,9 @@ import org.apache.log4j.Logger;
 \r
 import com.indexdata.masterkey.pazpar2.client.ClientCommand;\r
 import com.indexdata.masterkey.pazpar2.client.Pazpar2Client;\r
+import com.indexdata.masterkey.pazpar2.client.Pazpar2HttpResponse;\r
 import com.indexdata.masterkey.pazpar2.client.exceptions.Pazpar2ErrorException;\r
-import com.indexdata.pz2utils4jsf.pazpar2.data.ApplicationError;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.CommandError;\r
 \r
 public class CommandThread extends Thread {\r
 \r
@@ -16,7 +17,7 @@ public class CommandThread extends Thread {
   Pazpar2Command command;\r
   Pazpar2Client client;\r
   private ByteArrayOutputStream baos = new ByteArrayOutputStream();\r
-  private StringBuilder response = new StringBuilder("");\r
+  private StringBuilder response = new StringBuilder("");  \r
   \r
   public CommandThread (Pazpar2Command command, Pazpar2Client client) {\r
     this.command = command;\r
@@ -40,16 +41,24 @@ public class CommandThread extends Thread {
     }\r
     try {\r
       long start = System.currentTimeMillis();\r
-      client.executeCommand(clientCommand, baos);\r
-      response.append(baos.toString("UTF-8"));\r
+      Pazpar2HttpResponse httpResponse = client.executeCommand(clientCommand, baos);\r
+      if (httpResponse.getStatusCode()==200) {\r
+        response.append(baos.toString("UTF-8"));  \r
+      } else {\r
+        String resp = baos.toString("UTF-8");\r
+        throw new Pazpar2ErrorException(resp,httpResponse.getStatusCode(),resp,null);\r
+      }       \r
       long end = System.currentTimeMillis();      \r
       logger.debug("Executed " + command.getName() + " in " + (end-start) + " ms." );\r
     } catch (IOException e) {\r
-      response.append(ApplicationError.createErrorXml(command.getName(), "io", e.getMessage())); \r
+      response.append(CommandError.createErrorXml(command.getName(), "io", e.getMessage())); \r
       logger.error(response.toString());\r
     } catch (Pazpar2ErrorException e) {\r
-      response.append(ApplicationError.createErrorXml(command.getName(), "pazpar2error", e.getMessage())); \r
+      response.append(CommandError.createErrorXml(command.getName(), "pazpar2error", e.getMessage())); \r
       logger.error(response.toString());\r
+    } catch (Exception e) {\r
+      response.append(CommandError.createErrorXml(command.getName(), "general", e.getMessage())); \r
+      logger.error(response.toString());      \r
     }\r
   }\r
   \r
index abab426..dcf75a7 100644 (file)
@@ -12,7 +12,7 @@ import org.apache.log4j.Logger;
 \r
 import com.indexdata.pz2utils4jsf.config.Pz2Configurator;\r
 import com.indexdata.pz2utils4jsf.controls.ResultsPager;\r
-import com.indexdata.pz2utils4jsf.pazpar2.data.ApplicationError;\r
+import com.indexdata.pz2utils4jsf.errors.ApplicationError;\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
@@ -278,9 +278,22 @@ public class Pz2Bean implements Pz2Interface, Serializable {
     return pz2.hasErrors();\r
   }\r
     \r
-  public ApplicationError getOneError() {\r
-    return pz2.getOneError();\r
+  public ApplicationError getCommandError() {\r
+    return pz2.getCommandError();\r
   }\r
   \r
+  public List<ApplicationError> getConfigurationErrors () {\r
+    return pz2.getConfigurationErrors();\r
+  }\r
+\r
+  @Override\r
+  public boolean hasCommandErrors() {\r
+    return pz2.hasCommandErrors();\r
+  }\r
+\r
+  @Override\r
+  public boolean hasConfigurationErrors() {\r
+    return pz2.hasConfigurationErrors();\r
+  }\r
 \r
 }\r
index d7fb64c..3de5b68 100644 (file)
@@ -4,8 +4,7 @@ import java.io.Serializable;
 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.ApplicationError;\r
+import com.indexdata.pz2utils4jsf.errors.ApplicationError;\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
@@ -300,8 +299,38 @@ public interface Pz2Interface extends Serializable {
    */\r
   public void setCurrentStateKey(String key);\r
   \r
+  /** \r
+   * @return true if any errors encountered so far\r
+   */\r
   public boolean hasErrors();\r
-      \r
-  public ApplicationError getOneError();\r
+  \r
+  /**\r
+   * \r
+   * @return true if errors encountered during execution of commands\r
+   */\r
+  public boolean hasCommandErrors();\r
+  \r
+  /**\r
+   * \r
+   * @return true if errors encountered when configuring the service\r
+   */\r
+  public boolean hasConfigurationErrors();\r
+  \r
+  /**\r
+   * Returns one (of possibly multiple) errors encountered during execution of commands\r
+   * Will prefer to show the search errors - if any - as the search command is usually \r
+   * executed first.  \r
+   * \r
+   * @return\r
+   */\r
+  public ApplicationError getCommandError();\r
+  \r
+  /**\r
+   * Returns all errors encountered during configuration of the application, in particular\r
+   * the Pazpar2 client. \r
+   * \r
+   * @return\r
+   */\r
+  public List<ApplicationError> getConfigurationErrors();\r
    \r
 }\r
index 74980bc..cae075f 100644 (file)
@@ -12,10 +12,16 @@ import javax.inject.Named;
 \r
 import org.apache.log4j.Logger;\r
 \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.Pz2Configurator;\r
 import com.indexdata.pz2utils4jsf.controls.ResultsPager;\r
-import com.indexdata.pz2utils4jsf.pazpar2.data.ApplicationError;\r
+import com.indexdata.pz2utils4jsf.errors.ApplicationError;\r
+import com.indexdata.pz2utils4jsf.errors.ErrorHelper;\r
+import com.indexdata.pz2utils4jsf.errors.ConfigurationError;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.CommandError;\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
@@ -37,11 +43,12 @@ public class Pz2Session implements Pz2Interface {
   private QueryStates queryStates = new QueryStates();\r
   \r
   private static final long serialVersionUID = 3947514708343320514L;  \r
-  private com.indexdata.masterkey.pazpar2.client.Pazpar2ClientConfiguration cfg = null;\r
-  private com.indexdata.masterkey.pazpar2.client.Pazpar2Client client = null;   \r
+  private Pazpar2ClientConfiguration cfg = null;\r
+  private Pazpar2Client client = null;   \r
   private TargetFilter targetFilter = null;  \r
   private ResultsPager pager = null; \r
-  private ApplicationTroubleshooter errorHelper = null;\r
+  private ErrorHelper errorHelper = null;\r
+  private List<ApplicationError> configurationErrors = null;\r
   \r
   public Pz2Session () {\r
     logger.info("Instantiating pz2 session object [" + Utils.objectId(this) + "]");      \r
@@ -49,17 +56,26 @@ public class Pz2Session implements Pz2Interface {
     \r
   public void init(Pz2Configurator pz2conf) {\r
     if (client==null) {\r
+      configurationErrors = new ArrayList<ApplicationError>();\r
+      errorHelper = new ErrorHelper(pz2conf);\r
       logger.info(Utils.objectId(this) + " is configuring itself using the provided " + Utils.objectId(pz2conf));\r
       try {\r
-        cfg = new com.indexdata.masterkey.pazpar2.client.Pazpar2ClientConfiguration(pz2conf.getConfig());\r
-        client = new com.indexdata.masterkey.pazpar2.client.Pazpar2ClientGeneric(cfg);\r
-        errorHelper = new ApplicationTroubleshooter(pz2conf);        \r
-        resetDataObjects();\r
-      } catch (ProxyErrorException e) {\r
-        e.printStackTrace();\r
-      } catch (IOException ioe) {\r
-        ioe.printStackTrace();\r
+        cfg = new Pazpar2ClientConfiguration(pz2conf.getConfig());\r
+      } catch (ProxyErrorException pe) {\r
+        logger.error("Could not configure Pazpar2 client: " + pe.getMessage());\r
+        configurationErrors.add(new ConfigurationError("Pz2Client Config","ProxyError","Could not configure Pazpar2 client: " + pe.getMessage(),errorHelper));\r
+      } catch (IOException io) {\r
+        logger.error("Could not configure Pazpar2 client: " + io.getMessage());\r
+        configurationErrors.add(new ConfigurationError("Pz2Client Config","ProxyError","Could not configure Pazpar2 client: " + io.getMessage(),errorHelper));\r
       }\r
+      try {\r
+        client = new Pazpar2ClientGeneric(cfg);     \r
+      } catch (ProxyErrorException pe) {\r
+        logger.error("Could not instantiate Pazpar2 client: " + pe.getMessage());\r
+        configurationErrors.add(new ConfigurationError("Pz2Client","ProxyError","Could not create Pazpar2 client: " +pe.getMessage(),errorHelper));                \r
+      } \r
+      logger.info("Got " + configurationErrors.size() + " configuration errors");\r
+      resetDataObjects();\r
     } else {\r
       logger.warn("Attempt to configure session but it already has a configured client");\r
     }\r
@@ -95,33 +111,42 @@ public class Pz2Session implements Pz2Interface {
    * @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
+    if (! hasConfigurationErrors()) {\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
+           String commandName = thread.getCommand().getName();\r
+           Pazpar2ResponseData responseObject = Pazpar2ResponseParser.getParser().getDataObject(thread.getResponse());\r
+           dataObjects.put(commandName, responseObject);        \r
+        }\r
+        return getActiveClients();\r
+      } else {\r
+        logger.debug("Skipped requests for " + commands + " as there's not yet a query."); \r
+        resetDataObjects();\r
+        return "0";\r
       }\r
-      for (CommandThread thread : threadList) {\r
-         String commandName = thread.getCommand().getName();\r
-         Pazpar2ResponseData responseObject = Pazpar2ResponseParser.getParser().getDataObject(thread.getResponse());\r
-         dataObjects.put(commandName, responseObject);        \r
-      }\r
-      return getActiveClients();\r
     } else {\r
-      logger.debug("Skipped requests for " + commands + " as there's not yet a query."); \r
-      resetDataObjects();\r
+      configurationErrors.add(\r
+          new ConfigurationError("Querying while errors",\r
+                                 "App halted",\r
+                                 "Cannot query Pazpar2 while there are configuration errors.",\r
+                                 errorHelper));\r
       return "0";\r
     }\r
     \r
@@ -273,10 +298,11 @@ public class Pz2Session implements Pz2Interface {
     queryStates.setCurrentStateKey(key);\r
   }\r
   \r
-  /**\r
-   * Returns true if application error found in any response data objects \r
-   */\r
-  public boolean hasErrors () {\r
+  public boolean hasConfigurationErrors () {\r
+      return (configurationErrors.size()>0);      \r
+  }\r
+  \r
+  public boolean hasCommandErrors () {\r
     if (dataObjects.get("search").hasApplicationError()) {\r
       logger.info("Error detected in search");\r
       return true;\r
@@ -287,17 +313,28 @@ public class Pz2Session implements Pz2Interface {
         return true;\r
       }\r
     }    \r
-    return false;\r
+    return false;    \r
+  }\r
+  \r
+  /**\r
+   * Returns true if application error found in any response data objects \r
+   */\r
+  public boolean hasErrors () {\r
+    return hasConfigurationErrors() || hasCommandErrors();\r
   }\r
 \r
+  public List<ApplicationError> getConfigurationErrors() {\r
+    logger.info("Returning " + configurationErrors.size() + " configuration errors");\r
+    return configurationErrors;\r
+  }\r
   \r
   /**\r
    * Returns a search command error, if any, otherwise the first\r
    * error found for an arbitrary command, if any, otherwise\r
    * an empty dummy error. \r
    */    \r
-  public ApplicationError getOneError() {\r
-    ApplicationError error = new ApplicationError();    \r
+  public ApplicationError getCommandError() {\r
+    CommandError error = new CommandError();    \r
     if (dataObjects.get("search").hasApplicationError()) {\r
       error = dataObjects.get("search").getApplicationError();                        \r
     } else {\r
@@ -308,7 +345,7 @@ public class Pz2Session implements Pz2Interface {
         } \r
       }\r
     }\r
-    error.setTroubleshooter(errorHelper);\r
+    error.setErrorHelper(errorHelper);\r
     return error;         \r
   }\r
 \r
@@ -339,7 +376,7 @@ public class Pz2Session implements Pz2Interface {
     return pager;\r
   }\r
   \r
-  protected ApplicationTroubleshooter getTroubleshooter() {\r
+  protected ErrorHelper getTroubleshooter() {\r
     return errorHelper;\r
   }\r
   \r
@@ -421,10 +458,10 @@ public class Pz2Session implements Pz2Interface {
     return defaultValue;    \r
   }\r
 \r
-  private String doCommand(String commandName) {\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
+    return update(commandName);      \r
   }\r
   \r
   private void resetDataObjects() {\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/ApplicationError.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/ApplicationError.java
deleted file mode 100644 (file)
index 5e95712..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.indexdata.pz2utils4jsf.pazpar2.data;\r
-\r
-import static com.indexdata.pz2utils4jsf.utils.Utils.nl;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import com.indexdata.pz2utils4jsf.pazpar2.ApplicationTroubleshooter;\r
-import com.indexdata.utils.XmlUtils;\r
-\r
-public class ApplicationError extends Pazpar2ResponseData {\r
-\r
-  private static final long serialVersionUID = 8878776025779714122L;\r
-  private ApplicationTroubleshooter errorHelper = null;\r
-  \r
-  \r
-  public ApplicationError () {    \r
-  }\r
-  \r
-  public String getCommandName() {\r
-    return getOneElementValue("commandname");\r
-  }\r
-      \r
-  public String getErrorMessage() {\r
-    return getOneElementValue("errormessage");\r
-  }\r
-    \r
-  public String getException () {\r
-    return getOneElementValue("exception");\r
-  }\r
-    \r
-  public List<String> getSuggestions() { \r
-    if (errorHelper!=null) {\r
-      return errorHelper.getSuggestions(getCommandName(), getErrorMessage());\r
-    } else {\r
-      List<String> nohelper = new ArrayList<String>();\r
-      nohelper.add("Tips: could not generate tips due to a programming error, error helper was not set");\r
-      return nohelper;\r
-    }\r
-  }\r
-  \r
-  /**\r
-   * Creates an XML string error message, embedded in an XML string document named by the command\r
-   * @param commandName\r
-   * @param exceptionName\r
-   * @param errorMessage\r
-   * @return\r
-   */\r
-  public static String createErrorXml (String commandName, String exceptionName, String errorMessage) {\r
-    StringBuilder errorXml = new StringBuilder("");\r
-    errorXml.append("<" + commandName + ">"+nl);\r
-    errorXml.append(" <applicationerror>"+nl);\r
-    errorXml.append("  <commandname>" + commandName + "</commandname>");\r
-    errorXml.append("  <exception>" + XmlUtils.escape(exceptionName) + "</exception>"+nl);    \r
-    errorXml.append("  <errormessage>" + XmlUtils.escape(errorMessage) + "</errormessage>"+nl);\r
-    errorXml.append(" </applicationerror>"+nl);\r
-    errorXml.append("</" + commandName + ">"+nl);\r
-    return errorXml.toString(); \r
-  }\r
-  \r
-  public void setTroubleshooter (ApplicationTroubleshooter errorHelper) {\r
-    this.errorHelper = errorHelper; \r
-  }\r
-\r
-}\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/CommandError.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/CommandError.java
new file mode 100644 (file)
index 0000000..2421f38
--- /dev/null
@@ -0,0 +1,86 @@
+package com.indexdata.pz2utils4jsf.pazpar2.data;\r
+\r
+import static com.indexdata.pz2utils4jsf.utils.Utils.nl;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import com.indexdata.pz2utils4jsf.errors.ApplicationError;\r
+import com.indexdata.pz2utils4jsf.errors.ErrorHelper;\r
+import com.indexdata.pz2utils4jsf.errors.ErrorHelper.ErrorCode;\r
+import com.indexdata.utils.XmlUtils;\r
+\r
+/**\r
+ * Captures errors encountered during the execution of a command. \r
+ * Is parsed by Pazpar2ResponseParser, piggybacked in a (seemingly)\r
+ * regular command respond.\r
+ * \r
+ * @author Niels Erik\r
+ *\r
+ */\r
+public class CommandError extends Pazpar2ResponseData implements ApplicationError {\r
+\r
+  private static final long serialVersionUID = 8878776025779714122L;\r
+  private ErrorCode applicationErrorCode;\r
+  private ErrorHelper errorHelper = null;\r
+  \r
+  \r
+  public CommandError () {    \r
+  }\r
+  \r
+  public String getLabel() {\r
+    return getOneElementValue("commandname");\r
+  }\r
+      \r
+  public String getMessage() {\r
+    return getOneElementValue("errormessage");\r
+  }\r
+    \r
+  public String getException () {\r
+    return getOneElementValue("exception");\r
+  }\r
+    \r
+  public List<String> getSuggestions() { \r
+    if (errorHelper!=null) {\r
+      return errorHelper.getSuggestions(this);\r
+    } else {\r
+      List<String> nohelper = new ArrayList<String>();\r
+      nohelper.add("Tips: could not generate tips due to a programming error, error helper was not set");\r
+      return nohelper;\r
+    }\r
+  }\r
+  \r
+  /**\r
+   * Creates an XML string error message, embedded in an XML string document named by the command\r
+   * @param commandName\r
+   * @param exceptionName\r
+   * @param errorMessage\r
+   * @return\r
+   */\r
+  public static String createErrorXml (String commandName, String exceptionName, String errorMessage) {\r
+    StringBuilder errorXml = new StringBuilder("");\r
+    errorXml.append("<" + commandName + ">"+nl);\r
+    errorXml.append(" <applicationerror>"+nl);\r
+    errorXml.append("  <commandname>" + commandName + "</commandname>"+nl);\r
+    errorXml.append("  <exception>" + XmlUtils.escape(exceptionName) + "</exception>"+nl);    \r
+    errorXml.append("  <errormessage>" + XmlUtils.escape(errorMessage) + "</errormessage>"+nl);    \r
+    errorXml.append(" </applicationerror>"+nl);\r
+    errorXml.append("</" + commandName + ">"+nl);\r
+    return errorXml.toString(); \r
+  }\r
+  \r
+  public void setErrorHelper (ErrorHelper errorHelper) {\r
+    this.errorHelper = errorHelper; \r
+  }\r
+\r
+  @Override\r
+  public void setApplicationErrorCode(ErrorCode code) {\r
+    this.applicationErrorCode = code;    \r
+  }\r
+\r
+  @Override\r
+  public ErrorCode getApplicationErrorCode() {\r
+    return applicationErrorCode;    \r
+  }\r
+\r
+}\r
index 8be2d24..d6ee2bb 100644 (file)
@@ -14,7 +14,7 @@ public class Pazpar2ResponseData implements Serializable {
   HashMap<String,String> attributes = new HashMap<String,String>();\r
   HashMap<String,List<Pazpar2ResponseData>> elements = new HashMap<String,List<Pazpar2ResponseData>>();\r
   String textContent = "";\r
-  ApplicationError error = null;\r
+  CommandError error = null;\r
         \r
   public void setType (String type) {\r
     this.type = type;\r
@@ -98,8 +98,8 @@ public class Pazpar2ResponseData implements Serializable {
     return (getOneElement("applicationerror") != null);   \r
   }\r
   \r
-  public ApplicationError getApplicationError() {\r
-    return (ApplicationError) getOneElement("applicationerror");\r
+  public CommandError getApplicationError() {\r
+    return (CommandError) getOneElement("applicationerror");\r
   }\r
   \r
   \r
index 40cf412..2e0ef39 100644 (file)
@@ -72,17 +72,17 @@ public class Pazpar2ResponseParser extends DefaultHandler {
    * @return Response data object\r
    */\r
   public Pazpar2ResponseData getDataObject (String response) {\r
-    try {\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
+      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
+      e.printStackTrace();      \r
     }\r
     return result;\r
   }\r
@@ -123,7 +123,7 @@ public class Pazpar2ResponseParser extends DefaultHandler {
     } else if (localName.equals("search")) {\r
       currentElement = new SearchResponse();\r
     } else if (localName.equals("applicationerror")) {\r
-      currentElement = new ApplicationError();\r
+      currentElement = new CommandError();\r
     } else {\r
       currentElement = new Pazpar2ResponseData();\r
     }\r