Commits

Anonymous committed b6aa065

o AnnotatonValidationInterceptor is no longer required. Retrieving the correct instance of ActionValidatorManager is handled via ActionValidatorManagerFactory
o supported property methods: is/has/get/set (via regexp)

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

Comments (0)

Files changed (3)

tiger/src/java/com/opensymphony/xwork/validator/AnnotationActionValidatorManager.java

  */
 package com.opensymphony.xwork.validator;
 
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
  * @author jepjep
  * @version $Id$
  */
-public class AnnotationActionValidatorManager {
+public class AnnotationActionValidatorManager extends ActionValidatorManager {
 
 
-    /** The file suffix for any validation file. */
+    /**
+     * The file suffix for any validation file.
+     */
     protected static final String VALIDATION_CONFIG_SUFFIX = "-validation.xml";
 
     private static final Map validatorCache = Collections.synchronizedMap(new HashMap());
     private static final Map validatorFileCache = Collections.synchronizedMap(new HashMap());
-    private static final Log LOG = LogFactory.getLog(ActionValidatorManager.class);
+    private static final Log LOG = LogFactory.getLog(AnnotationActionValidatorManager.class);
 
     /**
      * Returns a list of validators for the given class and context. This is the primary
      * lookup method for validators.
      *
-     * @param clazz the class to lookup.
+     * @param clazz   the class to lookup.
      * @param context the context of the action class - can be <tt>null</tt>.
      * @return a list of all validators for the given class and context.
      */
 
         // create clean instances of the validators for the caller's use
         ArrayList validators = new ArrayList(cfgs.size());
-        for (Iterator iterator = cfgs.iterator(); iterator.hasNext(); ) {
+        for (Iterator iterator = cfgs.iterator(); iterator.hasNext();) {
             ValidatorConfig cfg = (ValidatorConfig) iterator.next();
             Validator validator = ValidatorFactory.getValidator(cfg);
             validators.add(validator);
     /**
      * Validates the given object using action and its context.
      *
-     * @param object the action to validate.
+     * @param object  the action to validate.
      * @param context the action's context.
      * @throws ValidationException if an error happens when validating the action.
      */
     /**
      * Validates an action give its context and a validation context.
      *
-     * @param object the action to validate.
-     * @param context the action's context.
+     * @param object           the action to validate.
+     * @param context          the action's context.
      * @param validatorContext
      * @throws ValidationException if an error happens when validating the action.
      */
                 }
             }
 
-            if (validator instanceof ShortCircuitableValidator && ((ShortCircuitableValidator) validator).isShortCircuit()) {
+            if (validator instanceof ShortCircuitableValidator && ((ShortCircuitableValidator) validator).isShortCircuit())
+            {
                 // get number of existing errors
                 List errs = null;
 
     /**
      * Builds a key for validators - used when caching validators.
      *
-     * @param clazz the action.
+     * @param clazz   the action.
      * @param context the action's context.
      * @return a validator key which is the class name plus context.
      */
         return loadFile(fileName, aClass, checkFile);
     }
 
+
+    protected static List buildClassValidatorConfigs(Class aClass, boolean checkFile) {
+
+        String fileName = aClass.getName().replace('.', '/') + VALIDATION_CONFIG_SUFFIX;
+
+        List result = new ArrayList(loadFile(fileName, aClass, checkFile));
+
+        List annotationResult = new ArrayList(AnnotationValidationConfigurationBuilder.buildAnnotationClassValidatorConfigs(aClass));
+
+        result.addAll(annotationResult);
+
+        return result;
+
+    }
+
     /**
      * <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;
      *   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
      *   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.
+     * @param clazz     the Class to look up validators for.
+     * @param context   the context to use when looking up validators.
      * @param checkFile true if the validation config file should be checked to see if it has been
-     *      updated.
-     * @param checked the set of previously checked class-contexts, null if none have been checked
+     *                  updated.
+     * @param checked   the set of previously checked class-contexts, null if none have been checked
      * @return a list of validator configs for the given class and context.
      */
     private static List buildValidatorConfigs(Class clazz, String context, boolean checkFile, Set checked) {
         return validatorConfigs;
     }
 
-    protected static List loadFile(String fileName, Class clazz, boolean checkFile) {
+    private static List loadFile(String fileName, Class clazz, boolean checkFile) {
         List retList = Collections.EMPTY_LIST;
 
         if ((checkFile && FileManager.fileNeedsReloading(fileName)) || !validatorFileCache.containsKey(fileName)) {
     }
 
 
-    private static List buildClassValidatorConfigs(Class aClass, boolean checkFile) {
-
-        String fileName = aClass.getName().replace('.', '/') + VALIDATION_CONFIG_SUFFIX;
-
-        List result = new ArrayList(loadFile(fileName, aClass, checkFile));
-
-        List annotationResult = new ArrayList(AnnotationValidationConfigurationBuilder.buildAnnotationClassValidatorConfigs(aClass));
-
-        result.addAll(annotationResult);
-
-        return result;
-
-    }
-
 }

tiger/src/java/com/opensymphony/xwork/validator/AnnotationValidationConfigurationBuilder.java

 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import com.opensymphony.xwork.validator.annotations.*;
+import com.opensymphony.xwork.apt.Generator;
+import com.sun.mirror.declaration.MethodDeclaration;
 
 /**
  * <code>AnnotationValidationConfigurationBuilder</code>
 
     private static final Log log = LogFactory.getLog(AnnotationValidationConfigurationBuilder.class);
 
+    private static final Pattern SETTER_PATTERN = Pattern.compile("set([A-Z][A-Za-z0-9]*)$");
+    private static final Pattern GETTER_PATTERN = Pattern.compile("(get|is|has)([A-Z][A-Za-z0-9]*)$");
+
+
 
     private static List<ValidatorConfig> processAnnotations(Object o) {
 
             Method method = (Method) o;
             String name = method.getName();
 
-            fieldName = Introspector.decapitalize(name.substring(3));
+            fieldName = resolvePropertyName(method);
 
             annotations = method.getAnnotations();
         }
 
         return vCfg;
     }
-    
+
     private static ValidatorConfig processStringRegexValidatorAnnotation(StringRegexValidator v, String fieldName) {
         String validatorType = "stringregex";
 
 
     }
 
+    /**
+     * Returns the property name for a method.
+     * This method is independant from property fields.
+     *
+     * @param method The method to get the property name for.
+     * @return the property name for given method; null if non could be resolved.
+     */
+    public static String resolvePropertyName(Method method) {
+
+        Matcher matcher = SETTER_PATTERN.matcher(method.getName());
+        if (matcher.matches() && method.getParameterTypes().length == 1) {
+            String raw = matcher.group(1);
+            return raw.substring(0, 1).toLowerCase() + raw.substring(1);
+        }
+
+        matcher = GETTER_PATTERN.matcher(method.getName());
+        if (matcher.matches() && method.getParameterTypes().length == 0) {
+            String raw = matcher.group(2);
+            return raw.substring(0, 1).toLowerCase() + raw.substring(1);
+        }
+
+        return null;
+    }
+
 }

tiger/src/java/com/opensymphony/xwork/validator/AnnotationValidationInterceptor.java

-/*
- * Copyright (c) 2002-2005 by OpenSymphony
- * All rights reserved.
- */
-package com.opensymphony.xwork.validator;
-
-import com.opensymphony.xwork.validator.ValidationInterceptor;
-import com.opensymphony.xwork.ActionInvocation;
-import com.opensymphony.xwork.Action;
-
-/**
- * <!-- START SNIPPET: description -->
- *
- * This interceptor runs the action through the standard validation framework, which in turn checks the action against
- * any validation rules (found in files such as <i>ActionClass-validation.xml</i>) and adds field-level and action-level
- * error messages (provided that the action implements {@link com.opensymphony.xwork.ValidationAware}). This interceptor
- * is often one of the last (or second to last) interceptors applied in a stack, as it assumes that all values have
- * already been set on the action. This interceptor does nothing if the name of the method being invoked is
- * <b>input</b>. For example, a request to <b>foo!input.action</b> would be skipped by this request.
- *
- * <p/>Note that this has nothing to do with the {@link com.opensymphony.xwork.Validateable} interface and simply adds
- * error messages to the action. 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.
- *
- * <!-- END SNIPPET: description -->
- *
- * <p/> <u>Interceptor parameters:</u>
- *
- * <!-- START SNIPPET: parameters -->
- *
- * <ul>
- *
- * <li>None</li>
- *
- * </ul>
- *
- * <!-- END SNIPPET: parameters -->
- *
- * <p/> <u>Extending the interceptor:</u>
- *
- * <p/>
- *
- * <!-- START SNIPPET: extending -->
- *
- * There are no known extension points for this interceptor.
- *
- * <!-- END SNIPPET: extending -->
- *
- * <p/> <u>Example code:</u>
- *
- * <pre>
- * <!-- START SNIPPET: example -->
- * &lt;action name="someAction" class="com.examples.SomeAction"&gt;
- *     &lt;interceptor-ref name="params"/&gt;
- *     &lt;interceptor-ref name="annotationValidation"/&gt;
- *     &lt;interceptor-ref name="workflow"/&gt;
- *     &lt;result name="success"&gt;good_result.ftl&lt;/result&gt;
- * &lt;/action&gt;
- * <!-- END SNIPPET: example -->
- * </pre>
- *
- * @author Rainer Hermanns
- * @see ActionValidatorManager
- * @see com.opensymphony.xwork.validator.ValidationInterceptor
- * @see com.opensymphony.xwork.interceptor.DefaultWorkflowInterceptor
- *
- * @version $Id$
- */
-public class AnnotationValidationInterceptor extends ValidationInterceptor {
-
-    /**
-     * Gets the current action and its context and calls {@link ActionValidatorManager#validate(Object, String)}.
-     *
-     * @param invocation the execution state of the Action.
-     * @throws Exception if an error occurs validating the action.
-     */
-    protected void before(ActionInvocation invocation) throws Exception {
-
-        System.out.println("Called before in AnnotationValidationInterceptor");
-        Object action = invocation.getAction();
-        String context = invocation.getProxy().getActionName();
-
-        if (log.isDebugEnabled()) {
-            log.debug("Validating "
-                    + invocation.getProxy().getNamespace() + "/" + invocation.getProxy().getActionName() + ".");
-        }
-
-        if (!"input".equals(invocation.getProxy().getMethod())) {
-            AnnotationActionValidatorManager.validate(action, context);
-        }
-    }
-
-}