Repository: struts
Updated Branches:
  refs/heads/master afb0c2a22 -> ee562666a


Form.getValidators does not respect validateAnnotatedMethodOnly flag

WW-4139 removed method name from getValidators call.  While this works
fine for a case mentioned in that ticket it fails to account for a case
when
dynamicMethodCalls and validateAnnotatedMethodOnly are used. Without
method name actionValidatorManager.getValidators returns all validators
defined for a given field.
Expected behavior for dynamicMethodCalls with
validateAnnotatedMethodOnly case is to return validators for a given
field defined at the method level.


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/ee562666
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/ee562666
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/ee562666

Branch: refs/heads/master
Commit: ee562666abf01faf4dd73f65c9f4d77b079423d1
Parents: afb0c2a
Author: Lukasz Racon <lra...@jgsullivan.com>
Authored: Mon Nov 9 17:02:02 2015 -0600
Committer: Lukasz Racon <lra...@jgsullivan.com>
Committed: Mon Nov 9 17:02:02 2015 -0600

----------------------------------------------------------------------
 .../org/apache/struts2/components/Form.java     | 25 +++++++-
 .../java/org/apache/struts2/TestAction.java     | 24 ++++++++
 .../org/apache/struts2/components/FormTest.java | 60 +++++++++++++++++---
 3 files changed, 101 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/ee562666/core/src/main/java/org/apache/struts2/components/Form.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/struts2/components/Form.java 
b/core/src/main/java/org/apache/struts2/components/Form.java
index 52aaa7c..6b2e478 100644
--- a/core/src/main/java/org/apache/struts2/components/Form.java
+++ b/core/src/main/java/org/apache/struts2/components/Form.java
@@ -35,6 +35,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.struts2.dispatcher.mapper.ActionMapping;
 import org.apache.struts2.views.annotations.StrutsTag;
 import org.apache.struts2.views.annotations.StrutsTagAttribute;
+import org.apache.struts2.views.jsp.TagUtils;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -277,7 +278,12 @@ public class Form extends ClosingUIBean {
         ActionMapping mapping = 
actionMapper.getMappingFromActionName(formActionValue);
         String actionName = mapping.getName();
 
-        List<Validator> actionValidators = 
actionValidatorManager.getValidators(actionClass, actionName);
+        String methodName = null;
+        if (isValidateAnnotatedMethodOnly(actionName)) {
+            methodName = mapping.getMethod();
+        }
+        
+        List<Validator> actionValidators = 
actionValidatorManager.getValidators(actionClass, actionName, methodName);
         List<Validator> validators = new ArrayList<>();
 
         findFieldValidators(name, actionClass, actionName, actionValidators, 
validators, "");
@@ -285,6 +291,23 @@ public class Form extends ClosingUIBean {
         return validators;
     }
 
+    private boolean isValidateAnnotatedMethodOnly(String actionName) {
+        RuntimeConfiguration runtimeConfiguration = 
configuration.getRuntimeConfiguration();
+        String actionNamespace = TagUtils.buildNamespace(actionMapper, stack, 
request);
+        ActionConfig actionConfig = 
runtimeConfiguration.getActionConfig(actionNamespace, actionName);
+
+        if (actionConfig != null) {
+            List<InterceptorMapping> interceptors = 
actionConfig.getInterceptors();
+            for (InterceptorMapping interceptorMapping : interceptors) {
+                if 
(ValidationInterceptor.class.isInstance(interceptorMapping.getInterceptor())) {
+                    ValidationInterceptor validationInterceptor = 
(ValidationInterceptor) interceptorMapping.getInterceptor();
+                    return 
validationInterceptor.isValidateAnnotatedMethodOnly();
+                }
+            }
+        }
+        return false;
+    }
+
     private void findFieldValidators(String name, Class actionClass, String 
actionName,
                                      List<Validator> validatorList, 
List<Validator> resultValidators, String prefix) {
 

http://git-wip-us.apache.org/repos/asf/struts/blob/ee562666/core/src/test/java/org/apache/struts2/TestAction.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/struts2/TestAction.java 
b/core/src/test/java/org/apache/struts2/TestAction.java
index dde13e5..8d87588 100644
--- a/core/src/test/java/org/apache/struts2/TestAction.java
+++ b/core/src/test/java/org/apache/struts2/TestAction.java
@@ -24,6 +24,10 @@ package org.apache.struts2;
 import com.opensymphony.xwork2.Action;
 import com.opensymphony.xwork2.ActionSupport;
 import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.validator.annotations.RequiredFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
+import com.opensymphony.xwork2.validator.annotations.Validations;
+import com.opensymphony.xwork2.validator.annotations.ValidatorType;
 import org.apache.struts2.views.jsp.ui.User;
 
 import java.util.*;
@@ -177,6 +181,26 @@ public class TestAction extends ActionSupport {
         return result;
     }
 
+    @Validations(
+            requiredFields = {
+                       @RequiredFieldValidator(type = ValidatorType.SIMPLE, 
fieldName = "status", message = "You must enter a value for field.")
+            },
+            requiredStrings = {
+                       @RequiredStringValidator(type = ValidatorType.SIMPLE, 
fieldName = "result", message = "You must enter a value for field.")
+            }
+    )
+    public String annotatedExecute1() throws Exception {
+        return Action.SUCCESS;
+    }
+    @Validations(
+            requiredFields = {
+                       @RequiredFieldValidator(type = ValidatorType.SIMPLE, 
fieldName = "status", message = "You must enter a value for field.")
+            }
+    )
+    public String annotatedExecute2() throws Exception {
+        return Action.SUCCESS;
+    }
+
     public String executeThrowsException() throws Exception {
         throw new StrutsException("something went wrong!");
     }

http://git-wip-us.apache.org/repos/asf/struts/blob/ee562666/core/src/test/java/org/apache/struts2/components/FormTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/struts2/components/FormTest.java 
b/core/src/test/java/org/apache/struts2/components/FormTest.java
index f1611f2..86148f7 100644
--- a/core/src/test/java/org/apache/struts2/components/FormTest.java
+++ b/core/src/test/java/org/apache/struts2/components/FormTest.java
@@ -26,35 +26,76 @@ import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.ActionProxy;
 import com.opensymphony.xwork2.config.entities.ActionConfig;
+import com.opensymphony.xwork2.config.entities.InterceptorMapping;
+import com.opensymphony.xwork2.validator.ValidationInterceptor;
 import com.opensymphony.xwork2.validator.validators.RequiredFieldValidator;
+import com.opensymphony.xwork2.validator.validators.RequiredStringValidator;
+import org.apache.struts2.dispatcher.mapper.ActionMapper;
+import org.apache.struts2.dispatcher.mapper.DefaultActionMapper;
 import org.apache.struts2.TestAction;
 import org.apache.struts2.views.jsp.AbstractUITagTest;
 import org.easymock.EasyMock;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * <code>FormTest</code>
  *
  */
 public class FormTest extends AbstractUITagTest {
-
+       private ValidationInterceptor validationInterceptor;
 
     public void testTestFormGetValidators() {
-        Form form = new Form(stack, request, response);
+        checkValidateAnnotatedMethodOnly(false, null, 1, 2, 1);
+    }
+    public void testAnnotatedFormGetValidators() {
+        checkValidateAnnotatedMethodOnly(true, null, 1, 2, 1);
+    }
+    public void testValidateAnnotatedMethodOnlyGetValidators1() {
+        checkValidateAnnotatedMethodOnly(true, "annotatedExecute1", 0, 1, 1);
+    }
+    public void testValidateAnnotatedMethodOnlyGetValidators2() {
+        checkValidateAnnotatedMethodOnly(true, "annotatedExecute2", 0, 1, 0);
+    }
+
+    private void checkValidateAnnotatedMethodOnly(boolean 
validateAnnotatedMethodOnly, String methodName,
+               int expectedFooValidators, int expectedStatusValidators, int 
expectedResultValidators) {
+               Form form = new Form(stack, request, response);
         container.inject(form);
         form.getParameters().put("actionClass", TestAction.class);
-        form.setAction("actionName");
+
+        form.setAction("actionName" + (methodName != null ? "!" + methodName : 
""));
+        
validationInterceptor.setValidateAnnotatedMethodOnly(validateAnnotatedMethodOnly);
+
         List v = form.getValidators("foo");
-        assertEquals(1, v.size());
-        assertEquals(RequiredFieldValidator.class, v.get(0).getClass());
-    }
+        assertEquals(expectedFooValidators, v.size());
+        for (Object validator : v) {
+               assertEquals(RequiredFieldValidator.class, 
validator.getClass());
+               }
+
+        v = form.getValidators("status");
+        assertEquals(expectedStatusValidators, v.size());
+        for (Object validator : v) {
+               assertEquals(RequiredFieldValidator.class, 
validator.getClass());
+               }
+
+        v = form.getValidators("result");
+        assertEquals(expectedResultValidators, v.size());
+        for (Object validator : v) {
+               assertEquals(RequiredStringValidator.class, 
validator.getClass());
+               }
+       }
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        validationInterceptor = new ValidationInterceptor();
+        validationInterceptor.setIncludeMethods("*");
 
-        ActionConfig config = new ActionConfig.Builder("", "name", "").build();
+        ActionConfig config = new ActionConfig.Builder("", "name", "")
+               .addInterceptor(new InterceptorMapping("validationInterceptor", 
validationInterceptor))
+               .build();
         ActionInvocation invocation = 
EasyMock.createNiceMock(ActionInvocation.class);
         ActionProxy proxy = EasyMock.createNiceMock(ActionProxy.class);
 
@@ -66,6 +107,11 @@ public class FormTest extends AbstractUITagTest {
         
         EasyMock.replay(invocation);
         EasyMock.replay(proxy);
+
+        Map<String, ActionConfig> defaultNamespace = 
configuration.getRuntimeConfiguration().getActionConfigs().get("");
+        defaultNamespace.put("actionName", config);
+
+        ((DefaultActionMapper) 
container.getInstance(ActionMapper.class)).setAllowDynamicMethodCalls("true");
         
         ActionContext.getContext().setActionInvocation(invocation);
     }

Reply via email to