Author: husted
Date: Mon Feb 13 17:28:41 2006
New Revision: 377562

URL: http://svn.apache.org/viewcvs?rev=377562&view=rev
Log:
Resolve #38374 "Validation always skipped with Globals.CANCEL_KEY" reported by 
Paul Benedict 
* ActionConfig: Add cancellable property
* AbstractValidationActionForm: Throw InvalidCancelException if Cancel token 
present but cancellable not set 
* Add InvalidCancelException class

Added:
    
struts/action/trunk/src/java/org/apache/struts/action/InvalidCancelException.java
   (with props)
Modified:
    
struts/action/trunk/src/java/org/apache/struts/chain/commands/AbstractValidateActionForm.java
    
struts/action/trunk/src/java/org/apache/struts/chain/commands/servlet/PerformForward.java
    struts/action/trunk/src/java/org/apache/struts/config/ActionConfig.java

Added: 
struts/action/trunk/src/java/org/apache/struts/action/InvalidCancelException.java
URL: 
http://svn.apache.org/viewcvs/struts/action/trunk/src/java/org/apache/struts/action/InvalidCancelException.java?rev=377562&view=auto
==============================================================================
--- 
struts/action/trunk/src/java/org/apache/struts/action/InvalidCancelException.java
 (added)
+++ 
struts/action/trunk/src/java/org/apache/struts/action/InvalidCancelException.java
 Mon Feb 13 17:28:41 2006
@@ -0,0 +1,25 @@
+package org.apache.struts.action;
+
+
+/**
+ * <p> Thrown when a token generated by the Cancel tag is found in the
+ * request, but the cancellable property for the Action Mapping is not set.
+ * </p>
+ */
+public class InvalidCancelException extends Exception {
+    /**
+     * <p>Default constructor.</p>
+     */
+    public InvalidCancelException() {
+        super();
+    }
+
+    /**
+     * <p>Construct the exception with the specified message.</p>
+     *
+     * @param message the message
+     */
+    public InvalidCancelException(String message) {
+        super(message);
+    }
+}

Propchange: 
struts/action/trunk/src/java/org/apache/struts/action/InvalidCancelException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
struts/action/trunk/src/java/org/apache/struts/chain/commands/AbstractValidateActionForm.java
URL: 
http://svn.apache.org/viewcvs/struts/action/trunk/src/java/org/apache/struts/chain/commands/AbstractValidateActionForm.java?rev=377562&r1=377561&r2=377562&view=diff
==============================================================================
--- 
struts/action/trunk/src/java/org/apache/struts/chain/commands/AbstractValidateActionForm.java
 (original)
+++ 
struts/action/trunk/src/java/org/apache/struts/chain/commands/AbstractValidateActionForm.java
 Mon Feb 13 17:28:41 2006
@@ -1,24 +1,10 @@
-/*
- * $Id$
- *
- * Copyright 2003-2005 The Apache Software Foundation.
- *
- * 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 org.apache.struts.chain.commands;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.struts.action.ActionErrors;
 import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.InvalidCancelException;
 import org.apache.struts.chain.contexts.ActionContext;
 import org.apache.struts.config.ActionConfig;
 
@@ -32,6 +18,44 @@
  */
 public abstract class AbstractValidateActionForm extends ActionCommandBase {
     // ------------------------------------------------------ Instance 
Variables
+
+    /**
+     * <p> Provide Commons Logging instance for this class. </p>
+     */
+    private static final Log LOG =
+        LogFactory.getLog(AbstractSelectForward.class);
+
+    // ------------------------------------------------------ Protected Methods
+
+    /**
+     * <p>Helper method to verify the Cancel state.</p>
+     *
+     * <p>If the state is invalid, Cancel is unset and an
+     * InvalidCancelException is thrown.</p>
+     *
+     * @param actionCtx    Our ActionContext
+     * @param actionConfig Our ActionConfig
+     * @return true if cancel is set, false otherwise.
+     * @throws InvalidCancelException
+     */
+    private boolean isCancelled(ActionContext actionCtx,
+        ActionConfig actionConfig)
+        throws InvalidCancelException {
+        Boolean cancel = actionCtx.getCancelled();
+        boolean cancelled = ((cancel != null) && cancel.booleanValue());
+        boolean cancellable = actionConfig.getCancellable();
+
+        boolean invalidState = (cancelled && !cancellable);
+
+        if (invalidState) {
+            actionCtx.setCancelled(Boolean.FALSE);
+            actionCtx.setFormValid(Boolean.FALSE);
+            throw new InvalidCancelException();
+        }
+
+        return cancelled;
+    }
+
     // ---------------------------------------------------------- Public 
Methods
 
     /**
@@ -46,31 +70,30 @@
      */
     public boolean execute(ActionContext actionCtx)
         throws Exception {
+        // Set form valid until found otherwise
+        actionCtx.setFormValid(Boolean.TRUE);
+
         // Is there a form bean for this request?
         ActionForm actionForm = actionCtx.getActionForm();
 
         if (actionForm == null) {
-            actionCtx.setFormValid(Boolean.TRUE);
-
-            return (false);
-        }
-
-        // Was this request cancelled?
-        Boolean cancel = actionCtx.getCancelled();
-
-        if ((cancel != null) && cancel.booleanValue()) {
-            actionCtx.setFormValid(Boolean.TRUE);
-
-            return (false);
+            return false;
         }
 
         // Is validation disabled on this request?
         ActionConfig actionConfig = actionCtx.getActionConfig();
 
         if (!actionConfig.getValidate()) {
-            actionCtx.setFormValid(Boolean.TRUE);
+            return false;
+        }
+
+        // Was this request cancelled?
+        if (isCancelled(actionCtx, actionConfig)) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug(" Cancelled transaction, skipping validation");
+            }
 
-            return (false);
+            return false;
         }
 
         // Call the validate() method of this form bean
@@ -78,9 +101,7 @@
 
         // If there were no errors, proceed normally
         if ((errors == null) || (errors.isEmpty())) {
-            actionCtx.setFormValid(Boolean.TRUE);
-
-            return (false);
+            return false;
         }
 
         // Flag the validation failure and proceed
@@ -90,7 +111,7 @@
         actionCtx.saveErrors(errors);
         actionCtx.setFormValid(Boolean.FALSE);
 
-        return (false);
+        return false;
     }
 
     // ------------------------------------------------------- Protected 
Methods

Modified: 
struts/action/trunk/src/java/org/apache/struts/chain/commands/servlet/PerformForward.java
URL: 
http://svn.apache.org/viewcvs/struts/action/trunk/src/java/org/apache/struts/chain/commands/servlet/PerformForward.java?rev=377562&r1=377561&r2=377562&view=diff
==============================================================================
--- 
struts/action/trunk/src/java/org/apache/struts/chain/commands/servlet/PerformForward.java
 (original)
+++ 
struts/action/trunk/src/java/org/apache/struts/chain/commands/servlet/PerformForward.java
 Mon Feb 13 17:28:41 2006
@@ -15,6 +15,8 @@
  */
 package org.apache.struts.chain.commands.servlet;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.struts.action.ActionServlet;
 import org.apache.struts.chain.commands.AbstractPerformForward;
 import org.apache.struts.chain.contexts.ActionContext;
@@ -23,8 +25,6 @@
 import org.apache.struts.config.ModuleConfig;
 import org.apache.struts.util.MessageResources;
 import org.apache.struts.util.RequestUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 import javax.servlet.RequestDispatcher;
 import javax.servlet.http.HttpServletRequest;
@@ -37,6 +37,7 @@
  */
 public class PerformForward extends AbstractPerformForward {
     private static final Log LOG = LogFactory.getLog(PerformForward.class);
+
     // ------------------------------------------------------- Protected 
Methods
 
     /**
@@ -79,6 +80,7 @@
             if (uri.startsWith("/")) {
                 uri = request.getContextPath() + uri;
             }
+
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Redirecting to " + uri);
             }
@@ -88,9 +90,11 @@
         } else {
             RequestDispatcher rd =
                 sacontext.getContext().getRequestDispatcher(uri);
+
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Forwarding to " + uri);
             }
+
             rd.forward(request, sacontext.getResponse());
         }
     }

Modified: 
struts/action/trunk/src/java/org/apache/struts/config/ActionConfig.java
URL: 
http://svn.apache.org/viewcvs/struts/action/trunk/src/java/org/apache/struts/config/ActionConfig.java?rev=377562&r1=377561&r2=377562&view=diff
==============================================================================
--- struts/action/trunk/src/java/org/apache/struts/config/ActionConfig.java 
(original)
+++ struts/action/trunk/src/java/org/apache/struts/config/ActionConfig.java Mon 
Feb 13 17:28:41 2006
@@ -74,7 +74,16 @@
     protected String inherit = null;
 
     /**
-     * <p> Have the inheritance values for this class been applied?
+     * <p>Can this Action be cancelled? [false]</p> <p> By default, when an
+     * Action is cancelled, validation is bypassed and the Action should not
+     * execute the business operation. If a request tries to cancel an Action
+     * when cancellable is not set, a "InvalidCancelException" is thrown.
+     * </p>
+     */
+    protected boolean cancellable = false;
+
+    /**
+     * <p> Have the inheritance values for this class been applied?</p>
      */
     protected boolean extensionProcessed = false;
 
@@ -250,6 +259,28 @@
     }
 
     /**
+     * <p>Accessor for cancellable property</p>
+     *
+     * @return True if Action can be cancelled
+     */
+    public boolean getCancellable() {
+        return (this.cancellable);
+    }
+
+    /**
+     * <p>Mutator for for cancellable property</p>
+     *
+     * @param cancellable
+     */
+    public void setCancellable(boolean cancellable) {
+        if (configured) {
+            throw new IllegalStateException("Configuration is frozen");
+        }
+
+        this.cancellable = cancellable;
+    }
+
+    /**
      * <p>Returns the path of the ActionConfig that this object should inherit
      * properties from.</p>
      *
@@ -844,7 +875,7 @@
      */
     public ExceptionConfig findException(Class type) {
         // Check through the entire superclass hierarchy as needed
-        ExceptionConfig config = null;
+        ExceptionConfig config;
 
         while (true) {
             // Check for a locally defined handler
@@ -1103,8 +1134,14 @@
     public String toString() {
         StringBuffer sb = new StringBuffer("ActionConfig[");
 
+        sb.append("cancellable=");
+        sb.append(cancellable);
+
         sb.append("path=");
         sb.append(path);
+
+        sb.append("validate=");
+        sb.append(validate);
 
         if (attribute != null) {
             sb.append(",attribute=");



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to