Work on error reporting. Adds troubleshooter.
authorNiels Erik G. Nielsen <nielserik@indexdata.com>
Fri, 8 Mar 2013 17:44:32 +0000 (12:44 -0500)
committerNiels Erik G. Nielsen <nielserik@indexdata.com>
Fri, 8 Mar 2013 17:44:32 +0000 (12:44 -0500)
14 files changed:
src/META-INF/resources/pz2utils/pz2watch.xhtml
src/main/java/com/indexdata/pz2utils4jsf/config/Pz2Configurator.java
src/main/java/com/indexdata/pz2utils4jsf/config/Pz2ConfigureByMk2Config.java
src/main/java/com/indexdata/pz2utils4jsf/config/Pz2ConfigureByWebXml.java
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/ApplicationTroubleshooter.java [new file with mode: 0644]
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 [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Pazpar2ErrorResponse.java [deleted file]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Pazpar2ResponseData.java
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Pazpar2ResponseParser.java
src/main/java/com/indexdata/pz2utils4jsf/utils/Utils.java

index bfa2b3b..dfa628d 100644 (file)
     <h:form id="activeclientsForm" prependId="false">\r
       <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() ? 'color: red;' : 'display: none;'}">\r
-        <p><h:outputText id="messages" value="Error: #{pz2.firstErrorMessage}"/></p>\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:panelGrid>                      \r
     </h:form>\r
 \r
index 88b275d..b4e8eab 100644 (file)
@@ -2,7 +2,10 @@ package com.indexdata.pz2utils4jsf.config;
 \r
 import java.io.IOException;\r
 import java.io.Serializable;\r
+import java.util.List;\r
 \r
 public interface Pz2Configurator extends Serializable {\r
   public Pz2Config getConfig() throws IOException;\r
+  \r
+  public List<String> document();\r
 }\r
index 2273b7a..f10aa1e 100644 (file)
@@ -1,6 +1,8 @@
 package com.indexdata.pz2utils4jsf.config;\r
 \r
 import java.io.IOException;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
 \r
 import javax.enterprise.context.SessionScoped;\r
 import javax.enterprise.inject.Alternative;\r
@@ -16,6 +18,8 @@ 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
@@ -43,21 +47,28 @@ public class Pz2ConfigureByMk2Config implements Pz2Configurator  {
         "pazpar-application-jsf", ((HttpServletRequest) externalContext.getRequest()).getServerName());\r
     ModuleConfiguration moduleConfig = mkConfigContext.getModuleConfiguration("pz2client");\r
     pz2config = new Pz2Config(moduleConfig);\r
-    logger.info("Accessing Pazpar2 at: " +pz2config.get("PAZPAR2_URL"));\r
+    logger.info(document());\r
+  }\r
+  \r
+\r
+  public List<String> document() {\r
+    List<String> doc = new ArrayList<String>();\r
+    \r
+    doc.add("Set to access Pazpar2 at: " +pz2config.get("PAZPAR2_URL"));\r
     if (pz2config.get("PAZPAR2_SERVICE_XML") != null) {\r
-      logger.info("Using the service definition contained in " + pz2config.getConfigFilePath() + "/" + pz2config.get("PAZPAR2_SERVICE_XML"));\r
+      doc.add("Set to use the service definition contained in " + pz2config.getConfigFilePath() + "/" + pz2config.get("PAZPAR2_SERVICE_XML"));\r
       if (pz2config.get("PAZPAR2_SETTINGS_XML") != null) {\r
-        logger.info("Using the target settings contained in " + pz2config.getConfigFilePath() + "/" + pz2config.get("PAZPAR2_SETTINGS_XML"));\r
+        doc.add("Set to use the target settings contained in " + pz2config.getConfigFilePath() + "/" + pz2config.get("PAZPAR2_SETTINGS_XML"));\r
       } else {\r
-        logger.info("Using the server side target settings as defined in the service definition.");\r
+        doc.add("Set to use the server side target settings as defined in the service definition.");\r
       }\r
     } else if (pz2config.get("PAZPAR2_SERVICE_ID") != null) {\r
-      logger.info("Using the server side service definition identified by service id "+pz2config.get("PAZPAR2_SERVICE_ID"));\r
+      doc.add("Set to use the server side service definition identified by service id "+pz2config.get("PAZPAR2_SERVICE_ID"));\r
     } else {\r
-      logger.error("Did not find service ID nor service definition XML file so set up pazpar2 service.");\r
+      doc.add("Error: Did not find service ID nor service definition XML file to set up pazpar2 service.");\r
     }\r
-\r
+    return doc;\r
   }\r
-  \r
+    \r
 \r
 }\r
index d131e94..ff38ae7 100644 (file)
@@ -1,7 +1,9 @@
 package com.indexdata.pz2utils4jsf.config;\r
 \r
 import java.io.IOException;\r
+import java.util.ArrayList;\r
 import java.util.HashMap;\r
+import java.util.List;\r
 import java.util.Map;\r
 \r
 import javax.enterprise.context.SessionScoped;\r
@@ -40,4 +42,10 @@ public class Pz2ConfigureByWebXml implements Pz2Configurator {
     parameters.put("PAZPAR2_SERVICE_ID", servletContext.getInitParameter("PAZPAR2_SERVICE_ID"));\r
     pz2config = new Pz2Config(parameters);    \r
   }\r
+  \r
+  public List<String> document() {\r
+    List<String> doc = new ArrayList<String>();\r
+    doc.add("No documentation written yet for this configurator");\r
+    return doc;\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
new file mode 100644 (file)
index 0000000..a30bc54
--- /dev/null
@@ -0,0 +1,53 @@
+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 5764777..50ec2b6 100644 (file)
@@ -5,12 +5,10 @@ import java.io.IOException;
 \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.utils.XmlUtils;\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
+import com.indexdata.pz2utils4jsf.pazpar2.data.ApplicationError;\r
 \r
 public class CommandThread extends Thread {\r
 \r
@@ -25,6 +23,16 @@ public class CommandThread extends Thread {
     this.client = client;\r
   }\r
   \r
+  /**\r
+   * Runs the specified command using the specified Pazpar2 client\r
+   * Sets the Pazpar2 response as an XML response string to be retrieved by\r
+   * getResponse().\r
+   * \r
+   * In case of an exception, an error response is generated, the document\r
+   * element being the same as it would have been if successful (named after\r
+   * the command, that is).  \r
+   *  \r
+   */\r
   public void run() {\r
     ClientCommand clientCommand = new ClientCommand(command.getName(), command.getEncodedQueryString());\r
     if (command.getName().equals("search")) {\r
@@ -37,20 +45,22 @@ public class CommandThread extends Thread {
       long end = System.currentTimeMillis();      \r
       logger.debug("Executed " + command.getName() + " in " + (end-start) + " ms." );\r
     } catch (IOException e) {\r
-      logger.error("Message: " + e.getMessage());      \r
-      response = new StringBuilder("<"+command.getName()+"><error exception=\"io\">"+XmlUtils.escape(e.getMessage())+"</error></"+command.getName()+">");\r
+      response.append(ApplicationError.createErrorXml(command.getName(), "io", e.getMessage())); \r
       logger.error(response.toString());\r
     } catch (Pazpar2ErrorException e) {\r
-      logger.error(e.getMessage());\r
-      response = new StringBuilder("<"+command.getName()+"><error exception=\"pazpar2error\">"+XmlUtils.escape(e.getMessage())+"</error></"+command.getName()+">");      \r
+      response.append(ApplicationError.createErrorXml(command.getName(), "pazpar2error", e.getMessage())); \r
       logger.error(response.toString());\r
     }\r
   }\r
   \r
+  /**\r
+   * \r
+   * @return Pazpar2 response as an XML string, possibly a generated error XML\r
+   */\r
   public String getResponse () {\r
     return response.toString();\r
   }\r
-  \r
+    \r
   public Pazpar2Command getCommand() {\r
     return command;\r
   }\r
index 6abdb34..abab426 100644 (file)
@@ -12,6 +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.pazpar2.data.ByTarget;\r
 import com.indexdata.pz2utils4jsf.pazpar2.data.RecordResponse;\r
 import com.indexdata.pz2utils4jsf.pazpar2.data.ShowResponse;\r
@@ -276,13 +277,9 @@ public class Pz2Bean implements Pz2Interface, Serializable {
   public boolean hasErrors() {\r
     return pz2.hasErrors();\r
   }\r
-  \r
-  public String getErrorMessages() {\r
-    return pz2.getErrorMessages();\r
-  }\r
-  \r
-  public String getFirstErrorMessage() {\r
-    return pz2.getFirstErrorMessage();\r
+    \r
+  public ApplicationError getOneError() {\r
+    return pz2.getOneError();\r
   }\r
   \r
 \r
index b69b4e2..d7fb64c 100644 (file)
@@ -5,6 +5,7 @@ import java.util.List;
 \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.pazpar2.data.ByTarget;\r
 import com.indexdata.pz2utils4jsf.pazpar2.data.RecordResponse;\r
 import com.indexdata.pz2utils4jsf.pazpar2.data.ShowResponse;\r
@@ -300,9 +301,7 @@ public interface Pz2Interface extends Serializable {
   public void setCurrentStateKey(String key);\r
   \r
   public boolean hasErrors();\r
-  \r
-  public String getErrorMessages();\r
-  \r
-  public String getFirstErrorMessage();\r
+      \r
+  public ApplicationError getOneError();\r
    \r
 }\r
index 822b416..74980bc 100644 (file)
@@ -15,6 +15,7 @@ import org.apache.log4j.Logger;
 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.pazpar2.data.ByTarget;\r
 import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseData;\r
 import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2ResponseParser;\r
@@ -40,7 +41,8 @@ public class Pz2Session implements Pz2Interface {
   private com.indexdata.masterkey.pazpar2.client.Pazpar2Client client = null;   \r
   private TargetFilter targetFilter = null;  \r
   private ResultsPager pager = null; \r
-      \r
+  private ApplicationTroubleshooter errorHelper = null;\r
+  \r
   public Pz2Session () {\r
     logger.info("Instantiating pz2 session object [" + Utils.objectId(this) + "]");      \r
   }\r
@@ -48,15 +50,16 @@ public class Pz2Session implements Pz2Interface {
   public void init(Pz2Configurator pz2conf) {\r
     if (client==null) {\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
-      resetDataObjects();\r
-    } catch (ProxyErrorException e) {\r
-      e.printStackTrace();\r
-    } catch (IOException ioe) {\r
-      ioe.printStackTrace();\r
-    }\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
+      }\r
     } else {\r
       logger.warn("Attempt to configure session but it already has a configured client");\r
     }\r
@@ -111,7 +114,9 @@ public class Pz2Session implements Pz2Interface {
         }\r
       }\r
       for (CommandThread thread : threadList) {\r
-         dataObjects.put(thread.getCommand().getName(), new Pazpar2ResponseParser().getObject(thread.getResponse()));        \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
@@ -268,41 +273,43 @@ 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
-    if (dataObjects.get("search").isError()) {\r
+    if (dataObjects.get("search").hasApplicationError()) {\r
       logger.info("Error detected in search");\r
       return true;\r
     }\r
     for (String name : dataObjects.keySet()) {\r
-      if (dataObjects.get(name).isError()) {\r
+      if (dataObjects.get(name).hasApplicationError()) {\r
         logger.info("Error detected in " + name);\r
         return true;\r
       }\r
     }    \r
     return false;\r
   }\r
-    \r
-  public String getErrorMessages() {\r
-    StringBuilder msgs = new StringBuilder("");\r
-    for (String name : dataObjects.keySet()) {     \r
-      if (dataObjects.get(name).isError()) {     \r
-        msgs.append(name + ": " + dataObjects.get(name).getErrorMessage());\r
-      } \r
-    }\r
-    return msgs.toString();\r
-  }\r
+\r
   \r
-  public String getFirstErrorMessage() {\r
-    if (dataObjects.get("search").isError()) {\r
-      return "Error doing search: " + dataObjects.get("search").getErrorMessage();\r
-    }\r
-    for (String name : dataObjects.keySet()) {     \r
-      if (dataObjects.get(name).isError()) {     \r
-        return name + ": " + dataObjects.get(name).getErrorMessage();        \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
+    if (dataObjects.get("search").hasApplicationError()) {\r
+      error = dataObjects.get("search").getApplicationError();                        \r
+    } else {\r
+      for (String name : dataObjects.keySet()) {     \r
+        if (dataObjects.get(name).hasApplicationError()) {     \r
+          error = dataObjects.get(name).getApplicationError(); \r
+          break;\r
+        } \r
+      }\r
     }\r
-    return "";\r
-    \r
+    error.setTroubleshooter(errorHelper);\r
+    return error;         \r
   }\r
 \r
     \r
@@ -332,6 +339,10 @@ public class Pz2Session implements Pz2Interface {
     return pager;\r
   }\r
   \r
+  protected ApplicationTroubleshooter getTroubleshooter() {\r
+    return errorHelper;\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
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/ApplicationError.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/ApplicationError.java
new file mode 100644 (file)
index 0000000..5e95712
--- /dev/null
@@ -0,0 +1,65 @@
+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/Pazpar2ErrorResponse.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Pazpar2ErrorResponse.java
deleted file mode 100644 (file)
index ff6a530..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.indexdata.pz2utils4jsf.pazpar2.data;\r
-\r
-public class Pazpar2ErrorResponse extends Pazpar2ResponseData {\r
-\r
-  private static final long serialVersionUID = 5261091417784893149L;\r
-\r
-}\r
index a01ca76..8be2d24 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
-  String errorText = null;\r
+  ApplicationError error = null;\r
         \r
   public void setType (String type) {\r
     this.type = type;\r
@@ -54,6 +54,12 @@ public class Pazpar2ResponseData implements Serializable {
     }\r
   }\r
   \r
+  /**\r
+   * Returns the text content of the first element found with the given\r
+   * name\r
+   * @param name of the element \r
+   * @return text value, empty string if none found\r
+   */\r
   public String getOneElementValue (String name) {\r
     if (getOneElement(name)!=null && getOneElement(name).getValue().length()>0) {\r
       return getOneElement(name).getValue();\r
@@ -88,13 +94,15 @@ public class Pazpar2ResponseData implements Serializable {
     }\r
   }\r
     \r
-  public boolean isError () {\r
-    return (getOneElement("error") != null);   \r
+  public boolean hasApplicationError () {\r
+    return (getOneElement("applicationerror") != null);   \r
   }\r
   \r
-  public String getErrorMessage() {\r
-    return getOneElementValue("error");\r
+  public ApplicationError getApplicationError() {\r
+    return (ApplicationError) getOneElement("applicationerror");\r
   }\r
-\r
+  \r
+  \r
+  \r
       \r
 }\r
index c4a4d11..40cf412 100644 (file)
@@ -52,6 +52,10 @@ public class Pazpar2ResponseParser extends DefaultHandler {
     }\r
   }\r
   \r
+  public static Pazpar2ResponseParser getParser() {\r
+    return new Pazpar2ResponseParser();\r
+  }\r
+  \r
   private void initSax() throws ParserConfigurationException, SAXException {\r
     SAXParserFactory spf = SAXParserFactory.newInstance();\r
     spf.setNamespaceAware(true);\r
@@ -60,7 +64,14 @@ public class Pazpar2ResponseParser extends DefaultHandler {
     xmlReader.setContentHandler(this);         \r
   }\r
   \r
-  public Pazpar2ResponseData getObject (String response) {\r
+  /**\r
+   * Parses a Pazpar2 XML response -- or an error response as XML -- and produces a \r
+   * Pazpar2ResponseData object, i.e. a 'show' object\r
+   * \r
+   * @param response XML response string from Pazpar2\r
+   * @return Response data object\r
+   */\r
+  public Pazpar2ResponseData getDataObject (String response) {\r
     try {\r
       xmlReader.parse(new InputSource(new ByteArrayInputStream(response.getBytes("UTF-8"))));\r
     } catch (UnsupportedEncodingException e) {\r
@@ -111,6 +122,8 @@ public class Pazpar2ResponseParser extends DefaultHandler {
       currentElement = new RecordResponse();\r
     } else if (localName.equals("search")) {\r
       currentElement = new SearchResponse();\r
+    } else if (localName.equals("applicationerror")) {\r
+      currentElement = new ApplicationError();\r
     } else {\r
       currentElement = new Pazpar2ResponseData();\r
     }\r
index e17c224..5273134 100644 (file)
@@ -2,6 +2,8 @@ package com.indexdata.pz2utils4jsf.utils;
 \r
 public class Utils {\r
   \r
+  public static String nl = System.getProperty("line.separator");  \r
+\r
   public static String objectId(Object o) {\r
     int lastdot = o.toString().lastIndexOf('.');\r
     if (lastdot>-1 && lastdot+1<o.toString().length()) {\r
@@ -10,5 +12,13 @@ public class Utils {
       return o.toString();\r
     }\r
   }\r
-\r
+  \r
+  public static String baseObjectName(Object o) {\r
+    String objName = o.getClass().getName();\r
+    if (objName.contains("$")) {\r
+      return objectId(objName.substring(0,objName.indexOf("$")));      \r
+    } else {\r
+      return objectId(objName);\r
+    }\r
+  }\r
 }\r