You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by gp...@apache.org on 2010/05/09 21:41:14 UTC

svn commit: r942592 - in /myfaces/extensions/validator/trunk: core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/ core/src/main/java/org/apache...

Author: gpetracek
Date: Sun May  9 19:41:13 2010
New Revision: 942592

URL: http://svn.apache.org/viewvc?rev=942592&view=rev
Log:
EXTVAL-83 mapped constraint source for extval constraints - thx to Rudy De Busscher for the initial patch

Added:
    myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ConstraintSourceUtils.java
    myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValAnnotationUtils.java
    myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/MappedConstraintSourceValidationModuleValidationInterceptor.java
Modified:
    myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationInterceptor.java
    myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/DefaultComponentMetaDataExtractor.java
    myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValUtils.java
    myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ReflectionUtils.java
    myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/MappedConstraintSourceBeanValidationModuleValidationInterceptorInternals.java
    myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/annotation/extractor/DefaultGroupControllerScanningExtractor.java
    myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/JoinValidationMetaDataStorageFilter.java
    myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationModuleStartupListener.java
    myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/extractor/DefaultPropertyScanningMetaDataExtractor.java

Modified: myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationInterceptor.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationInterceptor.java?rev=942592&r1=942591&r2=942592&view=diff
==============================================================================
--- myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationInterceptor.java (original)
+++ myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationInterceptor.java Sun May  9 19:41:13 2010
@@ -53,8 +53,7 @@ public class ValidationInterceptor exten
     {
         logger.finest("start to init component " + uiComponent.getClass().getName());
 
-        Map<String, Object> metaDataResult = ExtValUtils
-                .getTransformedMetaDataFor(facesContext, uiComponent, getModuleKey());
+        Map<String, Object> metaDataResult = getTransformedMetaDataFor(facesContext, uiComponent);
 
         //get component initializer for the current component and configure it
         //also in case of skipped validation to reset e.g. the required attribute
@@ -66,6 +65,11 @@ public class ValidationInterceptor exten
         logger.finest("init component of " + uiComponent.getClass().getName() + " finished");
     }
 
+    protected Map<String, Object> getTransformedMetaDataFor(FacesContext facesContext, UIComponent uiComponent)
+    {
+        return ExtValUtils.getTransformedMetaDataFor(facesContext, uiComponent, getModuleKey());
+    }
+
     protected void processValidation(FacesContext facesContext, UIComponent uiComponent, Object convertedObject)
     {
         MetaDataExtractor metaDataExtractor = ExtValUtils

Modified: myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/DefaultComponentMetaDataExtractor.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/DefaultComponentMetaDataExtractor.java?rev=942592&r1=942591&r2=942592&view=diff
==============================================================================
--- myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/DefaultComponentMetaDataExtractor.java (original)
+++ myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/DefaultComponentMetaDataExtractor.java Sun May  9 19:41:13 2010
@@ -18,35 +18,25 @@
  */
 package org.apache.myfaces.extensions.validator.core.metadata.extractor;
 
-import org.apache.myfaces.extensions.validator.core.ExtValContext;
+import java.util.logging.Logger;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+
 import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
 import org.apache.myfaces.extensions.validator.core.property.DefaultPropertyInformation;
 import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
 import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
 import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;
 import org.apache.myfaces.extensions.validator.core.storage.MetaDataStorage;
-import org.apache.myfaces.extensions.validator.core.storage.PropertyStorage;
 import org.apache.myfaces.extensions.validator.internal.Priority;
 import org.apache.myfaces.extensions.validator.internal.ToDo;
 import org.apache.myfaces.extensions.validator.internal.UsageCategory;
 import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.util.ExtValAnnotationUtils;
 import org.apache.myfaces.extensions.validator.util.ExtValUtils;
 import org.apache.myfaces.extensions.validator.util.ProxyUtils;
 
-import javax.faces.component.UIComponent;
-import javax.faces.context.FacesContext;
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.List;
-import java.util.logging.Logger;
-import java.util.logging.Level;
-
 /**
  * Default implementation which extracts meta-data (e.g. the annotations) of the value binding of a component.
  * It extracts the meta-data of the field and the property.
@@ -96,11 +86,11 @@ public class DefaultComponentMetaDataExt
          */
         Class entityClass = ProxyUtils.getUnproxiedClass(propertyDetails.getBaseObject().getClass());
 
-        //create
-        propertyInformation.setInformation(PropertyInformationKeys.PROPERTY_DETAILS, propertyDetails);
-
         if (isCached(entityClass, propertyDetails.getProperty()))
         {
+            //create
+            propertyInformation.setInformation(PropertyInformationKeys.PROPERTY_DETAILS, propertyDetails);
+
             for (MetaDataEntry metaDataEntry : getCachedMetaData(entityClass, propertyDetails.getProperty()))
             {
                 propertyInformation.addMetaDataEntry(metaDataEntry);
@@ -108,7 +98,7 @@ public class DefaultComponentMetaDataExt
         }
         else
         {
-            extractAnnotations(propertyInformation, propertyDetails, entityClass);
+            propertyInformation = ExtValAnnotationUtils.extractAnnotations(entityClass, propertyDetails);
             cacheMetaData(propertyInformation);
         }
 
@@ -136,233 +126,4 @@ public class DefaultComponentMetaDataExt
     {
         return ExtValUtils.getStorage(MetaDataStorage.class, MetaDataStorage.class.getName());
     }
-
-    private boolean isCachedField(Class entity, String property)
-    {
-        return getPropertyStorage().containsField(entity, property);
-    }
-
-    private void tryToCacheField(Class entity, String property, Field field)
-    {
-        PropertyStorage propertyStorage = getPropertyStorage();
-        if (!propertyStorage.containsField(entity, property))
-        {
-            propertyStorage.storeField(entity, property, field);
-        }
-    }
-
-    private Field getCachedField(Class entity, String property)
-    {
-        return getPropertyStorage().getField(entity, property);
-    }
-
-    private boolean isCachedMethod(Class entity, String property)
-    {
-        return getPropertyStorage().containsMethod(entity, property);
-    }
-
-    private void tryToCacheMethod(Class entity, String property, Method method)
-    {
-        PropertyStorage propertyStorage = getPropertyStorage();
-        if (!propertyStorage.containsMethod(entity, property))
-        {
-            propertyStorage.storeMethod(entity, property, method);
-        }
-    }
-
-    private Method getCachedMethod(Class entity, String property)
-    {
-        return getPropertyStorage().getMethod(entity, property);
-    }
-
-    private PropertyStorage getPropertyStorage()
-    {
-        return ExtValUtils.getStorage(PropertyStorage.class, PropertyStorage.class.getName());
-    }
-
-    protected void extractAnnotations(
-            PropertyInformation propertyInformation, PropertyDetails propertyDetails, Class entityClass)
-    {
-        while (!Object.class.getName().equals(entityClass.getName()))
-        {
-            addPropertyAccessAnnotations(entityClass, propertyDetails.getProperty(), propertyInformation);
-            addFieldAccessAnnotations(entityClass, propertyDetails.getProperty(), propertyInformation);
-
-            processInterfaces(entityClass, propertyDetails, propertyInformation);
-
-            entityClass = entityClass.getSuperclass();
-        }
-    }
-
-    private void processInterfaces(
-            Class currentClass, PropertyDetails propertyDetails, PropertyInformation propertyInformation)
-    {
-        for (Class currentInterface : currentClass.getInterfaces())
-        {
-            addPropertyAccessAnnotations(currentInterface, propertyDetails.getProperty(), propertyInformation);
-
-            processInterfaces(currentInterface, propertyDetails, propertyInformation);
-        }
-    }
-
-    protected void addPropertyAccessAnnotations(Class entity, String property,
-                                                PropertyInformation propertyInformation)
-    {
-        Method method = tryToGetReadMethod(entity, property);
-
-        if (method == null)
-        {
-            method = tryToGetReadMethodManually(entity, property);
-        }
-
-        if (method != null)
-        {
-            tryToCacheMethod(entity, property, method);
-            addAnnotationToAnnotationEntries(Arrays.asList(method.getAnnotations()), propertyInformation);
-        }
-        else
-        {
-            tryToCacheMethod(entity, property, null);
-        }
-    }
-
-    private Method tryToGetReadMethod(Class entity, String property)
-    {
-        if (isCachedMethod(entity, property))
-        {
-            return getCachedMethod(entity, property);
-        }
-
-        if (useBeanInfo())
-        {
-            try
-            {
-                BeanInfo beanInfo = Introspector.getBeanInfo(entity);
-                for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors())
-                {
-                    if (property.equals(propertyDescriptor.getName()) && propertyDescriptor.getReadMethod() != null)
-                    {
-                        return propertyDescriptor.getReadMethod();
-                    }
-                }
-            }
-            catch (IntrospectionException e)
-            {
-                //do nothing
-            }
-        }
-        return null;
-    }
-
-    private boolean useBeanInfo()
-    {
-        return Boolean.TRUE.equals(ExtValContext.getContext().getGlobalProperty(BeanInfo.class.getName()));
-    }
-
-    private Method tryToGetReadMethodManually(Class entity, String property)
-    {
-        property = property.substring(0, 1).toUpperCase() + property.substring(1);
-
-        try
-        {
-            //changed to official bean spec. due to caching there is no performance issue any more
-            return entity.getDeclaredMethod("is" + property);
-        }
-        catch (NoSuchMethodException e)
-        {
-            try
-            {
-                return entity.getDeclaredMethod("get" + property);
-            }
-            catch (NoSuchMethodException e1)
-            {
-                logger.finest("method not found - class: " + entity.getName()
-                        + " - methods: " + "get" + property + " " + "is" + property);
-
-                return null;
-            }
-        }
-    }
-
-    protected void addFieldAccessAnnotations(Class entity, String property,
-                                             PropertyInformation propertyInformation)
-    {
-        Field field;
-
-        try
-        {
-            field = getDeclaredField(entity, property);
-        }
-        catch (Exception e)
-        {
-            try
-            {
-                try
-                {
-                    field = entity.getDeclaredField("_" + property);
-                }
-                catch (Exception e1)
-                {
-                    if (property.length() > 1 &&
-                            Character.isUpperCase(property.charAt(0)) &&
-                            Character.isUpperCase(property.charAt(1)))
-                    {
-                        //don't use Introspector#decapitalize here
-                        field = entity.getDeclaredField(property.substring(0, 1).toLowerCase() + property.substring(1));
-                    }
-                    else
-                    {
-                        field = entity.getDeclaredField(Introspector.decapitalize(property));
-                    }
-                }
-            }
-            catch (NoSuchFieldException e1)
-            {
-                logger.log(Level.FINEST, "field " + property + " or _" + property + " not found", e1);
-
-                return;
-            }
-        }
-
-        if (field != null)
-        {
-            tryToCacheField(entity, property, field);
-            addAnnotationToAnnotationEntries(Arrays.asList(field.getAnnotations()), propertyInformation);
-        }
-        else
-        {
-            tryToCacheField(entity, property, null);
-        }
-    }
-
-    private Field getDeclaredField(Class entity, String property) throws NoSuchFieldException
-    {
-        if (isCachedField(entity, property))
-        {
-            return getCachedField(entity, property);
-        }
-
-        return entity.getDeclaredField(property);
-    }
-
-    protected void addAnnotationToAnnotationEntries(
-            List<Annotation> annotations, PropertyInformation propertyInformation)
-    {
-        for (Annotation annotation : annotations)
-        {
-            propertyInformation.addMetaDataEntry(createMetaDataEntryForAnnotation(annotation));
-
-            logger.finest(annotation.getClass().getName() + " found");
-        }
-    }
-
-    protected MetaDataEntry createMetaDataEntryForAnnotation(Annotation foundAnnotation)
-    {
-        MetaDataEntry entry = new MetaDataEntry();
-
-        entry.setKey(foundAnnotation.annotationType().getName());
-        entry.setValue(foundAnnotation);
-
-        return entry;
-    }
 }

Added: myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ConstraintSourceUtils.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ConstraintSourceUtils.java?rev=942592&view=auto
==============================================================================
--- myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ConstraintSourceUtils.java (added)
+++ myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ConstraintSourceUtils.java Sun May  9 19:41:13 2010
@@ -0,0 +1,314 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.util;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.beans.Introspector;
+import java.lang.reflect.Method;
+
+import org.apache.myfaces.extensions.validator.core.ExtValContext;
+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
+import org.apache.myfaces.extensions.validator.core.storage.MappedConstraintSourceStorage;
+import org.apache.myfaces.extensions.validator.core.validation.ConstraintSource;
+import org.apache.myfaces.extensions.validator.core.validation.IgnoreConstraintSource;
+import org.apache.myfaces.extensions.validator.core.validation.TargetProperty;
+import org.apache.myfaces.extensions.validator.core.validation.TargetPropertyId;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+
+/**
+ * @author Gerhard Petracek
+ * @since r4
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+@SuppressWarnings("unchecked")
+public final class ConstraintSourceUtils
+{
+    private ConstraintSourceUtils()
+    {
+        // Utility class, don't allow instantiation.
+    }
+
+    public static PropertyDetails resolveMappedConstraintSourceFor(String originalKey,
+                                                                   Class originalClass,
+                                                                   String originalProperty)
+    {
+        if (isMappedConstraintSourceCached(originalClass, originalProperty))
+        {
+            return getMappedConstraintSource(originalClass, originalProperty);
+        }
+
+        originalClass = ProxyUtils.getUnproxiedClass(originalClass);
+
+        Class newClass = findMappedClass(originalClass, originalProperty);
+
+        //mapped source is ignored via @IgnoreConstraintSource or there is just no mapping annotation at the target
+        if (newClass == null)
+        {
+            tryToCacheMappedConstraintSourceMetaData(originalClass, originalProperty, null);
+            return null;
+        }
+
+        String newProperty = findMappedProperty(originalClass, newClass, originalProperty);
+
+        PropertyDetails result = new PropertyDetails(originalKey, newClass, newProperty);
+
+        tryToCacheMappedConstraintSourceMetaData(originalClass, originalProperty, result);
+        return result;
+    }
+
+    private static boolean isMappedConstraintSourceCached(Class baseBeanClass, String property)
+    {
+        return getConstraintSourceStorage().containsMapping(baseBeanClass, property);
+    }
+
+    private static PropertyDetails getMappedConstraintSource(Class baseBeanClass, String property)
+    {
+        return getConstraintSourceStorage().getMappedConstraintSource(baseBeanClass, property);
+    }
+
+    private static void tryToCacheMappedConstraintSourceMetaData(
+            Class originalClass, String originalProperty, PropertyDetails result)
+    {
+        getConstraintSourceStorage().storeMapping(originalClass, originalProperty, result);
+    }
+
+    private static MappedConstraintSourceStorage getConstraintSourceStorage()
+    {
+        return ExtValUtils
+                .getStorage(MappedConstraintSourceStorage.class, MappedConstraintSourceStorage.class.getName());
+    }
+
+    private static Class findMappedClass(Class baseBeanClass, String property)
+    {
+        Class<? extends Annotation> constraintSourceAnnotationImplementation = (Class) ExtValContext.getContext()
+                .getGlobalProperty(ConstraintSource.class.getName());
+
+        Annotation foundConstraintSourceAnnotation = tryToGetAnnotationFromProperty(
+                baseBeanClass, property, constraintSourceAnnotationImplementation);
+
+        if (foundConstraintSourceAnnotation == null)
+        {
+            foundConstraintSourceAnnotation = tryToGetAnnotationFromField(
+                    baseBeanClass, property, constraintSourceAnnotationImplementation);
+        }
+
+        if (foundConstraintSourceAnnotation == null && !isMappedConstraintSourceIgnored(baseBeanClass, property))
+        {
+            foundConstraintSourceAnnotation = tryToGetConstraintSourceAnnotationFromClass(
+                    baseBeanClass, constraintSourceAnnotationImplementation);
+        }
+
+        if (foundConstraintSourceAnnotation != null)
+        {
+            return ExtValAnnotationUtils.extractValueOf(foundConstraintSourceAnnotation, Class.class);
+        }
+
+        return null;
+    }
+
+    private static String findMappedProperty(Class baseBeanClass, Class newBaseBeanClass, String originalProperty)
+    {
+        Annotation targetPropertyAnnotation = getTargetPropertyMetaData(baseBeanClass, originalProperty);
+        if (targetPropertyAnnotation != null)
+        {
+            return extractNewPropertyName(newBaseBeanClass, targetPropertyAnnotation);
+        }
+
+        return originalProperty;
+    }
+
+    private static Annotation getTargetPropertyMetaData(Class baseBeanClass, String originalProperty)
+    {
+        Class<? extends Annotation> targetPropertyAnnotation = getTargetPropertyAnnotationImplementation();
+        Class<? extends Annotation> targetPropertyIdAnnotation = getTargetPropertyIdAnnotationImplementation();
+
+        Annotation result = findTargetPropertyIdAnnotation(baseBeanClass, originalProperty, targetPropertyIdAnnotation);
+
+        if (result == null)
+        {
+            result = findTargetPropertyAnnotation(baseBeanClass, originalProperty, targetPropertyAnnotation);
+        }
+
+        return result;
+    }
+
+    private static Class<? extends Annotation> getTargetPropertyAnnotationImplementation()
+    {
+        return (Class) ExtValContext.getContext().getGlobalProperty(TargetProperty.class.getName());
+    }
+
+    private static Class<? extends Annotation> getTargetPropertyIdAnnotationImplementation()
+    {
+        return (Class) ExtValContext.getContext().getGlobalProperty(TargetPropertyId.class.getName());
+    }
+
+    private static String extractNewPropertyName(Class targetClass, Annotation annotation)
+    {
+        Object annotationValue = ExtValAnnotationUtils.extractValueOf(annotation, Object.class);
+
+        //@TargetProperty
+        if (annotationValue instanceof String)
+        {
+            return (String) annotationValue;
+        }
+
+        //@TargetPropertyId
+        if (annotationValue instanceof Class)
+        {
+            return findNameOfAnnotatedProperty(targetClass, (Class) annotationValue);
+        }
+        return null;
+    }
+
+    //EXTVAL-83/use-case 5
+    private static String findNameOfAnnotatedProperty(
+            Class targetClass, Class<? extends Annotation> customTargetMarkerAnnotation)
+    {
+        for (Method currentMethod : targetClass.getDeclaredMethods())
+        {
+            if (currentMethod.isAnnotationPresent(customTargetMarkerAnnotation))
+            {
+                return convertMethodToPropertyName(currentMethod.getName());
+            }
+        }
+
+        for (Field currentField : targetClass.getDeclaredFields())
+        {
+            if (currentField.isAnnotationPresent(customTargetMarkerAnnotation))
+            {
+                return convertFieldToPropertyName(currentField.getName());
+            }
+        }
+        return null;
+    }
+
+    private static String convertMethodToPropertyName(String name)
+    {
+        String result = name;
+
+        if (name.startsWith("is"))
+        {
+            result = name.substring(2);
+        }
+        else if (name.startsWith("get"))
+        {
+            result = name.substring(3);
+        }
+
+        return Introspector.decapitalize(result);
+    }
+
+    private static String convertFieldToPropertyName(String name)
+    {
+        if (name.startsWith("_"))
+        {
+            return name.substring(1);
+        }
+        return name;
+    }
+
+    private static Annotation findTargetPropertyIdAnnotation(Class baseBeanClass,
+                                                             String property,
+                                                             Class<? extends Annotation> targetPropertyIdAnnotation)
+    {
+        Annotation result = tryToGetAnnotationFromProperty(baseBeanClass, property, targetPropertyIdAnnotation);
+
+        if (result == null)
+        {
+            result = tryToGetAnnotationFromField(baseBeanClass, property, targetPropertyIdAnnotation);
+        }
+
+        return result;
+    }
+
+    private static Annotation findTargetPropertyAnnotation(Class baseBeanClass,
+                                                           String property,
+                                                           Class<? extends Annotation> targetPropertyAnnotation)
+    {
+        Annotation result = tryToGetAnnotationFromProperty(baseBeanClass, property, targetPropertyAnnotation);
+
+        if (result == null)
+        {
+            result = tryToGetAnnotationFromField(baseBeanClass, property, targetPropertyAnnotation);
+        }
+
+        return result;
+    }
+
+    private static boolean isMappedConstraintSourceIgnored(Class baseBeanClass, String property)
+    {
+        Method method = ReflectionUtils.tryToGetMethodOfProperty(baseBeanClass, property);
+
+        if (method != null && method.isAnnotationPresent(getIgnoreConstraintSourceAnnotationImplementation()))
+        {
+            return true;
+        }
+
+        Field field = ReflectionUtils.tryToGetFieldOfProperty(baseBeanClass, property);
+
+        if (field != null && field.isAnnotationPresent(getIgnoreConstraintSourceAnnotationImplementation()))
+        {
+            return true;
+        }
+
+        return false;
+    }
+
+    private static Annotation tryToGetConstraintSourceAnnotationFromClass(
+            Class baseBeanClass, Class<? extends Annotation> annotation)
+    {
+        if (baseBeanClass.isAnnotationPresent(annotation))
+        {
+            return baseBeanClass.getAnnotation(annotation);
+        }
+        return null;
+    }
+
+    private static Class<? extends Annotation> getIgnoreConstraintSourceAnnotationImplementation()
+    {
+        return (Class) ExtValContext.getContext().getGlobalProperty(IgnoreConstraintSource.class.getName());
+    }
+
+    private static Annotation tryToGetAnnotationFromField(
+            Class baseBeanClass, String property, Class<? extends Annotation> annotationClass)
+    {
+        Field field = ReflectionUtils.tryToGetFieldOfProperty(baseBeanClass, property);
+
+        if (field != null && field.isAnnotationPresent(annotationClass))
+        {
+            return field.getAnnotation(annotationClass);
+        }
+        return null;
+    }
+
+    private static Annotation tryToGetAnnotationFromProperty(Class baseBeanClass,
+                                                             String property,
+                                                             Class<? extends Annotation> annotationClass)
+    {
+        Method method = ReflectionUtils.tryToGetMethodOfProperty(baseBeanClass, property);
+
+        if (method != null && method.isAnnotationPresent(annotationClass))
+        {
+            return method.getAnnotation(annotationClass);
+        }
+        return null;
+    }
+}

Added: myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValAnnotationUtils.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValAnnotationUtils.java?rev=942592&view=auto
==============================================================================
--- myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValAnnotationUtils.java (added)
+++ myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValAnnotationUtils.java Sun May  9 19:41:13 2010
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.util;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
+import org.apache.myfaces.extensions.validator.core.property.DefaultPropertyInformation;
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.ToDo;
+import org.apache.myfaces.extensions.validator.internal.Priority;
+
+/**
+ * @author Gerhard Petracek
+ * @since r4
+ */
+@UsageInformation(UsageCategory.REUSE)
+@SuppressWarnings("unchecked")
+public class ExtValAnnotationUtils
+{
+    private static final Logger LOGGER = Logger.getLogger(ExtValAnnotationUtils.class.getName());
+
+    @ToDo(value = Priority.HIGH, description = "add cache")
+    public static PropertyInformation extractAnnotations(Class entityClass, PropertyDetails propertyDetails)
+    {
+        PropertyInformation propertyInformation = new DefaultPropertyInformation();
+        propertyInformation.setInformation(PropertyInformationKeys.PROPERTY_DETAILS, propertyDetails);
+
+        while (!Object.class.getName().equals(entityClass.getName()))
+        {
+            addPropertyAccessAnnotations(entityClass, propertyDetails.getProperty(), propertyInformation);
+            addFieldAccessAnnotations(entityClass, propertyDetails.getProperty(), propertyInformation);
+
+            processInterfaces(entityClass, propertyDetails, propertyInformation);
+
+            entityClass = entityClass.getSuperclass();
+        }
+
+        return propertyInformation;
+    }
+
+    @ToDo(value = Priority.HIGH, description = "add cache")
+    public static void addPropertyAccessAnnotations(Class entity,
+                                                    String property,
+                                                    PropertyInformation propertyInformation)
+    {
+        Method method = ReflectionUtils.tryToGetMethodOfProperty(entity, property);
+
+        if(method != null)
+        {
+            addAnnotationToAnnotationEntries(Arrays.asList(method.getAnnotations()), propertyInformation);
+        }
+    }
+
+    @ToDo(value = Priority.HIGH, description = "add cache")
+    public static void addFieldAccessAnnotations(Class entity,
+                                                 String property,
+                                                 PropertyInformation propertyInformation)
+    {
+        Field field = ReflectionUtils.tryToGetFieldOfProperty(entity, property);
+
+        if(field != null)
+        {
+            addAnnotationToAnnotationEntries(Arrays.asList(field.getAnnotations()), propertyInformation);
+        }
+    }
+
+    private static void processInterfaces(Class currentClass,
+                                          PropertyDetails propertyDetails,
+                                          PropertyInformation propertyInformation)
+    {
+        for (Class currentInterface : currentClass.getInterfaces())
+        {
+            addPropertyAccessAnnotations(currentInterface, propertyDetails.getProperty(), propertyInformation);
+
+            processInterfaces(currentInterface, propertyDetails, propertyInformation);
+        }
+    }
+
+    private static void addAnnotationToAnnotationEntries(List<Annotation> annotations,
+                                                         PropertyInformation propertyInformation)
+    {
+        for (Annotation annotation : annotations)
+        {
+            propertyInformation.addMetaDataEntry(createMetaDataEntryForAnnotation(annotation));
+
+            LOGGER.finest(annotation.getClass().getName() + " found");
+        }
+    }
+
+    private static MetaDataEntry createMetaDataEntryForAnnotation(Annotation foundAnnotation)
+    {
+        MetaDataEntry entry = new MetaDataEntry();
+
+        entry.setKey(foundAnnotation.annotationType().getName());
+        entry.setValue(foundAnnotation);
+
+        return entry;
+    }
+
+    public static <T> T extractValueOf(Annotation annotation, Class<T> targetClass)
+    {
+        for (Method annotationMethod : annotation.annotationType().getDeclaredMethods())
+        {
+            if ("value".equals(annotationMethod.getName()))
+            {
+                try
+                {
+                    return (T) annotationMethod.invoke(annotation);
+                }
+                catch (Exception e)
+                {
+                    //do nothing
+                }
+            }
+        }
+        return null;
+    }
+}

Modified: myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValUtils.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValUtils.java?rev=942592&r1=942591&r2=942592&view=diff
==============================================================================
--- myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValUtils.java (original)
+++ myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValUtils.java Sun May  9 19:41:13 2010
@@ -678,6 +678,19 @@ public class ExtValUtils
         return getTransformedMetaDataWith(facesContext, uiComponent, properties);
     }
 
+    public static Map<String, Object> getTransformedMetaDataFor(
+            FacesContext facesContext, PropertyInformation propertyInformation, Class moduleKey)
+    {
+        Map<String, Object> properties = new HashMap<String, Object>();
+
+        if (moduleKey != null)
+        {
+            properties.put(ValidationModuleKey.class.getName(), moduleKey);
+        }
+
+        return getTransformedMetaDataWith(facesContext, propertyInformation, properties);
+    }
+
     public static Map<String, Object> getTransformedMetaDataWith(
             FacesContext facesContext, UIComponent uiComponent, Map<String, Object> properties)
     {
@@ -710,8 +723,47 @@ public class ExtValUtils
         return metaDataResult;
     }
 
-    private static Map<String, Object> transformMetaData(FacesContext facesContext,
-                                                         UIComponent uiComponent,
+    public static Map<String, Object> getTransformedMetaDataWith(FacesContext facesContext,
+                                                                 PropertyInformation propertyInformation,
+                                                                 Map<String, Object> properties)
+    {
+        ValidationStrategy validationStrategy;
+
+        // This is called as part of the MetaData extraction in the default process. 
+        // So we need to do it here also before the transformations are run.
+        for (MetaDataExtractionInterceptor metaDataExtractionInterceptor :
+                ExtValContext.getContext().getMetaDataExtractionInterceptorsWith(properties))
+        {
+            metaDataExtractionInterceptor.afterExtracting(propertyInformation);
+        }
+
+        SkipValidationEvaluator skipValidationEvaluator = ExtValContext.getContext().getSkipValidationEvaluator();
+
+        Map<String, Object> metaData;
+        Map<String, Object> metaDataResult = new HashMap<String, Object>();
+
+        for (MetaDataEntry entry : propertyInformation.getMetaDataEntries())
+        {
+            metaData = new HashMap<String, Object>();
+            validationStrategy = getValidationStrategyForMetaData(entry.getKey());
+
+            if (validationStrategy != null)
+            {
+                metaData = transformMetaData(
+                        facesContext, null, validationStrategy, skipValidationEvaluator, metaData, entry);
+
+                if (!isComponentInitializationSkipped(metaData, entry, validationStrategy))
+                {
+                    //don't break maybe there are constraints which don't support the skip-mechanism
+                    metaDataResult.putAll(metaData);
+                }
+            }
+        }
+
+        return metaDataResult;
+    }
+
+    private static Map<String, Object> transformMetaData(FacesContext facesContext, UIComponent uiComponent,
                                                          ValidationStrategy validationStrategy,
                                                          SkipValidationEvaluator skipValidationEvaluator,
                                                          Map<String, Object> metaData, MetaDataEntry entry)
@@ -930,7 +982,7 @@ public class ExtValUtils
      * needed for some component libs - if required initialization is used e.g. for visual indicators
      * but features like severity aware validation aren't used.
      * in such a case it's possible to use the required attribute.
-     * 
+     *
      * @return false to deactivate the final reset of the value of the required attribute
      */
     public static boolean isRequiredResetActivated()

Modified: myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ReflectionUtils.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ReflectionUtils.java?rev=942592&r1=942591&r2=942592&view=diff
==============================================================================
--- myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ReflectionUtils.java (original)
+++ myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ReflectionUtils.java Sun May  9 19:41:13 2010
@@ -18,12 +18,21 @@
  */
 package org.apache.myfaces.extensions.validator.util;
 
-import org.apache.myfaces.extensions.validator.internal.UsageCategory;
-import org.apache.myfaces.extensions.validator.internal.UsageInformation;
-
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.StringTokenizer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.myfaces.extensions.validator.core.ExtValContext;
+import org.apache.myfaces.extensions.validator.core.storage.PropertyStorage;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
 
 /**
  * @author Gerhard Petracek
@@ -32,6 +41,8 @@ import java.util.StringTokenizer;
 @UsageInformation(UsageCategory.INTERNAL)
 public class ReflectionUtils
 {
+    private static final Logger LOGGER = Logger.getLogger(ReflectionUtils.class.getName());
+
     public static Method tryToGetMethod(Class targetClass, String targetMethodName)
     {
         return tryToGetMethod(targetClass, targetMethodName, null);
@@ -61,7 +72,7 @@ public class ReflectionUtils
     {
         Class currentClass = targetClass;
         Method targetMethod = null;
-        
+
         while (!Object.class.getName().equals(currentClass.getName()))
         {
             try
@@ -193,4 +204,174 @@ public class ReflectionUtils
 
         return currentBase;
     }
+
+    public static PropertyStorage getPropertyStorage()
+    {
+        return ExtValUtils.getStorage(PropertyStorage.class, PropertyStorage.class.getName());
+    }
+
+    public static Method tryToGetMethodOfProperty(Class entity, String property)
+    {
+        if (isCachedMethod(entity, property))
+        {
+            return getCachedMethod(entity, property);
+        }
+
+        Method method = tryToGetReadMethod(entity, property);
+
+        tryToCacheMethod(entity, property, method);
+
+        return method;
+    }
+
+    public static Field tryToGetFieldOfProperty(Class entity, String property)
+    {
+        if (isCachedField(entity, property))
+        {
+            return getCachedField(entity, property);
+        }
+
+        Field field = null;
+
+        try
+        {
+            field = entity.getDeclaredField(property);
+        }
+        catch (Exception e)
+        {
+            try
+            {
+                try
+                {
+                    field = entity.getDeclaredField("_" + property);
+                }
+                catch (Exception e1)
+                {
+                    if (property.length() > 1
+                            && Character.isUpperCase(property.charAt(0))
+                            && Character.isUpperCase(property.charAt(1)))
+                    {
+                        //don't use Introspector#decapitalize here
+                        field = entity.getDeclaredField(property.substring(0, 1).toLowerCase() + property.substring(1));
+                    }
+                    else
+                    {
+                        field = entity.getDeclaredField(Introspector.decapitalize(property));
+                    }
+                }
+            }
+            catch (NoSuchFieldException e1)
+            {
+                LOGGER.log(Level.FINEST, "field " + property + " or _" + property + " not found", e1);
+            }
+        }
+
+        tryToCacheField(entity, property, field);
+
+        return field;
+    }
+
+    private static void tryToCacheField(Class entity, String property, Field field)
+    {
+        PropertyStorage propertyStorage = getPropertyStorage();
+        if (!propertyStorage.containsField(entity, property))
+        {
+            propertyStorage.storeField(entity, property, field);
+        }
+    }
+
+    private static boolean isCachedField(Class entity, String property)
+    {
+        return getPropertyStorage().containsField(entity, property);
+    }
+
+    private static Method tryToGetReadMethod(Class baseBeanClass, String property)
+    {
+        Method method = ReflectionUtils.tryToGetReadMethodViaBeanInfo(baseBeanClass, property);
+
+        if (method == null)
+        {
+            method = ReflectionUtils.tryToGetReadMethodManually(baseBeanClass, property);
+        }
+        return method;
+    }
+
+    private static Method tryToGetReadMethodViaBeanInfo(Class entity, String property)
+    {
+        if (useBeanInfo())
+        {
+            try
+            {
+                BeanInfo beanInfo = Introspector.getBeanInfo(entity);
+                for (PropertyDescriptor propertyDescriptor : beanInfo
+                        .getPropertyDescriptors())
+                {
+                    if (property.equals(propertyDescriptor.getName())
+                            && propertyDescriptor.getReadMethod() != null)
+                    {
+                        return propertyDescriptor.getReadMethod();
+                    }
+                }
+            }
+            catch (IntrospectionException e)
+            {
+                //do nothing
+            }
+        }
+        return null;
+    }
+
+    private static boolean useBeanInfo()
+    {
+        return Boolean.TRUE.equals(ExtValContext.getContext().getGlobalProperty(BeanInfo.class.getName()));
+    }
+
+    private static Method tryToGetReadMethodManually(Class entity, String property)
+    {
+        property = property.substring(0, 1).toUpperCase() + property.substring(1);
+
+        try
+        {
+            //changed to official bean spec. due to caching there is no performance issue any more
+            return entity.getDeclaredMethod("is" + property);
+        }
+        catch (NoSuchMethodException e)
+        {
+            try
+            {
+                return entity.getDeclaredMethod("get" + property);
+            }
+            catch (NoSuchMethodException e1)
+            {
+                LOGGER.finest("method not found - class: " + entity.getName()
+                        + " - methods: " + "get" + property + " " + "is" + property);
+
+                return null;
+            }
+        }
+    }
+
+    private static Field getCachedField(Class entity, String property)
+    {
+        return getPropertyStorage().getField(entity, property);
+    }
+
+    private static boolean isCachedMethod(Class entity, String property)
+    {
+        return getPropertyStorage().containsMethod(entity, property);
+    }
+
+    private static void tryToCacheMethod(Class entity, String property, Method method)
+    {
+        PropertyStorage propertyStorage = getPropertyStorage();
+        if (!propertyStorage.containsMethod(entity, property))
+        {
+            propertyStorage.storeMethod(entity, property, method);
+        }
+    }
+
+    private static Method getCachedMethod(Class entity, String property)
+    {
+        return getPropertyStorage().getMethod(entity, property);
+    }
 }

Modified: myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/MappedConstraintSourceBeanValidationModuleValidationInterceptorInternals.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/MappedConstraintSourceBeanValidationModuleValidationInterceptorInternals.java?rev=942592&r1=942591&r2=942592&view=diff
==============================================================================
--- myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/MappedConstraintSourceBeanValidationModuleValidationInterceptorInternals.java (original)
+++ myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/MappedConstraintSourceBeanValidationModuleValidationInterceptorInternals.java Sun May  9 19:41:13 2010
@@ -18,20 +18,12 @@
  */
 package org.apache.myfaces.extensions.validator.beanval;
 
-import org.apache.myfaces.extensions.validator.core.ExtValContext;
-import org.apache.myfaces.extensions.validator.core.storage.MappedConstraintSourceStorage;
 import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
 import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
-import org.apache.myfaces.extensions.validator.core.validation.ConstraintSource;
-import org.apache.myfaces.extensions.validator.core.validation.IgnoreConstraintSource;
-import org.apache.myfaces.extensions.validator.core.validation.TargetProperty;
-import org.apache.myfaces.extensions.validator.core.validation.TargetPropertyId;
-import org.apache.myfaces.extensions.validator.internal.Priority;
-import org.apache.myfaces.extensions.validator.internal.ToDo;
 import org.apache.myfaces.extensions.validator.internal.UsageCategory;
 import org.apache.myfaces.extensions.validator.internal.UsageInformation;
 import org.apache.myfaces.extensions.validator.util.ExtValUtils;
-import org.apache.myfaces.extensions.validator.util.ProxyUtils;
+import org.apache.myfaces.extensions.validator.util.ConstraintSourceUtils;
 
 import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
@@ -39,17 +31,9 @@ import javax.validation.ConstraintViolat
 import javax.validation.ValidatorFactory;
 import javax.validation.groups.Default;
 import javax.validation.metadata.ElementDescriptor;
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.Set;
 import java.util.Collections;
+import java.util.Set;
 import java.util.logging.Logger;
-import java.util.logging.Level;
 
 /**
  * @author Gerhard Petracek
@@ -145,407 +129,8 @@ class MappedConstraintSourceBeanValidati
         return ExtValUtils.getPropertyDetails(propertyInformation).getKey();
     }
 
-    //use the PropertyDetails to avoid a new data-structure
-    //an instance of the target class isn't required in for this use-case so the class itself is stored directly
-    //a clean approach would require an additional api
-    //however, since it's only used in this class it's ok to use casting instead
     PropertyDetails resolveMappedConstraintSourceFor(String originalKey, Class baseBeanClass, String property)
     {
-        if (isMappedConstraintSourceCached(baseBeanClass, property))
-        {
-            return getMappedConstraintSource(baseBeanClass, property);
-        }
-
-        baseBeanClass = ProxyUtils.getUnproxiedClass(baseBeanClass);
-
-        Class newBaseBeanClass = findMappedClass(baseBeanClass, property);
-
-        //mapped source is ignored via @IgnoreConstraintSource or there is just no mapping annotation at the target
-        if(newBaseBeanClass == null)
-        {
-            tryToCacheMappedConstraintSourceMetaData(baseBeanClass, property, null);
-            return null;
-        }
-
-        String newProperty = findMappedProperty(baseBeanClass, newBaseBeanClass, property);
-
-        PropertyDetails result = new PropertyDetails(originalKey, newBaseBeanClass, newProperty);
-
-        tryToCacheMappedConstraintSourceMetaData(baseBeanClass, property, result);
-        return result;
-    }
-
-    private boolean isMappedConstraintSourceCached(Class baseBeanClass, String property)
-    {
-        return getConstraintSourceStorage().containsMapping(baseBeanClass, property);
-    }
-
-    private PropertyDetails getMappedConstraintSource(Class baseBeanClass, String property)
-    {
-        return getConstraintSourceStorage().getMappedConstraintSource(baseBeanClass, property);
-    }
-
-    private void tryToCacheMappedConstraintSourceMetaData(
-            Class originalClass, String originalProperty, PropertyDetails result)
-    {
-        getConstraintSourceStorage().storeMapping(originalClass, originalProperty, result);
-    }
-
-    private MappedConstraintSourceStorage getConstraintSourceStorage()
-    {
-        return ExtValUtils
-                .getStorage(MappedConstraintSourceStorage.class, MappedConstraintSourceStorage.class.getName());
-    }
-
-    private Class findMappedClass(Class baseBeanClass, String property)
-    {
-        Class<? extends Annotation> constraintSourceAnnotationImplementation = (Class) ExtValContext.getContext()
-                .getGlobalProperty(ConstraintSource.class.getName());
-
-        Annotation foundConstraintSourceAnnotation = tryToGetAnnotationFromProperty(
-                baseBeanClass, property, constraintSourceAnnotationImplementation);
-
-        if (foundConstraintSourceAnnotation == null)
-        {
-            foundConstraintSourceAnnotation = tryToGetAnnotationFromField(
-                    baseBeanClass, property, constraintSourceAnnotationImplementation);
-        }
-
-        if (foundConstraintSourceAnnotation == null && !isMappedConstraintSourceIgnored(baseBeanClass, property))
-        {
-            foundConstraintSourceAnnotation = tryToGetConstraintSourceAnnotationFromClass(
-                    baseBeanClass, constraintSourceAnnotationImplementation);
-        }
-
-        if (foundConstraintSourceAnnotation != null)
-        {
-            return extractValueOf(foundConstraintSourceAnnotation, Class.class);
-        }
-
-        return null;
-    }
-
-    private Method tryToGetMethod(Class baseBeanClass, String property)
-    {
-        Method method = tryToGetReadMethod(baseBeanClass, property);
-
-        if (method == null)
-        {
-            method = tryToGetReadMethodManually(baseBeanClass, property);
-        }
-        return method;
-    }
-
-    private Method tryToGetReadMethod(Class entity, String property)
-    {
-        if (useBeanInfo())
-        {
-            try
-            {
-                BeanInfo beanInfo = Introspector.getBeanInfo(entity);
-                for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors())
-                {
-                    if (property.equals(propertyDescriptor.getName()) && propertyDescriptor.getReadMethod() != null)
-                    {
-                        return propertyDescriptor.getReadMethod();
-                    }
-                }
-            }
-            catch (IntrospectionException e)
-            {
-                //do nothing
-            }
-        }
-        return null;
-    }
-
-    private boolean useBeanInfo()
-    {
-        return Boolean.TRUE.equals(ExtValContext.getContext().getGlobalProperty(BeanInfo.class.getName()));
-    }
-
-    @ToDo(value = Priority.MEDIUM, description = "refactor - it's also used in DefaultComponentMetaDataExtractor")
-    private Method tryToGetReadMethodManually(Class entity, String property)
-    {
-        property = property.substring(0, 1).toUpperCase() + property.substring(1);
-
-        try
-        {
-            //changed to official bean spec. due to caching there is no performance issue any more
-            return entity.getDeclaredMethod("is" + property);
-        }
-        catch (NoSuchMethodException e)
-        {
-            try
-            {
-                return entity.getDeclaredMethod("get" + property);
-            }
-            catch (NoSuchMethodException e1)
-            {
-                logger.finest("method not found - class: " + entity.getName()
-                        + " - methods: " + "get" + property + " " + "is" + property);
-
-                return null;
-            }
-        }
-    }
-
-    @ToDo(value = Priority.MEDIUM, description = "refactor - it's also used in DefaultComponentMetaDataExtractor")
-    private Field tryToGetField(Class baseBeanClass, String property)
-    {
-        Field field;
-
-        try
-        {
-            field = getDeclaredField(baseBeanClass, property);
-        }
-        catch (Exception e)
-        {
-            try
-            {
-                try
-                {
-                    field = baseBeanClass.getDeclaredField("_" + property);
-                }
-                catch (Exception e1)
-                {
-                    if (property.length() > 1 &&
-                            Character.isUpperCase(property.charAt(0)) &&
-                            Character.isUpperCase(property.charAt(1)))
-                    {
-                        //don't use Introspector#decapitalize here
-                        field = baseBeanClass
-                                .getDeclaredField(property.substring(0, 1).toLowerCase() + property.substring(1));
-                    }
-                    else
-                    {
-                        field = baseBeanClass.getDeclaredField(Introspector.decapitalize(property));
-                    }
-                }
-            }
-            catch (NoSuchFieldException e1)
-            {
-                logger.log(Level.FINEST, "field " + property + " or _" + property + " not found", e1);
-
-                return null;
-            }
-        }
-
-        return field;
-    }
-
-    @ToDo.List({
-      @ToDo(value = Priority.HIGH, description = "add support for instances wrapped with cglib"),
-      @ToDo(value = Priority.BLOCKING, description = "refactor - it's also used in DefaultComponentMetaDataExtractor")
-    })
-    private Field getDeclaredField(Class entity, String property) throws NoSuchFieldException
-    {
-        return entity.getDeclaredField(property);
-    }
-
-    private boolean isMappedConstraintSourceIgnored(Class baseBeanClass, String property)
-    {
-        Method method = tryToGetMethod(baseBeanClass, property);
-
-        if(method != null && method.isAnnotationPresent(getIgnoreConstraintSourceAnnotationImplementation()))
-        {
-            return true;
-        }
-
-        Field field = tryToGetField(baseBeanClass, property);
-
-        if(field != null && field.isAnnotationPresent(getIgnoreConstraintSourceAnnotationImplementation()))
-        {
-            return true;
-        }
-
-        return false;
-    }
-
-    private Annotation tryToGetConstraintSourceAnnotationFromClass(
-            Class baseBeanClass, Class<? extends Annotation> annotation)
-    {
-        if (baseBeanClass.isAnnotationPresent(annotation))
-        {
-            return baseBeanClass.getAnnotation(annotation);
-        }
-        return null;
-    }
-
-    private Class<? extends Annotation> getIgnoreConstraintSourceAnnotationImplementation()
-    {
-        return (Class) ExtValContext.getContext().getGlobalProperty(IgnoreConstraintSource.class.getName());
-    }
-
-    private String findMappedProperty(Class baseBeanClass, Class newBaseBeanClass, String originalProperty)
-    {
-        Annotation targetPropertyAnnotation = getTargetPropertyMetaData(baseBeanClass, originalProperty);
-        if (targetPropertyAnnotation != null)
-        {
-            return extractNewPropertyName(newBaseBeanClass, targetPropertyAnnotation);
-        }
-
-        return originalProperty;
-    }
-
-    private Annotation getTargetPropertyMetaData(Class baseBeanClass, String originalProperty)
-    {
-        Class<? extends Annotation> targetPropertyAnnotation = getTargetPropertyAnnotationImplementation();
-        Class<? extends Annotation> targetPropertyIdAnnotation = getTargetPropertyIdAnnotationImplementation();
-
-        Annotation result = findTargetPropertyIdAnnotation(baseBeanClass, originalProperty, targetPropertyIdAnnotation);
-
-        if (result == null)
-        {
-            result = findTargetPropertyAnnotation(baseBeanClass, originalProperty, targetPropertyAnnotation);
-        }
-
-        return result;
-    }
-
-    private Annotation findTargetPropertyIdAnnotation(Class baseBeanClass,
-                                                      String property,
-                                                      Class<? extends Annotation> targetPropertyIdAnnotation)
-    {
-        Annotation result = tryToGetAnnotationFromProperty(baseBeanClass, property, targetPropertyIdAnnotation);
-
-        if (result == null)
-        {
-            result = tryToGetAnnotationFromField(baseBeanClass, property, targetPropertyIdAnnotation);
-        }
-
-        return result;
-    }
-
-    private Annotation findTargetPropertyAnnotation(Class baseBeanClass,
-                                                    String property,
-                                                    Class<? extends Annotation> targetPropertyAnnotation)
-    {
-        Annotation result = tryToGetAnnotationFromProperty(baseBeanClass, property, targetPropertyAnnotation);
-
-        if (result == null)
-        {
-            result = tryToGetAnnotationFromField(baseBeanClass, property, targetPropertyAnnotation);
-        }
-
-        return result;
-    }
-
-    private Annotation tryToGetAnnotationFromProperty(
-            Class baseBeanClass, String property, Class<? extends Annotation> annotationClass)
-    {
-        Method method = tryToGetMethod(baseBeanClass, property);
-
-        if (method != null && method.isAnnotationPresent(annotationClass))
-        {
-            return method.getAnnotation(annotationClass);
-        }
-        return null;
-    }
-
-    private Annotation tryToGetAnnotationFromField(
-            Class baseBeanClass, String property, Class<? extends Annotation> annotationClass)
-    {
-        Field field = tryToGetField(baseBeanClass, property);
-
-        if (field != null && field.isAnnotationPresent(annotationClass))
-        {
-            return field.getAnnotation(annotationClass);
-        }
-        return null;
-    }
-
-    private Class<? extends Annotation> getTargetPropertyAnnotationImplementation()
-    {
-        return (Class) ExtValContext.getContext().getGlobalProperty(TargetProperty.class.getName());
-    }
-
-    private Class<? extends Annotation> getTargetPropertyIdAnnotationImplementation()
-    {
-        return (Class) ExtValContext.getContext().getGlobalProperty(TargetPropertyId.class.getName());
-    }
-
-    private String extractNewPropertyName(Class targetClass, Annotation annotation)
-    {
-        Object annotationValue = extractValueOf(annotation, Object.class);
-
-        //@TargetProperty
-        if (annotationValue instanceof String)
-        {
-            return (String) annotationValue;
-        }
-
-        //@TargetPropertyId
-        if (annotationValue instanceof Class)
-        {
-            return findNameOfAnnotatedProperty(targetClass, (Class) annotationValue);
-        }
-        return null;
-    }
-
-    //EXTVAL-83/use-case 5
-    private String findNameOfAnnotatedProperty(
-            Class targetClass, Class<? extends Annotation> customTargetMarkerAnnotation)
-    {
-        for(Method currentMethod : targetClass.getDeclaredMethods())
-        {
-            if(currentMethod.isAnnotationPresent(customTargetMarkerAnnotation))
-            {
-                return convertMethodToPropertyName(currentMethod.getName());
-            }
-        }
-
-        for(Field currentField : targetClass.getDeclaredFields())
-        {
-            if(currentField.isAnnotationPresent(customTargetMarkerAnnotation))
-            {
-                return convertFieldToPropertyName(currentField.getName());
-            }
-        }
-        return null;
-    }
-
-    private String convertMethodToPropertyName(String name)
-    {
-        String result = name;
-
-        if(name.startsWith("is"))
-        {
-            result = name.substring(2);
-        }
-        else if(name.startsWith("get"))
-        {
-            result = name.substring(3);
-        }
-
-        return Introspector.decapitalize(result);
-    }
-
-    private String convertFieldToPropertyName(String name)
-    {
-        if(name.startsWith("_"))
-        {
-            return name.substring(1);
-        }
-        return name;
-    }
-
-    private <T> T extractValueOf(Annotation annotation, Class<T> targetClass)
-    {
-        for (Method annotationMethod : annotation.annotationType().getDeclaredMethods())
-        {
-            if ("value".equals(annotationMethod.getName()))
-            {
-                try
-                {
-                    return (T) annotationMethod.invoke(annotation);
-                }
-                catch (Exception e)
-                {
-                    //do nothing
-                }
-            }
-        }
-        return null;
+        return ConstraintSourceUtils.resolveMappedConstraintSourceFor(originalKey, baseBeanClass, property);
     }
 }

Modified: myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/annotation/extractor/DefaultGroupControllerScanningExtractor.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/annotation/extractor/DefaultGroupControllerScanningExtractor.java?rev=942592&r1=942591&r2=942592&view=diff
==============================================================================
--- myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/annotation/extractor/DefaultGroupControllerScanningExtractor.java (original)
+++ myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/annotation/extractor/DefaultGroupControllerScanningExtractor.java Sun May  9 19:41:13 2010
@@ -20,14 +20,13 @@ package org.apache.myfaces.extensions.va
 
 import org.apache.myfaces.extensions.validator.core.metadata.extractor.DefaultComponentMetaDataExtractor;
 import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
-import org.apache.myfaces.extensions.validator.core.property.DefaultPropertyInformation;
 import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
-import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;
 import org.apache.myfaces.extensions.validator.internal.ToDo;
 import org.apache.myfaces.extensions.validator.internal.Priority;
 import org.apache.myfaces.extensions.validator.internal.UsageInformation;
 import org.apache.myfaces.extensions.validator.internal.UsageCategory;
 import org.apache.myfaces.extensions.validator.util.ProxyUtils;
+import static org.apache.myfaces.extensions.validator.util.ExtValAnnotationUtils.extractAnnotations;
 
 import javax.faces.context.FacesContext;
 
@@ -51,11 +50,6 @@ public class DefaultGroupControllerScann
 
         Class entityClass = ProxyUtils.getUnproxiedClass(propertyDetails.getBaseObject().getClass());
 
-        PropertyInformation propertyInformation = new DefaultPropertyInformation();
-        propertyInformation.setInformation(PropertyInformationKeys.PROPERTY_DETAILS, propertyDetails);
-
-        extractAnnotations(propertyInformation, propertyDetails, entityClass);
-
-        return propertyInformation;
+        return extractAnnotations(entityClass, propertyDetails);
     }
 }

Modified: myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/JoinValidationMetaDataStorageFilter.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/JoinValidationMetaDataStorageFilter.java?rev=942592&r1=942591&r2=942592&view=diff
==============================================================================
--- myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/JoinValidationMetaDataStorageFilter.java (original)
+++ myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/JoinValidationMetaDataStorageFilter.java Sun May  9 19:41:13 2010
@@ -29,6 +29,8 @@ import org.apache.myfaces.extensions.val
 import org.apache.myfaces.extensions.validator.util.ClassUtils;
 import org.apache.myfaces.extensions.validator.util.ExtValUtils;
 import org.apache.myfaces.extensions.validator.util.ProxyUtils;
+import static org.apache.myfaces.extensions.validator.util.ExtValAnnotationUtils.addPropertyAccessAnnotations;
+import static org.apache.myfaces.extensions.validator.util.ExtValAnnotationUtils.addFieldAccessAnnotations;
 import org.apache.myfaces.extensions.validator.internal.UsageInformation;
 import org.apache.myfaces.extensions.validator.internal.UsageCategory;
 

Added: myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/MappedConstraintSourceValidationModuleValidationInterceptor.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/MappedConstraintSourceValidationModuleValidationInterceptor.java?rev=942592&view=auto
==============================================================================
--- myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/MappedConstraintSourceValidationModuleValidationInterceptor.java (added)
+++ myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/MappedConstraintSourceValidationModuleValidationInterceptor.java Sun May  9 19:41:13 2010
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator;
+
+import java.util.Map;
+import java.util.Collections;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+
+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.util.ExtValAnnotationUtils;
+import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+import static org.apache.myfaces.extensions.validator.util.ConstraintSourceUtils.resolveMappedConstraintSourceFor;
+
+/**
+ * @author Rudy De Busscher
+ * @since r4
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public class MappedConstraintSourceValidationModuleValidationInterceptor
+        extends PropertyValidationModuleValidationInterceptor
+{
+    @Override
+    protected Map<String, Object> getTransformedMetaDataFor(FacesContext facesContext, UIComponent uiComponent)
+    {
+        PropertyDetails originalPropertyDetail = ExtValUtils.getELHelper()
+                .getPropertyDetailsOfValueBinding(uiComponent);
+
+        PropertyInformation propertyInformation = extractFromMappedConstraintSource(originalPropertyDetail);
+
+        if (propertyInformation == null)
+        {
+            // No @ConstraintSource or alike so nothing to do.
+            return Collections.emptyMap();
+        }
+
+        return ExtValUtils.getTransformedMetaDataFor(facesContext, propertyInformation, getModuleKey());
+    }
+
+    @Override
+    protected void processFieldValidation(FacesContext facesContext,
+                                          UIComponent uiComponent,
+                                          Object convertedObject,
+                                          PropertyInformation propertyInformation)
+    {
+        PropertyDetails originalPropertyDetail = ExtValUtils.getPropertyDetails(propertyInformation);
+
+        propertyInformation = extractFromMappedConstraintSource(originalPropertyDetail);
+
+        if (propertyInformation != null)
+        {
+            super.processFieldValidation(facesContext, uiComponent, convertedObject, propertyInformation);
+        }
+    }
+
+    private PropertyInformation extractFromMappedConstraintSource(PropertyDetails originalPropertyDetail)
+    {
+        PropertyDetails constraintSourcePropertyDetails =
+                resolveMappedConstraintSourceFor(originalPropertyDetail.getKey(),
+                                                 originalPropertyDetail.getBaseObject().getClass(),
+                                                 originalPropertyDetail.getProperty());
+
+        if (constraintSourcePropertyDetails == null)
+        {
+            return null;
+        }
+
+        return ExtValAnnotationUtils.extractAnnotations(
+                (Class) constraintSourcePropertyDetails.getBaseObject(), constraintSourcePropertyDetails);
+    }
+
+    @Override
+    protected boolean recordProcessedInformation()
+    {
+        // Nothing to do here, has already been done.
+        return false;
+    }
+}

Modified: myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationModuleStartupListener.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationModuleStartupListener.java?rev=942592&r1=942591&r2=942592&view=diff
==============================================================================
--- myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationModuleStartupListener.java (original)
+++ myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationModuleStartupListener.java Sun May  9 19:41:13 2010
@@ -62,6 +62,7 @@ public class PropertyValidationModuleSta
         initStaticStrategyMappings();
         initDefaultComponentInitializer();
         addSkipValidationSupport();
+        addMappedConstraintSourceValidationSupport();
         initStorageManagerAndNameMappers();
         initSkipValidationEvaluator();
         initMetaDataStorageFilters();
@@ -110,6 +111,12 @@ public class PropertyValidationModuleSta
         //config.addMapping(CommonMetaDataKeys.SKIP_VALIDATION, RequiredStrategy.class.getName());
     }
 
+    private void addMappedConstraintSourceValidationSupport()
+    {
+        ExtValContext.getContext().registerRendererInterceptor(
+                new MappedConstraintSourceValidationModuleValidationInterceptor());
+    }
+
     @SuppressWarnings({"unchecked"})
     private void initStorageManagerAndNameMappers()
     {

Modified: myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/extractor/DefaultPropertyScanningMetaDataExtractor.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/extractor/DefaultPropertyScanningMetaDataExtractor.java?rev=942592&r1=942591&r2=942592&view=diff
==============================================================================
--- myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/extractor/DefaultPropertyScanningMetaDataExtractor.java (original)
+++ myfaces/extensions/validator/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/extractor/DefaultPropertyScanningMetaDataExtractor.java Sun May  9 19:41:13 2010
@@ -30,6 +30,8 @@ import org.apache.myfaces.extensions.val
 import org.apache.myfaces.extensions.validator.internal.UsageCategory;
 import org.apache.myfaces.extensions.validator.util.ExtValUtils;
 import org.apache.myfaces.extensions.validator.util.ProxyUtils;
+import static org.apache.myfaces.extensions.validator.util.ExtValAnnotationUtils.addFieldAccessAnnotations;
+import static org.apache.myfaces.extensions.validator.util.ExtValAnnotationUtils.addPropertyAccessAnnotations;
 import org.apache.myfaces.extensions.validator.PropertyValidationModuleKey;
 
 import javax.faces.context.FacesContext;