changeset 665:27f25b9ae9af

Improved exception handling. Display error messages after invalid user input. gnv/trunk@758 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Wed, 10 Mar 2010 13:41:53 +0000
parents 15497dce8fcd
children bb7df90fcb74
files gnv/ChangeLog gnv/src/main/java/de/intevation/gnv/action/CommunicationKeys.java gnv/src/main/java/de/intevation/gnv/action/FetchArtifactFactoriesAction.java gnv/src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/exception/ArtifactDatabaseInputException.java gnv/src/main/webapp/WEB-INF/jsp/index.jsp gnv/src/main/webapp/styles/default.css
diffstat 9 files changed, 205 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/gnv/ChangeLog	Tue Mar 09 15:29:44 2010 +0000
+++ b/gnv/ChangeLog	Wed Mar 10 13:41:53 2010 +0000
@@ -1,3 +1,29 @@
+2010-03-10  Ingo Weinzierl <ingo.weinzierl@intevation.de>
+
+	* src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java,
+	  src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java:
+	  Throw different exceptions if an error occured in the artifact server.
+	  On this way, we are able to distinguish between general server errors or
+	  errors caused by an invalid user input.
+
+	* src/main/java/de/intevation/gnv/action/FetchArtifactFactoriesAction.java,
+	  src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java:
+	  Catch the exceptions thrown by DefaultArtifactDatabaseClient and set an 
+	  attribute at the request object for each exception type. The attributes 
+	  will take effect on different places in the user interface.
+
+	* src/main/java/de/intevation/gnv/artifactdatabase/client/exception/ArtifactDatabaseInputException.java:
+	  Exception used to be thrown if an invalid user input error occured.
+
+	* src/main/java/de/intevation/gnv/action/CommunicationKeys.java: Added some
+	  keys to store different error messages in the Http session.
+
+	* src/main/webapp/styles/default.css: Added new style class to adjust the
+	  style of error messages caused by invalid user input.
+
+	* src/main/webapp/WEB-INF/jsp/index.jsp: Display invalid input errors at
+	  the top of the input area.
+
 2010-03-09  Ingo Weinzierl <ingo.weinzierl@intevation.de>
 
 	* src/main/webapp/WEB-INF/config/log4j.properties,
--- a/gnv/src/main/java/de/intevation/gnv/action/CommunicationKeys.java	Tue Mar 09 15:29:44 2010 +0000
+++ b/gnv/src/main/java/de/intevation/gnv/action/CommunicationKeys.java	Wed Mar 10 13:41:53 2010 +0000
@@ -10,6 +10,7 @@
      * The Key which should be used for accessing ExceptionMessages
      */
     public final static String REQUEST_EXCEPTION_MESSAGE_ID = "request_exception_message_id";
+    public final static String REQUEST_EXCEPTION_INPUT_ID   = "request_exception_input_id";
     public final static String REQUEST_EXCEPTION_MESSAGE    = "request_exception_message";
     public final static String REQUEST_EXCEPTION_VALUE      = "request_exception_value";
 }
--- a/gnv/src/main/java/de/intevation/gnv/action/FetchArtifactFactoriesAction.java	Tue Mar 09 15:29:44 2010 +0000
+++ b/gnv/src/main/java/de/intevation/gnv/action/FetchArtifactFactoriesAction.java	Wed Mar 10 13:41:53 2010 +0000
@@ -7,6 +7,8 @@
 import de.intevation.gnv.action.sessionmodel.SessionModelFactory;
 
 import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClientFactory;
+import de.intevation.gnv.artifactdatabase.client.exception.ArtifactDatabaseClientException;
+import de.intevation.gnv.artifactdatabase.client.exception.ArtifactDatabaseInputException;
 
 import de.intevation.gnv.artifactdatabase.objects.ArtifactObject;
 
@@ -61,6 +63,14 @@
 
             return super.execute(mapping, form, request, response);
         }
+        catch (ArtifactDatabaseClientException e) {
+            log.error(e, e);
+            request.setAttribute(
+                CommunicationKeys.REQUEST_EXCEPTION_INPUT_ID,
+                e.getMessage());
+
+            return super.getExceptionForward(mapping);
+        }
         catch (Exception e) {
             log.error(e, e);
             request.setAttribute(
--- a/gnv/src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java	Tue Mar 09 15:29:44 2010 +0000
+++ b/gnv/src/main/java/de/intevation/gnv/action/NextArtifactStepAction.java	Wed Mar 10 13:41:53 2010 +0000
@@ -7,6 +7,8 @@
 
 import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient;
 import de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClientFactory;
+import de.intevation.gnv.artifactdatabase.client.exception.ArtifactDatabaseClientException;
+import de.intevation.gnv.artifactdatabase.client.exception.ArtifactDatabaseInputException;
 
 import de.intevation.gnv.artifactdatabase.objects.ArtifactDescription;
 import de.intevation.gnv.artifactdatabase.objects.DefaultInputParameter;
@@ -99,11 +101,20 @@
                             target,
                             ips
                         );
-                    } catch (Exception e) {
+                    }
+                    catch (ArtifactDatabaseInputException e) {
+                        log.debug("================ CATCH ME ======================");
+                        log.debug("===== ERROR MSG: " + e.getMessage());
                         log.error(e, e);
                         request.setAttribute(
-                                CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID, e
-                                        .getMessage());
+                            CommunicationKeys.REQUEST_EXCEPTION_INPUT_ID,
+                            e.getMessage());
+                    }
+                    catch (Exception e) {
+                        log.error(e, e);
+                        request.setAttribute(
+                            CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID,
+                            e.getMessage());
                     }
     
                     Map tmpOuts = ad.getOutputModes();
@@ -121,7 +132,16 @@
                         
                         request.setAttribute("diagramm", true);
                         
-                    } catch (Exception e) {
+                    }
+                    catch (ArtifactDatabaseInputException e) {
+                        log.debug("================ CATCH ME ======================");
+                        log.debug("===== ERROR MSG: " + e.getMessage());
+                        log.error(e, e);
+                        request.setAttribute(
+                            CommunicationKeys.REQUEST_EXCEPTION_INPUT_ID,
+                            e.getMessage());
+                    }
+                    catch (Exception e) {
                         log.error(e, e);
                         request.setAttribute(
                             CommunicationKeys.REQUEST_EXCEPTION_MESSAGE_ID,
--- a/gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java	Tue Mar 09 15:29:44 2010 +0000
+++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/ArtifactDatabaseClient.java	Wed Mar 10 13:41:53 2010 +0000
@@ -8,6 +8,7 @@
 import org.w3c.dom.Document;
 
 import de.intevation.gnv.artifactdatabase.client.exception.ArtifactDatabaseClientException;
+import de.intevation.gnv.artifactdatabase.client.exception.ArtifactDatabaseInputException;
 import de.intevation.gnv.artifactdatabase.objects.ArtifactDescription;
 import de.intevation.gnv.artifactdatabase.objects.ArtifactObject;
 import de.intevation.gnv.artifactdatabase.objects.ArtifactStatisticsSet;
@@ -31,7 +32,7 @@
      * @throws ArtifactDatabaseClientException
      */
     public Collection<ArtifactObject> getArtifactFactories()
-                                                            throws ArtifactDatabaseClientException;
+    throws ArtifactDatabaseClientException, ArtifactDatabaseInputException;
 
     /**
      * 
@@ -40,7 +41,7 @@
      * @throws ArtifactDatabaseClientException
      */
     public ArtifactObject createNewArtifact(ArtifactObject artifactFactory)
-                                            throws ArtifactDatabaseClientException;
+    throws ArtifactDatabaseClientException, ArtifactDatabaseInputException;
 
     /**
      * 
@@ -49,10 +50,10 @@
      * @throws ArtifactDatabaseClientException
      */
     public ArtifactDescription getCurrentStepDescription(
-                                                         ArtifactObject artifactFactory,
-                                                         ArtifactObject currentArtifact,
-                                                         boolean includeUI)
-                                                         throws ArtifactDatabaseClientException;
+        ArtifactObject artifactFactory,
+        ArtifactObject currentArtifact,
+        boolean includeUI)
+    throws ArtifactDatabaseClientException, ArtifactDatabaseInputException;
 
     /**
      * 
@@ -64,17 +65,17 @@
      * @throws ArtifactDatabaseClientException
      */
     public ArtifactDescription doNextStep(
-                                          ArtifactObject artifactFactory,
-                                          ArtifactObject currentArtifact,
-                                          String target,
-                                          Collection<InputParameter> inputParameter)
-                                                                                    throws ArtifactDatabaseClientException;
+        ArtifactObject artifactFactory,
+        ArtifactObject currentArtifact,
+        String         target,
+        Collection<InputParameter> inputParameter)
+    throws ArtifactDatabaseClientException, ArtifactDatabaseInputException;
 
     public void doAdvance(
         ArtifactObject factory,
         ArtifactObject artifact,
-        String         target
-    ) throws IOException, ArtifactDatabaseClientException;
+        String         target)
+    throws IOException, ArtifactDatabaseClientException, ArtifactDatabaseInputException;
 
     /**
      * @param artifactFactory
@@ -84,9 +85,9 @@
      * @throws ArtifactDatabaseClientException
      */
     public void doFeed(ArtifactObject artifactFactory,
-                       ArtifactObject currentArtifact,
-                       Collection<InputParameter> inputParameter)
-                                                                 throws ArtifactDatabaseClientException;
+        ArtifactObject currentArtifact,
+        Collection<InputParameter> inputParameter)
+    throws ArtifactDatabaseClientException, ArtifactDatabaseInputException;
 
     /**
      * 
@@ -128,9 +129,10 @@
     
     public void setLocale(Locale locale);
     
-    public Collection<ArtifactObject> getArtifactFactoryMetaInformation(Collection<MapService> mapServices, 
-                                                  String geometry, 
-                                                  String srs)
-                                                  throws ArtifactDatabaseClientException;
+    public Collection<ArtifactObject> getArtifactFactoryMetaInformation(
+        Collection<MapService> mapServices, 
+        String                 geometry, 
+        String                 srs)
+    throws ArtifactDatabaseClientException, ArtifactDatabaseInputException;
     
 }
--- a/gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java	Tue Mar 09 15:29:44 2010 +0000
+++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java	Wed Mar 10 13:41:53 2010 +0000
@@ -31,6 +31,7 @@
 import org.w3c.dom.NodeList;
 
 import de.intevation.gnv.artifactdatabase.client.exception.ArtifactDatabaseClientException;
+import de.intevation.gnv.artifactdatabase.client.exception.ArtifactDatabaseInputException;
 import de.intevation.gnv.artifactdatabase.objects.Artifact;
 import de.intevation.gnv.artifactdatabase.objects.ArtifactDescription;
 import de.intevation.gnv.artifactdatabase.objects.ArtifactFactory;
@@ -69,6 +70,19 @@
     public final static String NAMESPACE_PREFIX = "art";
 
     /**
+     * Xpath expression to get general exception messages related to server
+     * errors.
+     */
+    public static final String EXCEPTION_GENERAL =
+        "/art:exceptionreport/art:exception/text()";
+
+    /**
+     * Xpath expression to get exception messages related to invalid user input.
+     */
+    public static final String EXCEPTION_USER_INPUT =
+        "/art:exceptionreport/art:exception/art:input/text()";
+
+    /**
      * the logger, used to log exceptions and additonaly information
      */
     private static Logger log = Logger
@@ -101,7 +115,7 @@
      * @see de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient#getArtifactFactories()
      */
     public Collection<ArtifactObject> getArtifactFactories()
-                                                            throws ArtifactDatabaseClientException {
+    throws ArtifactDatabaseClientException, ArtifactDatabaseInputException {
         Collection<ArtifactObject> resultValues = null;
         if (!initialized) {
             this.initialize();
@@ -182,8 +196,8 @@
     /**
      * @throws IOException
      */
-    private Document doGetRequest(String requestUrl) throws IOException,
-                                                    ArtifactDatabaseClientException {
+    private Document doGetRequest(String requestUrl)
+    throws IOException, ArtifactDatabaseClientException, ArtifactDatabaseInputException {
         return this.doGetRequest(requestUrl, null);
     }
 
@@ -191,8 +205,7 @@
      * @throws IOException
      */
     private Document doGetRequest(String requestUrl, Document requestBody)
-                                                                          throws IOException,
-                                                                          ArtifactDatabaseClientException {
+    throws IOException, ArtifactDatabaseClientException, ArtifactDatabaseInputException {
         XMLUtils xmlUtils = new XMLUtils();
         Representation output = doGetRequestInternal(requestUrl, requestBody);
         Document document = xmlUtils.readDocument(output.getStream());
@@ -283,7 +296,7 @@
      * @see de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient#createNewArtifact(de.intevation.gnv.artifactdatabase.objects.ArtifactObject)
      */
     public ArtifactObject createNewArtifact(ArtifactObject artifactFactory)
-                                                                           throws ArtifactDatabaseClientException {
+    throws ArtifactDatabaseClientException, ArtifactDatabaseInputException {
 
         try {
             Document request = this.createCreateRequestBody(artifactFactory);
@@ -363,9 +376,8 @@
      * @throws IOException
      */
     private Document doPostRequest(ArtifactObject artifactFactory,
-                                   Document request, String suburl)
-                                                                   throws IOException,
-                                                                   ArtifactDatabaseClientException {
+        Document request, String suburl)
+    throws IOException, ArtifactDatabaseClientException, ArtifactDatabaseInputException {
         XMLUtils xmlUtils = new XMLUtils();
         String url = ((ArtifactFactory) artifactFactory).getDataBaseUrl();
         InputStream is = this.doPostRequest(url + "/" + suburl, request);
@@ -379,10 +391,10 @@
      *      de.intevation.gnv.artifactdatabase.objects.ArtifactObject)
      */
     public ArtifactDescription getCurrentStepDescription(
-                                                         ArtifactObject artifactFactory,
-                                                         ArtifactObject currentArtifact,
-                                                         boolean includeUI)
-                                                         throws ArtifactDatabaseClientException {
+        ArtifactObject artifactFactory,
+        ArtifactObject currentArtifact,
+        boolean includeUI)
+    throws ArtifactDatabaseClientException, ArtifactDatabaseInputException {
         try {
             String url = this.getArtifactUrl(artifactFactory, currentArtifact);
             Document request = this.createDescribeRequestBody(currentArtifact,
@@ -434,8 +446,8 @@
     }
 
     private ArtifactDescription readDescription(Document document,
-                                                ArtifactObject artifact)
-                                                                        throws ArtifactDatabaseClientException {
+        ArtifactObject artifact)
+    throws ArtifactDatabaseClientException, ArtifactDatabaseInputException {
         // Check if there was an Error or Exception reported from the
         // ArtifactDatabase
         this.check4ExceptionReport(document);
@@ -550,11 +562,11 @@
      *      java.lang.String, java.util.Collection)
      */
     public ArtifactDescription doNextStep(
-                                          ArtifactObject artifactFactory,
-                                          ArtifactObject currentArtifact,
-                                          String target,
-                                          Collection<InputParameter> inputParameter)
-                                                                                    throws ArtifactDatabaseClientException {
+        ArtifactObject             artifactFactory,
+        ArtifactObject             currentArtifact,
+        String                     target,
+        Collection<InputParameter> inputParameter)
+    throws ArtifactDatabaseClientException, ArtifactDatabaseInputException {
 
         try {
             // 1 Feed
@@ -586,8 +598,8 @@
     public void doAdvance(
         ArtifactObject factory,
         ArtifactObject artifact,
-        String         target
-    ) throws IOException, ArtifactDatabaseClientException {
+        String         target)
+    throws IOException, ArtifactDatabaseClientException, ArtifactDatabaseInputException {
         String url                = getArtifactUrl(factory, artifact);
         Document advanceDocument  = createAdvanceRequestBody(artifact, target);
         InputStream advanceResult = doPostRequest(url, advanceDocument);
@@ -758,10 +770,11 @@
      *      de.intevation.gnv.artifactdatabase.objects.ArtifactObject,
      *      java.util.Collection)
      */
-    public void doFeed(ArtifactObject artifactFactory,
-                       ArtifactObject currentArtifact,
-                       Collection<InputParameter> inputParameter)
-                                                                 throws ArtifactDatabaseClientException {
+    public void doFeed(
+        ArtifactObject artifactFactory,
+        ArtifactObject currentArtifact,
+        Collection<InputParameter> inputParameter)
+    throws ArtifactDatabaseClientException, ArtifactDatabaseInputException {
 
         try {
             Document feedDocument = this.createFeedRequestBody(currentArtifact,
@@ -778,14 +791,21 @@
     }
 
     private void check4ExceptionReport(Document document)
-                                                         throws ArtifactDatabaseClientException {
+    throws ArtifactDatabaseClientException, ArtifactDatabaseInputException {
+        log.debug("REPORT: " + XMLUtils.writeDocument2String(document));
 
         String message = new XMLUtils().getStringXPath(document,
-                "/art:exceptionreport/art:exception");
+            EXCEPTION_GENERAL);
         if (message != null) {
+            log.error("FOUND GENERAL EXCEPTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
             throw new ArtifactDatabaseClientException(message);
         }
 
+        String input = XMLUtils.getStringXPath(document, EXCEPTION_USER_INPUT);
+        if (input != null) {
+            log.error("FOUND INPUT EXCEPTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+            throw new ArtifactDatabaseInputException(input);
+        }
     }
 
     public Document publishWMS(ArtifactObject factory, ArtifactObject artifact) {
@@ -868,10 +888,10 @@
      * @see de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient#getArtifactFactoryMetaInformation(java.util.Collection, java.lang.String, java.lang.String)
      */
     public Collection<ArtifactObject> getArtifactFactoryMetaInformation(
-                                                                Collection<MapService> mapServices,
-                                                                String geometry,
-                                                                String srs)
-                                                                           throws ArtifactDatabaseClientException {
+        Collection<MapService> mapServices,
+        String geometry,
+        String srs)
+    throws ArtifactDatabaseClientException, ArtifactDatabaseInputException {
         log.debug("DefaultArtifactDatabaseClient.getArtifactFactories");
         Collection<ArtifactObject> resultValues = null;
         try {
@@ -895,9 +915,10 @@
     }
     
     private Collection<ArtifactObject> parseMetaDataResult(
-              InputStream inputStream, 
-              String server,
-              String geometry) throws ArtifactDatabaseClientException{
+        InputStream inputStream, 
+        String      server,
+        String      geometry)
+    throws ArtifactDatabaseClientException, ArtifactDatabaseInputException {
         XMLUtils xmlUtils = new XMLUtils();
         Document document = xmlUtils.readDocument(inputStream);
         this.check4ExceptionReport(document);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/exception/ArtifactDatabaseInputException.java	Wed Mar 10 13:41:53 2010 +0000
@@ -0,0 +1,49 @@
+package de.intevation.gnv.artifactdatabase.client.exception;
+
+/**
+ * @author Ingo Weinzierl (ingo.weinzierl@intevation.de)
+ */
+public class ArtifactDatabaseInputException extends Exception {
+
+    /**
+     * The UID of this Class
+     */
+    private static final long serialVersionUID = -8979622024425251952L;
+
+    /**
+     * Constructor
+     */
+    public ArtifactDatabaseInputException() {
+        super();
+    }
+
+    /**
+     * Constructor
+     * 
+     * @param arg0
+     */
+    public ArtifactDatabaseInputException(String arg0) {
+        super(arg0);
+    }
+
+    /**
+     * Constructor
+     * 
+     * @param arg0
+     */
+    public ArtifactDatabaseInputException(Throwable arg0) {
+        super(arg0);
+    }
+
+    /**
+     * Constructor
+     * 
+     * @param arg0
+     * @param arg1
+     */
+    public ArtifactDatabaseInputException(String arg0, Throwable arg1) {
+        super(arg0, arg1);
+    }
+
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/gnv/src/main/webapp/WEB-INF/jsp/index.jsp	Tue Mar 09 15:29:44 2010 +0000
+++ b/gnv/src/main/webapp/WEB-INF/jsp/index.jsp	Wed Mar 10 13:41:53 2010 +0000
@@ -1,10 +1,13 @@
 <%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %>
+<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean-el" prefix="bean-el" %>
 <%@page import="java.util.Collection"%>
 <%@page import="de.intevation.gnv.artifactdatabase.objects.ArtifactObject"%>
+<%@page import="de.intevation.gnv.action.CommunicationKeys"%>
 <%@page import="de.intevation.gnv.action.sessionmodel.SessionModel"%>
 <%@page import="de.intevation.gnv.action.sessionmodel.SessionModelFactory"%>
 <%@page import="java.util.Iterator"%>
 <%  
+    String exception       = (String)request.getAttribute(CommunicationKeys.REQUEST_EXCEPTION_INPUT_ID);
     SessionModel sm        = SessionModelFactory.getInstance().getSessionModel(request);
     Object ui              = request.getAttribute("ui");
     Object staticui        = request.getAttribute("staticui");
@@ -39,10 +42,15 @@
     <%}%>
     
     <%-- render the dynamic part to feed the state and advance to the next state --%>
-    <%if (ui != null){%>
-        <div id="timeseriesfilter">
+    <%if (ui != null){%> 
+        <div id="timeseriesfilter"> 
             <form id="fisSelectionForm" onsubmit="displayOverlay()" action="<%=response.encodeURL("next.do")%>" method="post">
                <fieldset>
+            
+                <%-- error message, if user input was not valid --%>
+                <%if (exception != null) {%>
+                    <div class="inputException"><%=exception%></div>
+                <%}%>
                 <%=ui != null ? ui.toString().replaceAll("&nbsp;", "") : "" %>
                
                 <%if(furthertargets){%>
--- a/gnv/src/main/webapp/styles/default.css	Tue Mar 09 15:29:44 2010 +0000
+++ b/gnv/src/main/webapp/styles/default.css	Wed Mar 10 13:41:53 2010 +0000
@@ -177,6 +177,13 @@
     margin:      2px 2px;
 }
 
+.inputException {
+    color:       red;
+    font-size:   10px;
+    font-weight: bold;
+    margin:      2px 2px;
+}
+
 /*  ====================== Header ============================= */
 #head {
 	

http://dive4elements.wald.intevation.org