Revision: 1362
          http://stripes.svn.sourceforge.net/stripes/?rev=1362&view=rev
Author:   bengunter
Date:     2010-11-29 21:06:26 +0000 (Mon, 29 Nov 2010)

Log Message:
-----------
Applied improved fix for STS-780 from 1.5.x branch.

Modified Paths:
--------------
    trunk/stripes/src/net/sourceforge/stripes/action/ActionBeanContext.java
    
trunk/stripes/src/net/sourceforge/stripes/exception/DefaultExceptionHandler.java

Added Paths:
-----------
    
trunk/stripes/src/net/sourceforge/stripes/action/ValidationErrorReportResolution.java

Modified: 
trunk/stripes/src/net/sourceforge/stripes/action/ActionBeanContext.java
===================================================================
--- trunk/stripes/src/net/sourceforge/stripes/action/ActionBeanContext.java     
2010-11-29 20:59:48 UTC (rev 1361)
+++ trunk/stripes/src/net/sourceforge/stripes/action/ActionBeanContext.java     
2010-11-29 21:06:26 UTC (rev 1362)
@@ -14,12 +14,9 @@
  */
 package net.sourceforge.stripes.action;
 
-import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
 
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
@@ -27,12 +24,8 @@
 
 import net.sourceforge.stripes.controller.FlashScope;
 import net.sourceforge.stripes.controller.StripesConstants;
-import net.sourceforge.stripes.controller.StripesFilter;
 import net.sourceforge.stripes.exception.SourcePageNotFoundException;
-import net.sourceforge.stripes.tag.ErrorsTag;
 import net.sourceforge.stripes.util.CryptoUtil;
-import net.sourceforge.stripes.util.Log;
-import net.sourceforge.stripes.validation.ValidationError;
 import net.sourceforge.stripes.validation.ValidationErrors;
 
 /**
@@ -226,10 +219,7 @@
     public Resolution getSourcePageResolution() throws 
SourcePageNotFoundException {
         String sourcePage = getSourcePage();
         if (sourcePage == null) {
-            if (StripesFilter.getConfiguration().isDebugMode())
-                return new ValidationErrorReportResolution(this);
-            else
-                throw new SourcePageNotFoundException(this);
+            throw new SourcePageNotFoundException(this);
         }
         else {
             return new ForwardResolution(sourcePage);
@@ -267,90 +257,3 @@
             "}";
     }
 }
-
-class ValidationErrorReportResolution implements Resolution {
-    private static final Log log = 
Log.getInstance(ValidationErrorReportResolution.class);
-    private ActionBeanContext context;
-
-    /** Construct a new instance to report validation errors in the specified 
context. */
-    protected ValidationErrorReportResolution(ActionBeanContext context) {
-        this.context = context;
-    }
-
-    public void execute(HttpServletRequest request, HttpServletResponse 
response) throws Exception {
-        // log an exception for the stack trace
-        SourcePageNotFoundException exception = new 
SourcePageNotFoundException(this.context);
-        log.error(exception);
-
-        // start the HTML error report
-        response.setContentType("text/html");
-        PrintWriter writer = response.getWriter();
-        writer.println("<html>");
-        writer.println("<head><title>Stripes validation error 
report</title></head>");
-        writer.println("<body style=\"font-family: Arial, sans-serif; 
font-size: 10pt;\">");
-        writer.println("<h1>Stripes validation error report</h1><p>");
-        writer.println(exception.getMessage());
-        writer.println("</p><h2>Validation errors</h2><p>");
-        sendErrors(request, response);
-        writer.println("</p></body></html>");
-    }
-
-    protected void sendErrors(HttpServletRequest request, HttpServletResponse 
response)
-            throws Exception {
-        // Output all errors in a standard format
-        Locale locale = request.getLocale();
-        ResourceBundle bundle = null;
-
-        try {
-            bundle = 
StripesFilter.getConfiguration().getLocalizationBundleFactory()
-                    .getErrorMessageBundle(locale);
-        }
-        catch (MissingResourceException mre) {
-            log.warn(getClass().getName(), " could not find the error messages 
resource bundle. ",
-                    "As a result default headers/footers etc. will be used. 
Check that ",
-                    "you have a StripesResources.properties in your classpath 
(unless ",
-                    "of course you have configured a different bundle).");
-        }
-
-        // Fetch the header and footer
-        String header = getResource(bundle, "header", 
ErrorsTag.DEFAULT_HEADER);
-        String footer = getResource(bundle, "footer", 
ErrorsTag.DEFAULT_FOOTER);
-        String openElement = getResource(bundle, "beforeError", "<li>");
-        String closeElement = getResource(bundle, "afterError", "</li>");
-
-        // Write out the error messages
-        PrintWriter writer = response.getWriter();
-        writer.write(header);
-
-        for (List<ValidationError> list : 
this.context.getValidationErrors().values()) {
-            for (ValidationError fieldError : list) {
-                writer.write(openElement);
-                writer.write(fieldError.getMessage(locale));
-                writer.write(closeElement);
-            }
-        }
-
-        writer.write(footer);
-    }
-
-    /**
-     * Utility method that is used to lookup the resources used for the errors 
header,
-     * footer, and the strings that go before and after each error.
-     *
-     * @param bundle the bundle to look up the resource from
-     * @param name the name of the resource to lookup (prefixes will be added)
-     * @param fallback a value to return if no resource can be found
-     * @return the value to use for the named resource
-     */
-    protected String getResource(ResourceBundle bundle, String name, String 
fallback) {
-        if (bundle == null) {
-            return fallback;
-        }
-
-        String resource;
-        try { resource = bundle.getString("stripes.errors." + name); }
-        catch (MissingResourceException mre) { resource = fallback; }
-
-        return resource;
-    }
-}

Added: 
trunk/stripes/src/net/sourceforge/stripes/action/ValidationErrorReportResolution.java
===================================================================
--- 
trunk/stripes/src/net/sourceforge/stripes/action/ValidationErrorReportResolution.java
                               (rev 0)
+++ 
trunk/stripes/src/net/sourceforge/stripes/action/ValidationErrorReportResolution.java
       2010-11-29 21:06:26 UTC (rev 1362)
@@ -0,0 +1,141 @@
+/* Copyright 2010 Ben Gunter
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.sourceforge.stripes.action;
+
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import net.sourceforge.stripes.controller.StripesFilter;
+import net.sourceforge.stripes.exception.SourcePageNotFoundException;
+import net.sourceforge.stripes.tag.ErrorsTag;
+import net.sourceforge.stripes.util.Log;
+import net.sourceforge.stripes.validation.ValidationError;
+
+/**
+ * A resolution that streams a simple HTML response to the client detailing 
the validation errors
+ * that apply for an {...@link ActionBeanContext}.
+ * 
+ * @author Ben Gunter
+ * @since Stripes 1.5.5
+ */
+public class ValidationErrorReportResolution implements Resolution {
+    private static final Log log = 
Log.getInstance(ValidationErrorReportResolution.class);
+    private ActionBeanContext context;
+
+    /** Construct a new instance to report validation errors in the specified 
context. */
+    public ValidationErrorReportResolution(ActionBeanContext context) {
+        this.context = context;
+    }
+
+    /** Get the action bean context on which the validation errors occurred. */
+    public ActionBeanContext getContext() {
+        return context;
+    }
+
+    public void execute(HttpServletRequest request, HttpServletResponse 
response) throws Exception {
+        // log an exception for the stack trace
+        SourcePageNotFoundException exception = new 
SourcePageNotFoundException(getContext());
+        log.error(exception);
+
+        // start the HTML error report
+        response.setContentType("text/html");
+        PrintWriter writer = response.getWriter();
+        writer.println("<html>");
+        writer.println("<head><title>Stripes validation error 
report</title></head>");
+        writer.println("<body style=\"font-family: Arial, sans-serif; 
font-size: 10pt;\">");
+        writer.println("<h1>Stripes validation error report</h1><p>");
+        writer.println(exception.getMessage());
+        writer.println("</p><h2>Validation errors</h2><p>");
+        sendErrors(request, response);
+        writer.println("</p></body></html>");
+    }
+
+    /**
+     * Called by {...@link #execute(HttpServletRequest, HttpServletResponse)} 
to write the actual
+     * validation errors to the client. The {...@code header}, {...@code 
footer}, {...@code beforeError} and
+     * {...@code afterError} resources are used by this method.
+     * 
+     * @param request The servlet request.
+     * @param response The servlet response.
+     */
+    protected void sendErrors(HttpServletRequest request, HttpServletResponse 
response)
+            throws Exception {
+        // Output all errors in a standard format
+        Locale locale = request.getLocale();
+        ResourceBundle bundle = null;
+
+        try {
+            bundle = 
StripesFilter.getConfiguration().getLocalizationBundleFactory()
+                    .getErrorMessageBundle(locale);
+        }
+        catch (MissingResourceException mre) {
+            log.warn(getClass().getName(), " could not find the error messages 
resource bundle. ",
+                    "As a result default headers/footers etc. will be used. 
Check that ",
+                    "you have a StripesResources.properties in your classpath 
(unless ",
+                    "of course you have configured a different bundle).");
+        }
+
+        // Fetch the header and footer
+        String header = getResource(bundle, "header", 
ErrorsTag.DEFAULT_HEADER);
+        String footer = getResource(bundle, "footer", 
ErrorsTag.DEFAULT_FOOTER);
+        String openElement = getResource(bundle, "beforeError", "<li>");
+        String closeElement = getResource(bundle, "afterError", "</li>");
+
+        // Write out the error messages
+        PrintWriter writer = response.getWriter();
+        writer.write(header);
+
+        for (List<ValidationError> list : 
getContext().getValidationErrors().values()) {
+            for (ValidationError fieldError : list) {
+                writer.write(openElement);
+                writer.write(fieldError.getMessage(locale));
+                writer.write(closeElement);
+            }
+        }
+
+        writer.write(footer);
+    }
+
+    /**
+     * Utility method that is used to lookup the resources used for the error 
header, footer, and
+     * the strings that go before and after each error.
+     * 
+     * @param bundle the bundle to look up the resource from
+     * @param name the name of the resource to lookup (prefixes will be added)
+     * @param fallback a value to return if no resource can be found
+     * @return the value to use for the named resource
+     */
+    protected String getResource(ResourceBundle bundle, String name, String 
fallback) {
+        if (bundle == null) {
+            return fallback;
+        }
+
+        String resource;
+        try {
+            resource = bundle.getString("stripes.errors." + name);
+        }
+        catch (MissingResourceException mre) {
+            resource = fallback;
+        }
+
+        return resource;
+    }
+}

Modified: 
trunk/stripes/src/net/sourceforge/stripes/exception/DefaultExceptionHandler.java
===================================================================
--- 
trunk/stripes/src/net/sourceforge/stripes/exception/DefaultExceptionHandler.java
    2010-11-29 20:59:48 UTC (rev 1361)
+++ 
trunk/stripes/src/net/sourceforge/stripes/exception/DefaultExceptionHandler.java
    2010-11-29 21:06:26 UTC (rev 1362)
@@ -33,6 +33,7 @@
 import net.sourceforge.stripes.action.FileBean;
 import net.sourceforge.stripes.action.ForwardResolution;
 import net.sourceforge.stripes.action.Resolution;
+import net.sourceforge.stripes.action.ValidationErrorReportResolution;
 import net.sourceforge.stripes.config.Configuration;
 import net.sourceforge.stripes.controller.DispatcherHelper;
 import net.sourceforge.stripes.controller.ExecutionContext;
@@ -145,6 +146,12 @@
                 if (resolution != null)
                     resolution.execute(request, response);
             }
+            else if (throwable instanceof SourcePageNotFoundException) {
+                Resolution resolution = handle((SourcePageNotFoundException) 
throwable, request,
+                        response);
+                if (resolution != null)
+                    resolution.execute(request, response);
+            }
             else {
                 // If there's no sensible proxy, rethrow the original 
throwable,
                 // NOT the unwrapped one since they may add extra information
@@ -163,6 +170,33 @@
 
     /**
      * <p>
+     * A default handler for {...@link SourcePageNotFoundException}. That 
exception is thrown when
+     * validation errors occur on a request but the source page cannot be 
determined from the
+     * request parameters. Such a condition generally arises during 
application development when,
+     * for example, a parameter is accidentally omitted from a generated 
hyperlink or AJAX request.
+     * </p>
+     * <p>
+     * In the past, it was very difficult to determine what validation errors 
triggered the
+     * exception. This method returns a {...@link 
ValidationErrorReportResolution}, which sends a
+     * simple HTML response to the client that very clearly details the 
validation errors.
+     * </p>
+     * <p>
+     * In production, most applications will provide their own handler for
+     * {...@link SourcePageNotFoundException} by extending this class and 
overriding this method.
+     * </p>
+     * 
+     * @param exception The exception.
+     * @param request The servlet request.
+     * @param response The servlet response.
+     * @return A {...@link ValidationErrorReportResolution}
+     */
+    protected Resolution handle(SourcePageNotFoundException exception, 
HttpServletRequest request,
+            HttpServletResponse response) throws Exception {
+        return new 
ValidationErrorReportResolution(exception.getActionBeanContext());
+    }
+
+    /**
+     * <p>
      * {...@link FileUploadLimitExceededException} is notoriously difficult to 
handle for several
      * reasons:
      * <ul>


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Increase Visibility of Your 3D Game App & Earn a Chance To Win $500!
Tap into the largest installed PC base & get more eyes on your game by
optimizing for Intel(R) Graphics Technology. Get started today with the
Intel(R) Software Partner Program. Five $500 cash prizes are up for grabs.
http://p.sf.net/sfu/intelisp-dev2dev
_______________________________________________
Stripes-development mailing list
Stripes-development@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/stripes-development

Reply via email to