Commits

Anonymous committed db71d4d

XW-571 nested visitor validators break short-circuit functionality
o ported fix from xwork 1.2 branch

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

  • Participants
  • Parent commits ac87374

Comments (0)

Files changed (2)

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

 
 import com.opensymphony.xwork2.ObjectFactory;
 import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.validator.validators.VisitorFieldValidator;
 import com.opensymphony.xwork2.inject.Inject;
 import com.opensymphony.xwork2.util.FileManager;
 import com.opensymphony.xwork2.util.ValueStack;
 
                 if (validator instanceof FieldValidator) {
                     fValidator = (FieldValidator) validator;
-                    fullFieldName = fValidator.getValidatorContext().getFullFieldName(fValidator.getFieldName());
+                    fullFieldName = new InternalValidatorContextWrapper(fValidator.getValidatorContext()).getFullFieldName(fValidator.getFieldName());
 
                     if ((shortcircuitedFields != null) && shortcircuitedFields.contains(fullFieldName)) {
                         if (LOG.isDebugEnabled()) {
     }
 
 
+
+    /**
+     * An {@link com.opensymphony.xwork2.validator.ValidatorContext} wrapper that
+     * returns the full field name
+     * {@link com.opensymphony.xwork2.validator.AbstractActionValidatorManager.InternalValidatorContextWrapper#getFullFieldName(String)}
+     * by consulting it's parent if its an {@link com.opensymphony.xwork.2validator.validators.VisitorFieldValidator.AppendingValidatorContext}.
+     * <p/>
+     * Eg. if we have nested Visitor
+     * AddressVisitor nested inside PersonVisitor, when using the normal #getFullFieldName, we will get
+     * "address.somefield", we lost the parent, with this wrapper, we will get "person.address.somefield".
+     * This is so that the key is used to register errors, so that we don't screw up short-curcuit feature
+     * when using nested visitor. See XW-571 (nested visitor validators break short-circuit functionality)
+     * at http://jira.opensymphony.com/browse/XW-571
+     */
+    protected class InternalValidatorContextWrapper {
+        private ValidatorContext validatorContext = null;
+
+        InternalValidatorContextWrapper(ValidatorContext validatorContext) {
+            this.validatorContext = validatorContext;
+        }
+
+        /**
+         * Get the full field name by consulting the parent, so that when we are using nested visitors (
+         * visitor nested inside visitor etc.) we still get the full field name including its parents.
+         * See XW-571 for more details.
+         * @param field
+         * @return String
+         */
+        public String getFullFieldName(String field) {
+            if (validatorContext instanceof VisitorFieldValidator.AppendingValidatorContext) {
+                VisitorFieldValidator.AppendingValidatorContext appendingValidatorContext =
+                        (VisitorFieldValidator.AppendingValidatorContext) validatorContext;
+                return appendingValidatorContext.getFullFieldNameFromParent(field);
+            }
+            return validatorContext.getFullFieldName(field);
+        }
+
+    }    
 }

src/test/com/opensymphony/xwork2/validator/ActionValidatorManagerTest.java

         assertTrue(action.getFieldErrors().containsKey("customer.address.street"));
         assertEquals(((List)action.getFieldErrors().get("customer.address.street")).size(), 1);
         assertTrue(action.getFieldErrors().containsKey("customer.address.pobox"));
-        //assertEquals(((List)action.getFieldErrors().get("customer.address.pobox")).size(), 2);
-
-        for (Iterator i = action.getFieldErrors().keySet().iterator(); i.hasNext(); ) {
-            System.out.println(i.next());
-        }
-
-
-        for (Iterator i = ((List)action.getFieldErrors().get("customer.address.street")).iterator(); i.hasNext();) {
-            System.out.println("**"+i.next());
-        }
-        for (Iterator i = ((List)action.getFieldErrors().get("customer.address.pobox")).iterator(); i.hasNext();) {
-            System.out.println("**"+i.next());
-        }
-
+        assertEquals(((List)action.getFieldErrors().get("customer.address.pobox")).size(), 2);
     }
 
     private class MockAction extends ActionSupport {