Author: musachy
Date: Mon Mar 30 00:15:50 2009
New Revision: 759802

URL: http://svn.apache.org/viewvc?rev=759802&view=rev
Log:
Add XML support

Added:
    
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/DefaultOValValidationManager.java
    
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationManager.java
    
struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/SimpleFieldsXml.java
    
struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/org/apache/struts2/interceptor/SimpleFieldsXml-validation.xml
Modified:
    struts/sandbox/trunk/struts2-oval-plugin/pom.xml
    
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationInterceptor.java
    
struts/sandbox/trunk/struts2-oval-plugin/src/main/resources/struts-plugin.xml
    
struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/OValValidationInterceptorTest.java
    struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/oval-test.xml

Modified: struts/sandbox/trunk/struts2-oval-plugin/pom.xml
URL: 
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/pom.xml?rev=759802&r1=759801&r2=759802&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-oval-plugin/pom.xml (original)
+++ struts/sandbox/trunk/struts2-oval-plugin/pom.xml Mon Mar 30 00:15:50 2009
@@ -50,8 +50,14 @@
             <version>1.31</version>
         </dependency>
 
+        <dependency>
+            <groupId>com.thoughtworks.xstream</groupId>
+            <artifactId>xstream</artifactId>
+            <version>1.3.1</version>
+        </dependency>
+
         <!-- Testing -->
-         <dependency>
+        <dependency>
             <groupId>org.easymock</groupId>
             <artifactId>easymock</artifactId>
             <version>2.0</version>

Added: 
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/DefaultOValValidationManager.java
URL: 
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/DefaultOValValidationManager.java?rev=759802&view=auto
==============================================================================
--- 
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/DefaultOValValidationManager.java
 (added)
+++ 
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/DefaultOValValidationManager.java
 Mon Mar 30 00:15:50 2009
@@ -0,0 +1,139 @@
+package org.apache.struts2.interceptor;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.util.FileManager;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+import net.sf.oval.configuration.xml.XMLConfigurer;
+import net.sf.oval.configuration.Configurer;
+
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.HashMap;
+
+
+public class DefaultOValValidationManager implements OValValidationManager {
+    private static final Logger LOG = 
LoggerFactory.getLogger(DefaultOValValidationManager.class);
+
+    private static final String VALIDATION_CONFIG_SUFFIX = "-validation.xml";
+    private final Map<String, List<Configurer>> validatorCache = new 
HashMap<String, List<Configurer>>();
+    private final Map<String, Configurer> validatorFileCache = new 
HashMap<String, Configurer>();
+
+    public synchronized List<Configurer> getConfigurers(Class clazz, String 
context) {
+        final String validatorKey = buildValidatorKey(clazz, context);
+
+        if (validatorCache.containsKey(validatorKey)) {
+            if (FileManager.isReloadingConfigs()) {
+                validatorCache.put(validatorKey, buildXMLConfigurers(clazz, 
context, true, null));
+            }
+        } else {
+            validatorCache.put(validatorKey, buildXMLConfigurers(clazz, 
context, false, null));
+        }
+
+        // get the set of validator configs
+        return validatorCache.get(validatorKey);
+    }
+
+    protected static String buildValidatorKey(Class clazz, String context) {
+        StringBuilder sb = new StringBuilder(clazz.getName());
+        sb.append("/");
+        sb.append(context);
+        return sb.toString();
+    }
+
+    private List<Configurer> buildXMLConfigurers(Class clazz, String context, 
boolean checkFile, Set<String> checked) {
+        List<Configurer> xmlConfigurers = new ArrayList<Configurer>();
+
+        if (checked == null) {
+            checked = new TreeSet<String>();
+        } else if (checked.contains(clazz.getName())) {
+            return xmlConfigurers;
+        }
+
+        if (clazz.isInterface()) {
+            for (Class anInterface : clazz.getInterfaces()) {
+                xmlConfigurers.addAll(buildXMLConfigurers(anInterface, 
context, checkFile, checked));
+            }
+        } else {
+            if (!clazz.equals(Object.class)) {
+                
xmlConfigurers.addAll(buildXMLConfigurers(clazz.getSuperclass(), context, 
checkFile, checked));
+            }
+        }
+
+        // look for validators for implemented interfaces
+        for (Class anInterface1 : clazz.getInterfaces()) {
+            if (checked.contains(anInterface1.getName())) {
+                continue;
+            }
+
+            addIfNotNull(xmlConfigurers, 
buildClassValidatorConfigs(anInterface1, checkFile));
+
+            if (context != null) {
+                addIfNotNull(xmlConfigurers, 
buildAliasValidatorConfigs(anInterface1, context, checkFile));
+            }
+
+            checked.add(anInterface1.getName());
+        }
+
+        addIfNotNull(xmlConfigurers, buildClassValidatorConfigs(clazz, 
checkFile));
+
+        if (context != null) {
+            addIfNotNull(xmlConfigurers, buildAliasValidatorConfigs(clazz, 
context, checkFile));
+        }
+
+        checked.add(clazz.getName());
+
+        return xmlConfigurers;
+    }
+
+    protected void addIfNotNull(List<Configurer> configurers, Configurer 
configurer) {
+        if (configurer != null)
+            configurers.add(configurer);
+    }
+
+
+    protected XMLConfigurer buildAliasValidatorConfigs(Class aClass, String 
context, boolean checkFile) {
+        String fileName = aClass.getName().replace('.', '/') + "-" + context + 
VALIDATION_CONFIG_SUFFIX;
+
+        return loadFile(fileName, aClass, checkFile);
+    }
+
+    protected XMLConfigurer buildClassValidatorConfigs(Class aClass, boolean 
checkFile) {
+        String fileName = aClass.getName().replace('.', '/') + 
VALIDATION_CONFIG_SUFFIX;
+
+        return loadFile(fileName, aClass, checkFile);
+    }
+
+    protected XMLConfigurer loadFile(String fileName, Class clazz, boolean 
checkFile) {
+        if ((checkFile && FileManager.fileNeedsReloading(fileName, clazz)) || 
!validatorFileCache.containsKey(fileName)) {
+            java.io.InputStream is = null;
+
+            try {
+                is = FileManager.loadFile(fileName, clazz);
+
+                if (is != null) {
+                    if (LOG.isDebugEnabled())
+                        LOG.debug("Loading validation xml file [#0]", 
fileName);
+                    XMLConfigurer configurer = new XMLConfigurer();
+                    configurer.fromXML(is);
+                    validatorFileCache.put(fileName, configurer);
+                }
+            } finally {
+                if (is != null) {
+                    try {
+                        is.close();
+                    } catch (java.io.IOException e) {
+                        LOG.error("Unable to close input stream for [#0] ", e, 
fileName);
+                    }
+                }
+            }
+        } else {
+            return (XMLConfigurer) validatorFileCache.get(fileName);
+        }
+
+        return null;
+    }
+}
\ No newline at end of file

Modified: 
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationInterceptor.java
URL: 
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationInterceptor.java?rev=759802&r1=759801&r2=759802&view=diff
==============================================================================
--- 
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationInterceptor.java
 (original)
+++ 
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationInterceptor.java
 Mon Mar 30 00:15:50 2009
@@ -31,9 +31,10 @@
 import com.opensymphony.xwork2.util.logging.Logger;
 import com.opensymphony.xwork2.util.logging.LoggerFactory;
 import com.opensymphony.xwork2.util.ValueStack;
-import com.opensymphony.xwork2.util.reflection.ReflectionProvider;
 import net.sf.oval.Validator;
 import net.sf.oval.ConstraintViolation;
+import net.sf.oval.configuration.xml.XMLConfigurer;
+import net.sf.oval.configuration.Configurer;
 import net.sf.oval.context.FieldContext;
 import net.sf.oval.context.OValContext;
 import net.sf.oval.context.MethodReturnValueContext;
@@ -50,11 +51,17 @@
 public class OValValidationInterceptor extends MethodFilterInterceptor {
     private static final Logger LOG = 
LoggerFactory.getLogger(OValValidationInterceptor.class);
 
-    private final static String VALIDATE_PREFIX = "validate";
-    private final static String ALT_VALIDATE_PREFIX = "validateDo";
+    protected final static String VALIDATE_PREFIX = "validate";
+    protected final static String ALT_VALIDATE_PREFIX = "validateDo";
 
-    private boolean alwaysInvokeValidate = true;
-    private boolean programmatic = true;
+    protected boolean alwaysInvokeValidate = true;
+    protected boolean programmatic = true;
+    protected OValValidationManager validationManager;
+
+    @Inject
+    public void setValidationManager(OValValidationManager validationManager) {
+        this.validationManager = validationManager;
+    }
 
     /**
      * Determines if {...@link com.opensymphony.xwork2.Validateable}'s 
<code>validate()</code> should be called,
@@ -81,13 +88,14 @@
         ActionProxy proxy = invocation.getProxy();
         ValueStack valueStack = invocation.getStack();
         String methodName = proxy.getMethod();
+        String context = proxy.getActionName();
 
         if (LOG.isDebugEnabled()) {
             LOG.debug("Validating [#0/#1] with method [#2]", 
invocation.getProxy().getNamespace(), invocation.getProxy().getActionName(), 
methodName);
         }
 
         //OVal vallidatio (no XML yet)
-        performOValValidation(action, valueStack, methodName);
+        performOValValidation(action, valueStack, methodName, context);
 
         //Validatable.valiedate() and validateX()
         performProgrammaticValidation(invocation, action);
@@ -109,15 +117,13 @@
                 PrefixMethodInvocationUtil.invokePrefixMethod(
                         invocation,
                         new String[]{VALIDATE_PREFIX, ALT_VALIDATE_PREFIX});
-            }
-            catch (Exception e) {
+            } 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();
             }
@@ -129,10 +135,14 @@
         }
     }
 
-    protected void performOValValidation(Object action, ValueStack valueStack, 
String methodName) throws NoSuchMethodException {
-        Validator validator = new Validator();
+    protected void performOValValidation(Object action, ValueStack valueStack, 
String methodName, String context) throws NoSuchMethodException {
+        Class clazz = action.getClass();
+        //read validation from xmls
+        List<Configurer> configurers = validationManager.getConfigurers(clazz, 
context);
+
+        Validator validator = configurers.isEmpty() ? new Validator() : new 
Validator(configurers);
         //if the method is annotated with a @Profiles annotation, use those 
profiles
-        Method method = action.getClass().getMethod(methodName, new Class[0]);
+        Method method = clazz.getMethod(methodName, new Class[0]);
         if (method != null) {
             Profiles profiles = method.getAnnotation(Profiles.class);
             if (profiles != null) {
@@ -167,7 +177,7 @@
                 if (isActionError(violation))
                     validatorContext.addActionError(message);
                 else {
-                    String className = action.getClass().getName();
+                    String className = clazz.getName();
                     //the default OVal message shows the field name as 
ActionClass.fieldName
                     message = StringUtils.removeStart(message, className + 
".");
                     
validatorContext.addFieldError(extractFieldName(violation), message);
@@ -176,6 +186,7 @@
         }
     }
 
+
     /**
      * Get field name, used to add the validation error to fieldErrors
      */

Added: 
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationManager.java
URL: 
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationManager.java?rev=759802&view=auto
==============================================================================
--- 
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationManager.java
 (added)
+++ 
struts/sandbox/trunk/struts2-oval-plugin/src/main/java/org/apache/struts2/interceptor/OValValidationManager.java
 Mon Mar 30 00:15:50 2009
@@ -0,0 +1,51 @@
+package org.apache.struts2.interceptor;
+
+import net.sf.oval.configuration.xml.XMLConfigurer;
+import net.sf.oval.configuration.Configurer;
+
+import java.util.List;
+
+
+public interface OValValidationManager {
+    /**
+     * <p>This method 'collects' all the validator configurations for a given
+     * action invocation.</p>
+     * <p/>
+     * <p>It will traverse up the class hierarchy looking for validators for 
every super class
+     * and directly implemented interface of the current action, as well as 
adding validators for
+     * any alias of this invocation. Nifty!</p>
+     * <p/>
+     * <p>Given the following class structure:
+     * <pre>
+     *   interface Thing;
+     *   interface Animal extends Thing;
+     *   interface Quadraped extends Animal;
+     *   class AnimalImpl implements Animal;
+     *   class QuadrapedImpl extends AnimalImpl implements Quadraped;
+     *   class Dog extends QuadrapedImpl;
+     * </pre></p>
+     * <p/>
+     * <p>This method will look for the following config files for Dog:
+     * <pre>
+     *   Animal
+     *   Animal-context
+     *   AnimalImpl
+     *   AnimalImpl-context
+     *   Quadraped
+     *   Quadraped-context
+     *   QuadrapedImpl
+     *   QuadrapedImpl-context
+     *   Dog
+     *   Dog-context
+     * </pre></p>
+     * <p/>
+     * <p>Note that the validation rules for Thing is never looked for because 
no class in the
+     * hierarchy directly implements Thing.</p>
+     *
+     * @param clazz     the Class to look up validators for.
+     * @param context   the context to use when looking up validators.
+     *                  updated.
+     * @return a list of xml configurers for the given class and context.
+     */
+    List<Configurer> getConfigurers(Class clazz, String context);
+}

Modified: 
struts/sandbox/trunk/struts2-oval-plugin/src/main/resources/struts-plugin.xml
URL: 
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/src/main/resources/struts-plugin.xml?rev=759802&r1=759801&r2=759802&view=diff
==============================================================================
--- 
struts/sandbox/trunk/struts2-oval-plugin/src/main/resources/struts-plugin.xml 
(original)
+++ 
struts/sandbox/trunk/struts2-oval-plugin/src/main/resources/struts-plugin.xml 
Mon Mar 30 00:15:50 2009
@@ -26,6 +26,8 @@
         "http://struts.apache.org/dtds/struts-2.0.dtd";>
 
 <struts>
+    <bean type="org.apache.struts2.interceptor.OValValidationManager" 
class="org.apache.struts2.interceptor.DefaultOValValidationManager" />
+    
     <package name="oval-default" extends="struts-default">
            <interceptors>
                <interceptor name="ovalValidation" 
class="org.apache.struts2.interceptor.OValValidationInterceptor" />

Modified: 
struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/OValValidationInterceptorTest.java
URL: 
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/OValValidationInterceptorTest.java?rev=759802&r1=759801&r2=759802&view=diff
==============================================================================
--- 
struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/OValValidationInterceptorTest.java
 (original)
+++ 
struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/OValValidationInterceptorTest.java
 Mon Mar 30 00:15:50 2009
@@ -30,6 +30,17 @@
 import java.util.Map;
 
 public class OValValidationInterceptorTest extends XWorkTestCase {
+    public void testSimpleFieldsXML() throws Exception {
+        ActionProxy baseActionProxy = 
actionProxyFactory.createActionProxy("oval", "simpleFieldsXML", null, null);
+        baseActionProxy.execute();
+
+        Map<String, List<String>> fieldErrors = ((ValidationAware) 
baseActionProxy.getAction()).getFieldErrors();
+        assertNotNull(fieldErrors);
+        assertEquals(2, fieldErrors.size());
+        assertValue(fieldErrors, "firstName", Arrays.asList("firstName cannot 
be null"));
+        assertValue(fieldErrors, "lastName", Arrays.asList("lastName cannot be 
empty"));
+    }
+
     public void testSimpleField() throws Exception {
         ActionProxy baseActionProxy = 
actionProxyFactory.createActionProxy("oval", "simpleField", null, null);
         baseActionProxy.execute();

Added: 
struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/SimpleFieldsXml.java
URL: 
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/SimpleFieldsXml.java?rev=759802&view=auto
==============================================================================
--- 
struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/SimpleFieldsXml.java
 (added)
+++ 
struts/sandbox/trunk/struts2-oval-plugin/src/test/java/org/apache/struts2/interceptor/SimpleFieldsXml.java
 Mon Mar 30 00:15:50 2009
@@ -0,0 +1,29 @@
+package org.apache.struts2.interceptor;
+
+import com.opensymphony.xwork2.ActionSupport;
+import net.sf.oval.constraint.NotEmpty;
+import net.sf.oval.constraint.NotNull;
+
+public class SimpleFieldsXml extends ActionSupport {
+    @NotNull
+    private String firstName;
+
+    @NotEmpty
+    private String lastName = "";
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+}

Added: 
struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/org/apache/struts2/interceptor/SimpleFieldsXml-validation.xml
URL: 
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/org/apache/struts2/interceptor/SimpleFieldsXml-validation.xml?rev=759802&view=auto
==============================================================================
--- 
struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/org/apache/struts2/interceptor/SimpleFieldsXml-validation.xml
 (added)
+++ 
struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/org/apache/struts2/interceptor/SimpleFieldsXml-validation.xml
 Mon Mar 30 00:15:50 2009
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+<!DOCTYPE oval PUBLIC
+   "-//OVal/OVal Configuration DTD 1.3//EN"
+   "http://oval.sourceforge.net/oval-configuration-1.3.dtd";>
+-->
+<oval xmlns="http://oval.sf.net/oval-configuration"; 
xmlns:xsi="http://http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="http://oval.sf.net/oval-configuration 
http://oval.sourceforge.net/oval-configuration-1.3.xsd";
+>
+       <!-- define a constraint set -->
+       <constraintSet id="firstName">
+               <notNull message="{context} is null" />
+       </constraintSet>
+</oval>
\ No newline at end of file

Modified: 
struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/oval-test.xml
URL: 
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/oval-test.xml?rev=759802&r1=759801&r2=759802&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/oval-test.xml 
(original)
+++ struts/sandbox/trunk/struts2-oval-plugin/src/test/resources/oval-test.xml 
Mon Mar 30 00:15:50 2009
@@ -4,6 +4,7 @@
         >
 
 <xwork>
+    <bean type="org.apache.struts2.interceptor.OValValidationManager" 
class="org.apache.struts2.interceptor.DefaultOValValidationManager" />
     <package namespace="oval" name="oval-test">
         <result-types>
             <result-type name="void" 
class="org.apache.struts2.interceptor.VoidResult"/>
@@ -12,6 +13,10 @@
             <interceptor name="ovalValidation" 
class="org.apache.struts2.interceptor.OValValidationInterceptor"/>
         </interceptors>
 
+        <action name="simpleFieldsXML" 
class="org.apache.struts2.interceptor.SimpleFieldsXml">
+            <interceptor-ref name="ovalValidation"/>
+            <result type="void"></result>
+        </action>
         <action name="simpleField" 
class="org.apache.struts2.interceptor.SimpleField">
             <interceptor-ref name="ovalValidation"/>
             <result type="void"></result>


Reply via email to