Author: musachy
Date: Fri May 22 12:58:29 2009
New Revision: 777502

URL: http://svn.apache.org/viewvc?rev=777502&view=rev
Log:
WW-3135 OVal Plugin doesn't add field errors for "subfields"

patch provided by rdk@

Added:
    
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/MemberObject.java
    
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/ModelDrivenAction.java
    
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/domain/
    
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/domain/Address.java
    
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/domain/Person.java
Modified:
    
struts/struts2/trunk/plugins/oval/src/main/java/org/apache/struts2/oval/interceptor/OValValidationInterceptor.java
    
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/OValValidationInterceptorTest.java
    struts/struts2/trunk/plugins/oval/src/test/resources/oval-test.xml

Modified: 
struts/struts2/trunk/plugins/oval/src/main/java/org/apache/struts2/oval/interceptor/OValValidationInterceptor.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/oval/src/main/java/org/apache/struts2/oval/interceptor/OValValidationInterceptor.java?rev=777502&r1=777501&r2=777502&view=diff
==============================================================================
--- 
struts/struts2/trunk/plugins/oval/src/main/java/org/apache/struts2/oval/interceptor/OValValidationInterceptor.java
 (original)
+++ 
struts/struts2/trunk/plugins/oval/src/main/java/org/apache/struts2/oval/interceptor/OValValidationInterceptor.java
 Fri May 22 12:58:29 2009
@@ -24,6 +24,7 @@
 import com.opensymphony.xwork2.interceptor.PrefixMethodInvocationUtil;
 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.ActionProxy;
+import com.opensymphony.xwork2.ModelDriven;
 import com.opensymphony.xwork2.Validateable;
 import com.opensymphony.xwork2.inject.Inject;
 import com.opensymphony.xwork2.validator.ValidatorContext;
@@ -38,6 +39,9 @@
 import net.sf.oval.context.OValContext;
 import net.sf.oval.context.MethodReturnValueContext;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.lang.reflect.Method;
 import java.lang.reflect.Field;
@@ -167,7 +171,11 @@
 
         //perform validation
         List<ConstraintViolation> violations = validator.validate(action);
-        if (violations != null) {
+        addValidationErrors(violations.toArray(new ConstraintViolation[0]), 
action, valueStack, null);
+    }
+
+       private void addValidationErrors(ConstraintViolation[] violations, 
Object action, ValueStack valueStack, String parentFieldname) {
+               if (violations != null) {
             ValidatorContext validatorContext = new 
DelegatingValidatorContext(action);
             for (ConstraintViolation violation : violations) {
                 //translate message
@@ -182,15 +190,34 @@
                     valueStack.pop();
                 }
 
-                if (isActionError(violation))
+                if (isActionError(violation)) {
+                       LOG.debug("Adding action error '#0'", message);
                     validatorContext.addActionError(message);
-                else {
+                } else {
                     ValidationError validationError = 
buildValidationError(violation, message);
-                    
validatorContext.addFieldError(validationError.getFieldName(), 
validationError.getMessage());
+
+                    // build field name
+                    String fieldName = validationError.getFieldName();
+                    if (parentFieldname != null) {
+                       fieldName = parentFieldname + "." + fieldName;
+                    }
+
+                    LOG.debug("Adding field error [#0] with message '#1'", 
fieldName, validationError.getMessage());
+                    validatorContext.addFieldError(fieldName, 
validationError.getMessage());
+
+                    // don't add "model." prefix to fields of model in model 
driven action
+                    if ((action instanceof ModelDriven) && 
"model".equals(fieldName)) {
+                       fieldName = null;
+                    }
+
+                    // add violations of member object fields
+                    addValidationErrors(violation.getCauses(), action, 
valueStack, fieldName);
                 }
             }
         }
-    }
+       }
+
+
 
 
     /**

Added: 
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/MemberObject.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/MemberObject.java?rev=777502&view=auto
==============================================================================
--- 
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/MemberObject.java
 (added)
+++ 
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/MemberObject.java
 Fri May 22 12:58:29 2009
@@ -0,0 +1,18 @@
+package org.apache.struts2.oval.interceptor;
+
+import net.sf.oval.constraint.AssertValid;
+
+import org.apache.struts2.oval.interceptor.domain.Person;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class MemberObject extends ActionSupport {
+
+       @AssertValid
+       private Person person = new Person();
+
+       public Person getPerson() {
+               return person;
+       }
+
+}

Added: 
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/ModelDrivenAction.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/ModelDrivenAction.java?rev=777502&view=auto
==============================================================================
--- 
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/ModelDrivenAction.java
 (added)
+++ 
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/ModelDrivenAction.java
 Fri May 22 12:58:29 2009
@@ -0,0 +1,19 @@
+package org.apache.struts2.oval.interceptor;
+
+import net.sf.oval.constraint.AssertValid;
+
+import org.apache.struts2.oval.interceptor.domain.Person;
+
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.ModelDriven;
+
+public class ModelDrivenAction extends ActionSupport implements 
ModelDriven<Person> {
+
+       @AssertValid
+       private Person model = new Person();
+
+       public Person getModel() {
+               return model;
+       }
+
+}

Modified: 
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/OValValidationInterceptorTest.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/OValValidationInterceptorTest.java?rev=777502&r1=777501&r2=777502&view=diff
==============================================================================
--- 
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/OValValidationInterceptorTest.java
 (original)
+++ 
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/OValValidationInterceptorTest.java
 Fri May 22 12:58:29 2009
@@ -82,7 +82,7 @@
     public void testSlashesInNameWithWildcardsHitsCache() throws Exception {
         ActionProxy baseActionProxy = 
actionProxyFactory.createActionProxy("oval", "simpleFieldsXML/test", null, 
null);
         baseActionProxy.execute();
-               
+
         ActionProxy baseActionProxy2 = 
actionProxyFactory.createActionProxy("oval", "simpleFieldsXML/test2", null, 
null);
         baseActionProxy2.execute();
 
@@ -247,6 +247,40 @@
     }
 
 
+    public void testModelDrivenAction() throws Exception {
+        ActionProxy baseActionProxy = 
actionProxyFactory.createActionProxy("oval", "modelDrivenAction", null, null);
+        ModelDrivenAction action = (ModelDrivenAction) 
baseActionProxy.getAction();
+        action.getModel().setName(null);
+        action.getModel().setEmail(null);
+        action.getModel().getAddress().setStreet("short");
+        baseActionProxy.execute();
+
+        Map<String, List<String>> fieldErrors = ((ValidationAware) 
baseActionProxy.getAction()).getFieldErrors();
+        assertNotNull(fieldErrors);
+        assertEquals(5, fieldErrors.size()); // 5: as there will be field 
errors for 'model' and 'address' themselves
+        assertValue(fieldErrors, "name", Arrays.asList("name cannot be null"));
+        assertValue(fieldErrors, "email", Arrays.asList("email cannot be 
null"));
+        assertValue(fieldErrors, "address.street", Arrays.asList("street 
cannot be smaller than 7 characters"));
+
+    }
+
+    public void testMemberObject() throws Exception {
+       ActionProxy baseActionProxy = 
actionProxyFactory.createActionProxy("oval", "memberObject", null, null);
+       MemberObject action = (MemberObject) baseActionProxy.getAction();
+       action.getPerson().setName(null);
+       action.getPerson().setEmail(null);
+       action.getPerson().getAddress().setStreet("short");
+       baseActionProxy.execute();
+
+       Map<String, List<String>> fieldErrors = ((ValidationAware) 
baseActionProxy.getAction()).getFieldErrors();
+       assertNotNull(fieldErrors);
+       assertEquals(5, fieldErrors.size()); // 5: as there will be field 
errors for 'person' and 'person.address' themselves
+       assertValue(fieldErrors, "person.name", Arrays.asList("name cannot be 
null"));
+       assertValue(fieldErrors, "person.email", Arrays.asList("email cannot be 
null"));
+       assertValue(fieldErrors, "person.address.street", Arrays.asList("street 
cannot be smaller than 7 characters"));
+    }
+
+
     private void assertValue(Map<String, List<String>> map, String key, 
List<String> expectedValues) {
         assertNotNull(map);
         assertNotNull(key);

Added: 
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/domain/Address.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/domain/Address.java?rev=777502&view=auto
==============================================================================
--- 
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/domain/Address.java
 (added)
+++ 
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/domain/Address.java
 Fri May 22 12:58:29 2009
@@ -0,0 +1,18 @@
+package org.apache.struts2.oval.interceptor.domain;
+
+import net.sf.oval.constraint.MinLength;
+
+public class Address {
+
+       @MinLength(value=7)
+       private String street;
+
+       public void setStreet(String street) {
+               this.street = street;
+       }
+
+       public String getStreet() {
+               return street;
+       }
+
+}

Added: 
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/domain/Person.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/domain/Person.java?rev=777502&view=auto
==============================================================================
--- 
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/domain/Person.java
 (added)
+++ 
struts/struts2/trunk/plugins/oval/src/test/java/org/apache/struts2/oval/interceptor/domain/Person.java
 Fri May 22 12:58:29 2009
@@ -0,0 +1,43 @@
+package org.apache.struts2.oval.interceptor.domain;
+
+import javax.persistence.Column;
+
+import net.sf.oval.constraint.AssertValid;
+import net.sf.oval.constraint.NotNull;
+
+public class Person {
+
+       @Column(nullable=false)
+       private String name;
+
+       @NotNull
+       private String email;
+
+       @AssertValid
+       private Address address = new Address();
+
+       public void setEmail(String email) {
+               this.email = email;
+       }
+
+       public String getEmail() {
+               return email;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setAddress(Address address) {
+               this.address = address;
+       }
+
+       public Address getAddress() {
+               return address;
+       }
+
+}

Modified: struts/struts2/trunk/plugins/oval/src/test/resources/oval-test.xml
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/oval/src/test/resources/oval-test.xml?rev=777502&r1=777501&r2=777502&view=diff
==============================================================================
--- struts/struts2/trunk/plugins/oval/src/test/resources/oval-test.xml 
(original)
+++ struts/struts2/trunk/plugins/oval/src/test/resources/oval-test.xml Fri May 
22 12:58:29 2009
@@ -7,7 +7,7 @@
     <bean type="org.apache.struts2.oval.interceptor.OValValidationManager" 
class="org.apache.struts2.oval.interceptor.DummyDefaultOValValidationManager"/>
     <constant name="struts.enable.SlashesInActionNames" value="true"/>
     <constant name="struts.oval.validateJPAAnnotations" value="false" />
-    
+
     <package namespace="oval" name="oval-test">
         <result-types>
             <result-type name="void" 
class="org.apache.struts2.oval.interceptor.VoidResult"/>
@@ -82,5 +82,17 @@
             </interceptor-ref>
             <result type="void"></result>
         </action>
+        <action name="modelDrivenAction" 
class="org.apache.struts2.oval.interceptor.ModelDrivenAction">
+            <interceptor-ref name="ovalValidation">
+              <param name="validateJPAAnnotations">true</param>
+            </interceptor-ref>
+            <result type="void"></result>
+        </action>
+        <action name="memberObject" 
class="org.apache.struts2.oval.interceptor.MemberObject">
+            <interceptor-ref name="ovalValidation">
+              <param name="validateJPAAnnotations">true</param>
+            </interceptor-ref>
+            <result type="void"></result>
+        </action>
     </package>
 </xwork>


Reply via email to