Commits

Anonymous committed fc3cee5

XW-563 DefaultWorkflowInterceptor should not perform any validation, just direct flow based on validation errors available in the ValidationAware instance

git-svn-id: http://svn.opensymphony.com/svn/xwork/trunk@1598e221344d-f017-0410-9bd5-d282ab1896d7

Comments (0)

Files changed (6)

src/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptor.java

  */
 package com.opensymphony.xwork2.interceptor;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 import com.opensymphony.xwork2.Action;
 import com.opensymphony.xwork2.ActionInvocation;
-import com.opensymphony.xwork2.Validateable;
 import com.opensymphony.xwork2.ValidationAware;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * <!-- START SNIPPET: description -->
  *
- * An interceptor that does some basic validation workflow before allowing the interceptor chain to continue.
+ * An interceptor that makes sure there are not validation errors before allowing the interceptor chain to continue.
+ * <b>This interceptor does not perform any validation</b>.
  *
  * <p/>This interceptor does nothing if the name of the method being invoked is specified in the <b>excludeMethods</b>
  * parameter. <b>excludeMethods</b> accepts a comma-delimited list of method names. For example, requests to
  * <b>foo!input.action</b> and <b>foo!back.action</b> will be skipped by this interceptor if you set the
  * <b>excludeMethods</b> parameter to "input, back".
  *
- * <p/>The order of execution in the workflow is:
- *
- * <ol>
- *
- * <li>If the action being executed implements {@link Validateable}, the action's {@link Validateable#validate()
- * validate} method is called.</li>
- *
- * <li>Next, if the action implements {@link ValidationAware}, the action's {@link ValidationAware#hasErrors()
- * hasErrors} method is called. If this method returns true, this interceptor stops the chain from continuing and
- * immediately returns {@link Action#INPUT}</li>
- *
- * </ol>
- *
- * <p/>
- * <b>NOTE:</b> if the action doesn't implement either interface, this interceptor effectively does nothing. This
- * interceptor is often used with the <b>validation</b> interceptor. However, it does not have to be, especially if you
- * wish to write all your validation rules by hand in the validate() method rather than in XML files.
- *
- * <p/>
- *
  * <b>Note:</b> As this method extends off MethodFilterInterceptor, it is capable of
  * deciding if it is applicable only to selective methods in the action class. This is done by adding param tags
  * for the interceptor element, naming either a list of excluded method names and/or a list of included method
  * all methods for both parameters.
  * See {@link MethodFilterInterceptor} for more info.
  *
- * <p/><b>Update:</b> Added logic to execute a validate{MethodName} and then conditionally
- * followed than a general validate method, depending on the 'alwaysInvokeValidate' 
- * parameter/property which  is by default set to true.
- * This allows us to run some validation logic based on the method name we specify in the 
- * ActionProxy. For example, you can specify a validateInput() method 
- * that will be run before the invocation of the input method.
- * 
  * <!-- END SNIPPET: description -->
  *
  * <p/> <u>Interceptor parameters:</u>
  *
  * <ul>
  *
- * <li>alwaysInvokeValidate - Default to true. If true validate() method will always
- * be invoked, otherwise it will not.</li>
  * <li>inputResultName - Default to "input". Determine the result name to be returned when
  * an action / field error is found.</li>
  *
 
 	private static final Log _log = LogFactory.getLog(DefaultWorkflowInterceptor.class);
 	
-	private final static String VALIDATE_PREFIX = "validate";
-	private final static String ALT_VALIDATE_PREFIX = "validateDo";
-	
-	private boolean alwaysInvokeValidate = true;
-	
 	private String inputResultName = Action.INPUT;
 	
 	/**
-	 * Determine if {@link Validateable}'s <code>validate()</code> should always 
-	 * be invoked. Default to "true".
-	 * 
-	 * @param alwaysInvokeValidate <tt>true</tt> then <code>validate()</code> is always invoked.
-	 */
-	public void setAlwaysInvokeValidate(String alwaysInvokeValidate) {
-		this.alwaysInvokeValidate = Boolean.parseBoolean(alwaysInvokeValidate);
-	}
-	
-	/**
 	 * Set the <code>inputResultName</code> (result name to be returned when 
 	 * a action / field error is found registered). Default to {@link Action#INPUT}
 	 * 
     protected String doIntercept(ActionInvocation invocation) throws Exception {
         Object action = invocation.getAction();
         
-        
-        if (action instanceof Validateable) {
-        	// keep exception that might occured in validateXXX or validateDoXXX
-        	Exception exception = null; 
-        	
-            Validateable validateable = (Validateable) action;
-            if (_log.isDebugEnabled()) {
-            	_log.debug("Invoking validate() on action "+validateable);
-            }
-            
-            try {
-            	PrefixMethodInvocationUtil.invokePrefixMethod(
-            			invocation, 
-            			new String[] { VALIDATE_PREFIX, ALT_VALIDATE_PREFIX });
-            }
-            catch(Exception e) {
-            	// If any exception occurred while doing reflection, we want 
-            	// validate() to be executed
-            	_log.warn("an exception occured while executing the prefix method", e);
-            	exception = e;
-            }
-            
-            
-            if (alwaysInvokeValidate) {
-            	validateable.validate();
-            }
-            
-            if (exception != null) { 
-            	// rethrow if something is wrong while doing validateXXX / validateDoXXX 
-            	throw exception;
-            }
-        }
-        
-
         if (action instanceof ValidationAware) {
             ValidationAware validationAwareAction = (ValidationAware) action;
 

src/java/com/opensymphony/xwork2/validator/ValidationInterceptor.java

  */
 package com.opensymphony.xwork2.validator;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.opensymphony.xwork2.Action;
 import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.ActionProxy;
+import com.opensymphony.xwork2.Validateable;
+import com.opensymphony.xwork2.ValidationAware;
+import com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor;
 import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
+import com.opensymphony.xwork2.interceptor.PrefixMethodInvocationUtil;
 
 /**
  * <!-- START SNIPPET: description -->
  * parameter. <b>excludeMethods</b> accepts a comma-delimited list of method names. For example, requests to
  * <b>foo!input.action</b> and <b>foo!back.action</b> will be skipped by this interceptor if you set the
  * <b>excludeMethods</b> parameter to "input, back".
- *
- * <p/>Note that this has nothing to do with the {@link com.opensymphony.xwork2.Validateable} interface and simply adds
- * error messages to the action. The workflow of the action request does not change due to this interceptor. Rather,
+ * 
+ * </ol>
+ * 
+ * <p/> The workflow of the action request does not change due to this interceptor. Rather,
  * this interceptor is often used in conjuction with the <b>workflow</b> interceptor.
  *
  * <p/>
  *
  * <ul>
  *
- * <li>None</li>
+ * <li>alwaysInvokeValidate - Defaults to true. If true validate() method will always
+ * be invoked, otherwise it will not.</li>
  *
+ * <li>programmatic - Defaults to true. If true and the action is Validateable call validate(),
+ * and any method that starts with "validate".
+ * </li>
+ * 
+ * <li>declarative - Defaults to true. Perform validation based on xml or annotations.</li>
+ * 
  * </ul>
  *
  * <!-- END SNIPPET: parameters -->
 
     private boolean validateAnnotatedMethodOnly;
 
+    private static final Log _log = LogFactory.getLog(DefaultWorkflowInterceptor.class);
+    
+    private final static String VALIDATE_PREFIX = "validate";
+    private final static String ALT_VALIDATE_PREFIX = "validateDo";
+    
+    private boolean alwaysInvokeValidate = true;
+    private boolean programmatic = true;
+    private boolean declarative = true;
+
+    /**
+     * Determines if {@link Validateable}'s <code>validate()</code> should be called,
+     * as well as methods whose name that start with "validate". Defaults to "true".
+     * 
+     * @param programmatic <tt>true</tt> then <code>validate()</code> is invoked.
+     */
+    public void setProgrammatic(boolean programmatic) {
+        this.programmatic = programmatic;
+    }
+
+    /**
+     * Determines if validation based on annotations or xml should be performed. Defaults 
+     * to "true".
+     * 
+     * @param declarative <tt>true</tt> then perform validation based on annotations or xml.
+     */
+    public void setDeclarative(boolean declarative) {
+        this.declarative = declarative;
+    }
+
+    /**
+     * Determines if {@link Validateable}'s <code>validate()</code> should always 
+     * be invoked. Default to "true".
+     * 
+     * @param alwaysInvokeValidate <tt>true</tt> then <code>validate()</code> is always invoked.
+     */
+    public void setAlwaysInvokeValidate(String alwaysInvokeValidate) {
+            this.alwaysInvokeValidate = Boolean.parseBoolean(alwaysInvokeValidate);
+    }
 
     /**
      * Gets if <code>validate()</code> should always be called or only per annotated method.
      */
     protected void doBeforeInvocation(ActionInvocation invocation) throws Exception {
         Object action = invocation.getAction();
-        String context = invocation.getProxy().getActionName();
-        String method = invocation.getProxy().getMethod();
+        ActionProxy proxy = invocation.getProxy();
+        String context = proxy.getActionName();
+        String method = proxy.getMethod();
 
         if (log.isDebugEnabled()) {
             log.debug("Validating "
                     + invocation.getProxy().getNamespace() + "/" + invocation.getProxy().getActionName() + " with method "+ method +".");
         }
+        
 
-        if (validateAnnotatedMethodOnly) {
-            ActionValidatorManagerFactory.getInstance().validate(action, context, method);
-        } else {
-            ActionValidatorManagerFactory.getInstance().validate(action, context);
+        if(declarative) {
+            if (validateAnnotatedMethodOnly) {
+                ActionValidatorManagerFactory.getInstance().validate(action, context, method);
+            } else {
+                ActionValidatorManagerFactory.getInstance().validate(action, context);
+            }
+        }
+        
+        if (action instanceof Validateable && programmatic) {
+            // keep exception that might occured in validateXXX or validateDoXXX
+            Exception exception = null; 
+            
+            Validateable validateable = (Validateable) action;
+            if (_log.isDebugEnabled()) {
+                _log.debug("Invoking validate() on action "+validateable);
+            }
+            
+            try {
+                PrefixMethodInvocationUtil.invokePrefixMethod(
+                                invocation, 
+                                new String[] { VALIDATE_PREFIX, ALT_VALIDATE_PREFIX });
+            }
+            catch(Exception e) {
+                // If any exception occurred while doing reflection, we want 
+                // validate() to be executed
+                _log.warn("an exception occured while executing the prefix method", e);
+                exception = e;
+            }
+            
+            
+            if (alwaysInvokeValidate) {
+                validateable.validate();
+            }
+            
+            if (exception != null) { 
+                // rethrow if something is wrong while doing validateXXX / validateDoXXX 
+                throw exception;
+            }
         }
     }
 

src/test/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptor2Test.java

 import com.opensymphony.xwork2.ActionProxy;
 import com.opensymphony.xwork2.ActionSupport;
 import com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor;
+import com.opensymphony.xwork2.validator.ValidationInterceptor;
 
 /**
  * 
 		actionInvocationControl.expectAndDefaultReturn(null, actionProxy);
 		actionInvocation.getAction();
 		actionInvocationControl.expectAndDefaultReturn(null, action);
+		actionProxy.getActionName();
+		actionProxyControl.expectAndDefaultReturn(null, "action");
 		
 		actionInvocationControl.replay();
 		actionProxyControl.replay();
 		
+		ValidationInterceptor validationInterceptor = new ValidationInterceptor();
 		DefaultWorkflowInterceptor interceptor = new DefaultWorkflowInterceptor();
 		try {
+		        validationInterceptor.intercept(actionInvocation);
 			interceptor.intercept(actionInvocation);
 			fail();
 		}
 		actionInvocationControl.expectAndDefaultReturn(null, actionProxy);
 		actionInvocation.getAction();
 		actionInvocationControl.expectAndDefaultReturn(null, action);
+		actionProxy.getActionName();
+                actionProxyControl.expectAndDefaultReturn(null, "action");
 		
 		actionInvocationControl.replay();
 		actionProxyControl.replay();
 		
+		ValidationInterceptor validationInterceptor = new ValidationInterceptor();
 		DefaultWorkflowInterceptor interceptor = new DefaultWorkflowInterceptor();
 		try {
+		        validationInterceptor.intercept(actionInvocation);
 			interceptor.intercept(actionInvocation);
 			fail();
 		}

src/test/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptorPrefixMethodInvocationTest.java

-/*
- * Copyright (c) 2002-2006 by OpenSymphony
- * All rights reserved.
- */
-package com.opensymphony.xwork2.interceptor;
-
-import org.easymock.MockControl;
-
-import com.opensymphony.xwork2.Action;
-import com.opensymphony.xwork2.ActionInvocation;
-import com.opensymphony.xwork2.ActionProxy;
-import com.opensymphony.xwork2.Validateable;
-import com.opensymphony.xwork2.ValidationAware;
-
-import junit.framework.TestCase;
-
-/**
- * Test DefaultWorkflowInterceptor's prefix method invocation capabilities.
- * 
- * @author tm_jee
- * @version $Date$ $Id$
- */
-public class DefaultWorkflowInterceptorPrefixMethodInvocationTest extends TestCase {
-
-	public void testPrefixMethodInvocation1() throws Exception {
-		
-		MockControl controlAction = MockControl.createControl(ValidateAction.class);
-		ValidateAction mockAction = (ValidateAction) controlAction.getMock();
-		mockAction.hasErrors();
-		controlAction.setReturnValue(true);
-		mockAction.validateDoSave();
-		controlAction.setVoidCallable(1);
-		mockAction.validate();
-		controlAction.setVoidCallable();
-		
-		MockControl controlActionProxy = MockControl.createControl(ActionProxy.class);
-		ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock();
-		mockActionProxy.getMethod();
-		controlActionProxy.setDefaultReturnValue("save");
-		
-		MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class);
-		ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock();
-		mockActionInvocation.getAction();
-		controlActionInvocation.setDefaultReturnValue(mockAction);
-		mockActionInvocation.getProxy();
-		controlActionInvocation.setDefaultReturnValue(mockActionProxy);
-		
-		
-		controlAction.replay();
-		controlActionProxy.replay();
-		controlActionInvocation.replay();
-		
-		DefaultWorkflowInterceptor interceptor = new DefaultWorkflowInterceptor();
-		String result = interceptor.intercept(mockActionInvocation);
-		
-		assertEquals(Action.INPUT, result);
-		controlAction.verify();
-		controlActionProxy.verify();
-		controlActionInvocation.verify();
-	}
-	
-	public void testPrefixMethodInvocation2() throws Exception {
-		MockControl controlAction = MockControl.createControl(ValidateAction.class);
-		ValidateAction mockAction = (ValidateAction) controlAction.getMock();
-		mockAction.hasErrors();
-		controlAction.setReturnValue(false);
-		mockAction.validateSubmit();
-		controlAction.setVoidCallable(1);
-		mockAction.validate();
-		controlAction.setVoidCallable();
-		
-		MockControl controlActionProxy = MockControl.createControl(ActionProxy.class);
-		ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock();
-		mockActionProxy.getMethod();
-		controlActionProxy.setDefaultReturnValue("submit");
-		
-		MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class);
-		ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock();
-		mockActionInvocation.getAction();
-		controlActionInvocation.setDefaultReturnValue(mockAction);
-		mockActionInvocation.getProxy();
-		controlActionInvocation.setDefaultReturnValue(mockActionProxy);
-		mockActionInvocation.invoke();
-		controlActionInvocation.setReturnValue("okok");
-		
-		
-		controlAction.replay();
-		controlActionProxy.replay();
-		controlActionInvocation.replay();
-		
-		DefaultWorkflowInterceptor interceptor = new DefaultWorkflowInterceptor();
-		String result = interceptor.intercept(mockActionInvocation);
-		
-		assertEquals("okok", result);
-		controlAction.verify();
-		controlActionProxy.verify();
-		controlActionInvocation.verify();
-	}
-	
-	private interface ValidateAction extends Action, Validateable, ValidationAware {
-		void validateDoSave();
-		void validateSubmit();
-		String submit();
-    }
-}

src/test/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptorTest.java

 import com.mockobjects.dynamic.Mock;
 import com.opensymphony.xwork2.*;
 import com.opensymphony.xwork2.mock.MockActionProxy;
+import com.opensymphony.xwork2.validator.ValidationInterceptor;
+
 import junit.framework.TestCase;
 
 
     private Mock invocationMock;
     private Action action;
     private ActionProxy proxy;
+    private Mock proxyMock;
 
 
     public void testInvokesActionInvocationIfNoErrors() throws Exception {
-        actionMock.expectAndReturn("hasErrors", false);
-        actionMock.expect("validate");
         final String result = "testing123";
-        invocationMock.expectAndReturn("invoke", result);
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("getAction", action);
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getActionName", "name");
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("getAction", action);
         invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        actionMock.expect("validate");
+        proxyMock.expectAndReturn("getMethod", "execute");
+        invocationMock.expectAndReturn("getAction", action);
+        actionMock.expectAndReturn("hasErrors", false);
+        invocationMock.expectAndReturn("invoke", result);
+        invocationMock.expectAndReturn("invoke", result);
+        
+        ValidationInterceptor validationInterceptor = new ValidationInterceptor();
+        validationInterceptor.intercept(invocation);
         assertEquals(result, interceptor.intercept(invocation));
     }
 
     public void testReturnsInputWithoutExecutingIfHasErrors() throws Exception {
-        actionMock.expectAndReturn("hasErrors", true);
-        actionMock.expect("validate");
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("getAction", action);
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getActionName", "name");
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("getAction", action);
         invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        actionMock.expect("validate");
+        proxyMock.expectAndReturn("getMethod", "execute");
+        invocationMock.expectAndReturn("getAction", action);
+        actionMock.expectAndReturn("hasErrors", false);
+        invocationMock.expectAndReturn("invoke", Action.INPUT);
+        invocationMock.expectAndReturn("invoke", Action.INPUT);
+        
+        ValidationInterceptor validationInterceptor = new ValidationInterceptor();
+        validationInterceptor.intercept(invocation);
         assertEquals(Action.INPUT, interceptor.intercept(invocation));
     }
 
     public void testExcludesMethod() throws Exception {
         interceptor.setExcludeMethods("execute");
         final String result = "testing123";
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        invocationMock.expectAndReturn("invoke", result);
+        proxyMock.expectAndReturn("getMethod", "execute");        
         invocationMock.expectAndReturn("invoke", result);
+                
+        ValidationInterceptor validationInterceptor = new ValidationInterceptor();
+        validationInterceptor.setExcludeMethods("execute");
+        interceptor.setExcludeMethods("execute");
+        validationInterceptor.intercept(invocation);
+        
         assertEquals(result, interceptor.intercept(invocation));
     }
 
     public void testExcludesMethodWithWildCard() throws Exception {
         interceptor.setExcludeMethods("*");
         final String result = "testing123";
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        invocationMock.expectAndReturn("getAction", action);
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getActionName", "name");
+        proxyMock.expectAndReturn("getMethod", "execute");
+        invocationMock.expectAndReturn("getAction", action);
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        actionMock.expect("validate");
+        proxyMock.expectAndReturn("getMethod", "execute");
+        invocationMock.expectAndReturn("invoke", result);
         invocationMock.expectAndReturn("invoke", result);
+        
+        ValidationInterceptor validationInterceptor = new ValidationInterceptor();
+        validationInterceptor.intercept(invocation);
+        validationInterceptor.setExcludeMethods("*");
         assertEquals(result, interceptor.intercept(invocation));
     }
 
     public void testIncludesMethodWithWildcard() throws Exception {
         interceptor.setIncludeMethods("*");
-        actionMock.expectAndReturn("hasErrors", false);
-        actionMock.expect("validate");
         final String result = "testing123";
-        invocationMock.expectAndReturn("invoke", result);
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("getAction", action);
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getActionName", "name");
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("getAction", action);
         invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        actionMock.expect("validate");
+        invocationMock.expectAndReturn("invoke", result);
+        
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        invocationMock.expectAndReturn("getAction", action);
+        actionMock.expectAndReturn("hasErrors", false);
+        invocationMock.expectAndReturn("invoke", result);
+        
+        ValidationInterceptor validationInterceptor = new ValidationInterceptor();
+        validationInterceptor.setIncludeMethods("*");
+        validationInterceptor.intercept(invocation);
+        
         assertEquals(result, interceptor.intercept(invocation));
     }
 
 
     public void testIncludesMethod() throws Exception {
         interceptor.setIncludeMethods("execute");
-        actionMock.expectAndReturn("hasErrors", false);
-        actionMock.expect("validate");
         final String result = "testing123";
-        invocationMock.expectAndReturn("invoke", result);
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("getAction", action);
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getActionName", "name");
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("getAction", action);
         invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        actionMock.expect("validate");
+        invocationMock.expectAndReturn("invoke", result);
+        
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        invocationMock.expectAndReturn("getAction", action);
+        actionMock.expectAndReturn("hasErrors", false);
+        invocationMock.expectAndReturn("invoke", result);
+        
+        ValidationInterceptor validationInterceptor = new ValidationInterceptor();
+        validationInterceptor.setIncludeMethods("execute");
+        validationInterceptor.intercept(invocation);
+        
         assertEquals(result, interceptor.intercept(invocation));
     }
 
     public void testIncludesAndExcludesMethod() throws Exception {
         interceptor.setExcludeMethods("execute,input,validate");
         interceptor.setIncludeMethods("execute");
-        actionMock.expectAndReturn("hasErrors", false);
-        actionMock.expect("validate");
+        
         final String result = "testing123";
-        invocationMock.expectAndReturn("invoke", result);
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("getAction", action);
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getActionName", "name");
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("getAction", action);
         invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        actionMock.expect("validate");
+        invocationMock.expectAndReturn("invoke", result);
+        
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        invocationMock.expectAndReturn("getAction", action);
+        actionMock.expectAndReturn("hasErrors", false);
+        invocationMock.expectAndReturn("invoke", result);
+        
+        ValidationInterceptor validationInterceptor = new ValidationInterceptor();
+        validationInterceptor.setExcludeMethods("execute,input,validate");
+        validationInterceptor.setIncludeMethods("execute");
+        validationInterceptor.intercept(invocation);
+        
         assertEquals(result, interceptor.intercept(invocation));
     }
 
     public void testIncludesAndExcludesMethodAllWildCarded() throws Exception {
         interceptor.setExcludeMethods("*");
         interceptor.setIncludeMethods("*");
-        actionMock.expectAndReturn("hasErrors", false);
-        actionMock.expect("validate");
+        
         final String result = "testing123";
-        invocationMock.expectAndReturn("invoke", result);
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("getAction", action);
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getActionName", "name");
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("getAction", action);
         invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        actionMock.expect("validate");
+        invocationMock.expectAndReturn("invoke", result);
+        
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        invocationMock.expectAndReturn("getAction", action);
+        actionMock.expectAndReturn("hasErrors", false);
+        invocationMock.expectAndReturn("invoke", result);
+        
+        ValidationInterceptor validationInterceptor = new ValidationInterceptor();
+        validationInterceptor.setExcludeMethods("*");
+        validationInterceptor.setIncludeMethods("*");
+        validationInterceptor.intercept(invocation);
+        
         assertEquals(result, interceptor.intercept(invocation));
     }
 
     public void testIncludesAndExcludesMethodWithExcludeWildcard() throws Exception {
         interceptor.setExcludeMethods("*");
         interceptor.setIncludeMethods("execute");
-        actionMock.expectAndReturn("hasErrors", false);
-        actionMock.expect("validate");
+        
         final String result = "testing123";
-        invocationMock.expectAndReturn("invoke", result);
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("getAction", action);
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getActionName", "name");
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("getAction", action);
         invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        actionMock.expect("validate");
+        invocationMock.expectAndReturn("invoke", result);
+        
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        invocationMock.expectAndReturn("getAction", action);
+        actionMock.expectAndReturn("hasErrors", false);
+        invocationMock.expectAndReturn("invoke", result);
+        
+        ValidationInterceptor validationInterceptor = new ValidationInterceptor();
+        validationInterceptor.setExcludeMethods("*");
+        validationInterceptor.setIncludeMethods("execute");
+        validationInterceptor.intercept(invocation);
+        
         assertEquals(result, interceptor.intercept(invocation));
     }
 
     public void testIncludesAndExcludesMethodWithIncludeWildcardAndNoMatches() throws Exception {
         interceptor.setExcludeMethods("execute,input,validate");
         interceptor.setIncludeMethods("*");
+        
         final String result = "testing123";
+        proxyMock.expectAndReturn("getMethod", "execute");
+        proxyMock.expectAndReturn("getActionName", "name");
+        proxyMock.expectAndReturn("getMethod", "execute");
+        invocationMock.expectAndReturn("invoke", result);
+        
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("invoke", result);
+        
+        ValidationInterceptor validationInterceptor = new ValidationInterceptor();
+        validationInterceptor.setExcludeMethods("execute,input,validate");
+        validationInterceptor.setIncludeMethods("*");
+        validationInterceptor.intercept(invocation);
+        
         assertEquals(result, interceptor.intercept(invocation));
     }
 
     public void testIncludesAndExcludesMethodWithIncludeWildcard() throws Exception {
         interceptor.setExcludeMethods("input,validate");
         interceptor.setIncludeMethods("*");
-        actionMock.expectAndReturn("hasErrors", false);
-        actionMock.expect("validate");
+        
         final String result = "testing123";
-        invocationMock.expectAndReturn("invoke", result);
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("getAction", action);
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getActionName", "name");
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("getAction", action);
         invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        actionMock.expect("validate");
+        invocationMock.expectAndReturn("invoke", result);
+        
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        invocationMock.expectAndReturn("getAction", action);
+        actionMock.expectAndReturn("hasErrors", false);
+        invocationMock.expectAndReturn("invoke", result);
+        
+        ValidationInterceptor validationInterceptor = new ValidationInterceptor();
+        validationInterceptor.setExcludeMethods("input,validate");
+        validationInterceptor.setIncludeMethods("*");
+        validationInterceptor.intercept(invocation);
+        
         assertEquals(result, interceptor.intercept(invocation));
     }
 
 
         interceptor.setExcludeMethods("execute,input,validate");
         interceptor.setIncludeMethods("execute");
+        
         final String result = "testing123";
-        invocationMock.expectAndReturn("invoke", result);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        invocationMock.expectAndReturn("getAction", action);
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getActionName", "name");
+        proxyMock.expectAndReturn("getMethod", "execute");
         invocationMock.expectAndReturn("getAction", action);
+        invocationMock.expectAndReturn("getProxy", proxy);
+        proxyMock.expectAndReturn("getMethod", "execute");
+        invocationMock.expectAndReturn("invoke", result);
+        invocationMock.expectAndReturn("invoke", result);
+        
+        ValidationInterceptor validationInterceptor = new ValidationInterceptor();
+        validationInterceptor.setExcludeMethods("execute,input,validate");
+        validationInterceptor.setIncludeMethods("execute");
+        validationInterceptor.intercept(invocation);
+        
         assertEquals(result, interceptor.intercept(invocation));
     }
     
         actionMock = new Mock(ValidateAction.class);
         action = (ValidateAction) actionMock.proxy();
         invocationMock = new Mock(ActionInvocation.class);
-        proxy = new MockActionProxy();
-        proxy.setMethod("execute");
+        interceptor = new DefaultWorkflowInterceptor();
+        proxyMock = new Mock(ActionProxy.class);
+        proxy = (ActionProxy) proxyMock.proxy();
         invocationMock.expectAndReturn("getProxy", proxy);
         invocation = (ActionInvocation) invocationMock.proxy();
-        interceptor = new DefaultWorkflowInterceptor();
     }
 
     protected void tearDown() throws Exception {

src/test/com/opensymphony/xwork2/interceptor/ValidationInterceptorPrefixMethodInvocationTest.java

+/*
+ * Copyright (c) 2002-2006 by OpenSymphony
+ * All rights reserved.
+ */
+package com.opensymphony.xwork2.interceptor;
+
+import org.easymock.MockControl;
+
+import com.opensymphony.xwork2.Action;
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.ActionProxy;
+import com.opensymphony.xwork2.Validateable;
+import com.opensymphony.xwork2.ValidationAware;
+import com.opensymphony.xwork2.validator.ValidationInterceptor;
+
+import junit.framework.TestCase;
+
+/**
+ * Test ValidationInterceptor's prefix method invocation capabilities.
+ * 
+ * @author tm_jee
+ * @version $Date$ $Id$
+ */
+public class ValidationInterceptorPrefixMethodInvocationTest extends TestCase {
+
+	public void testPrefixMethodInvocation1() throws Exception {
+		
+		MockControl controlAction = MockControl.createControl(ValidateAction.class);
+		ValidateAction mockAction = (ValidateAction) controlAction.getMock();
+		mockAction.validateDoSave();
+		controlAction.setVoidCallable(1);
+		mockAction.validate();
+		controlAction.setVoidCallable();
+		
+		MockControl controlActionProxy = MockControl.createControl(ActionProxy.class);
+		ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock();
+		mockActionProxy.getMethod();
+		controlActionProxy.setDefaultReturnValue("save");
+		mockActionProxy.getActionName();
+		controlActionProxy.setDefaultReturnValue("something");
+		
+		MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class);
+		ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock();
+		mockActionInvocation.getAction();
+		controlActionInvocation.setDefaultReturnValue(mockAction);
+		mockActionInvocation.getProxy();
+		controlActionInvocation.setDefaultReturnValue(mockActionProxy);
+		mockActionInvocation.invoke();
+		controlActionInvocation.setDefaultReturnValue(Action.INPUT);
+		
+		
+		controlAction.replay();
+		controlActionProxy.replay();
+		controlActionInvocation.replay();
+		
+		ValidationInterceptor interceptor = new ValidationInterceptor();
+		String result = interceptor.intercept(mockActionInvocation);
+		
+		assertEquals(Action.INPUT, result);
+		controlAction.verify();
+		controlActionProxy.verify();
+		controlActionInvocation.verify();
+	}
+	
+	public void testPrefixMethodInvocation2() throws Exception {
+		MockControl controlAction = MockControl.createControl(ValidateAction.class);
+		ValidateAction mockAction = (ValidateAction) controlAction.getMock();
+		mockAction.validateSubmit();
+		controlAction.setVoidCallable(1);
+		mockAction.validate();
+		controlAction.setVoidCallable();
+		
+		MockControl controlActionProxy = MockControl.createControl(ActionProxy.class);
+		ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock();
+		mockActionProxy.getMethod();
+		controlActionProxy.setDefaultReturnValue("submit");
+		mockActionProxy.getActionName();
+                controlActionProxy.setDefaultReturnValue("something");
+		
+		MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class);
+		ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock();
+		mockActionInvocation.getAction();
+		controlActionInvocation.setDefaultReturnValue(mockAction);
+		mockActionInvocation.getProxy();
+		controlActionInvocation.setDefaultReturnValue(mockActionProxy);
+		mockActionInvocation.invoke();
+		controlActionInvocation.setReturnValue("okok");
+		
+		
+		controlAction.replay();
+		controlActionProxy.replay();
+		controlActionInvocation.replay();
+		
+		ValidationInterceptor interceptor = new ValidationInterceptor();
+		String result = interceptor.intercept(mockActionInvocation);
+		
+		assertEquals("okok", result);
+		controlAction.verify();
+		controlActionProxy.verify();
+		controlActionInvocation.verify();
+	}
+	
+	private interface ValidateAction extends Action, Validateable, ValidationAware {
+		void validateDoSave();
+		void validateSubmit();
+		String submit();
+    }
+}