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 2009/10/09 23:49:40 UTC

svn commit: r823706 - in /myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java: org/apache/myfaces/extensions/validator/beanval/ org/apache/myfaces/extensions/validator/beanval/validation/ util/

Author: gpetracek
Date: Fri Oct  9 21:49:39 2009
New Revision: 823706

URL: http://svn.apache.org/viewvc?rev=823706&view=rev
Log:
cleanup

Added:
    myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationInterceptorUtils.java
    myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/util/
    myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/util/BeanValidationUtils.java
Modified:
    myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationInterceptor.java
    myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationPhaseListener.java

Modified: myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationInterceptor.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationInterceptor.java?rev=823706&r1=823705&r2=823706&view=diff
==============================================================================
--- myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationInterceptor.java (original)
+++ myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationInterceptor.java Fri Oct  9 21:49:39 2009
@@ -18,36 +18,22 @@
  */
 package org.apache.myfaces.extensions.validator.beanval;
 
+import org.apache.myfaces.extensions.validator.core.interceptor.AbstractValidationInterceptor;
+import org.apache.myfaces.extensions.validator.core.metadata.extractor.MetaDataExtractor;
+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.renderkit.exception.SkipBeforeInterceptorsException;
 import org.apache.myfaces.extensions.validator.core.renderkit.exception.SkipRendererDelegationException;
-import org.apache.myfaces.extensions.validator.core.WebXmlParameter;
-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.property.PropertyDetails;
-import org.apache.myfaces.extensions.validator.core.metadata.extractor.MetaDataExtractor;
-import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
-import org.apache.myfaces.extensions.validator.core.metadata.transformer.MetaDataTransformer;
-import org.apache.myfaces.extensions.validator.core.interceptor.AbstractValidationInterceptor;
-import org.apache.myfaces.extensions.validator.util.ExtValUtils;
-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.ToDo;
 import org.apache.myfaces.extensions.validator.internal.UsageCategory;
-import org.apache.myfaces.extensions.validator.beanval.validation.strategy.BeanValidationStrategyAdapter;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+import util.BeanValidationUtils;
 
-import javax.faces.context.FacesContext;
 import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
 import javax.faces.render.Renderer;
-import javax.faces.validator.ValidatorException;
-import javax.faces.application.FacesMessage;
-import javax.validation.metadata.BeanDescriptor;
-import javax.validation.metadata.ElementDescriptor;
-import javax.validation.metadata.ConstraintDescriptor;
-import javax.validation.ConstraintViolation;
-import java.util.Set;
-import java.util.Map;
-import java.util.List;
-import java.util.ArrayList;
 import java.io.IOException;
 
 /**
@@ -62,13 +48,13 @@
     public void beforeEncodeBegin(FacesContext facesContext, UIComponent uiComponent, Renderer wrapped)
             throws IOException, SkipBeforeInterceptorsException, SkipRendererDelegationException
     {
-        if(processComponent(uiComponent))
+        if (processComponent(uiComponent))
         {
             initComponent(facesContext, uiComponent);
         }
     }
 
-    @ToDo(value = Priority.HIGH, description = "check groups")
+    @ToDo(value = Priority.HIGH, description = "possibility to deactivate initialization (in web.xml)")
     protected void initComponent(FacesContext facesContext, UIComponent uiComponent)
     {
         if (logger.isTraceEnabled())
@@ -76,11 +62,13 @@
             logger.trace("start to init component " + uiComponent.getClass().getName());
         }
 
-        PropertyDetails propertyDetails = extractPropertyDetails(facesContext, uiComponent);
+        BeanValidationInterceptorUtils bviUtils = new BeanValidationInterceptorUtils(this.logger);
+
+        PropertyDetails propertyDetails = bviUtils.extractPropertyDetails(facesContext, uiComponent);
 
-        if(propertyDetails != null)
+        if (propertyDetails != null)
         {
-            initComponentWithPropertyDetails(facesContext, uiComponent, propertyDetails);
+            bviUtils.initComponentWithPropertyDetails(facesContext, uiComponent, propertyDetails);
         }
 
         if (logger.isTraceEnabled())
@@ -89,101 +77,6 @@
         }
     }
 
-    private PropertyDetails extractPropertyDetails(FacesContext facesContext, UIComponent uiComponent)
-    {
-        PropertyDetails result = ExtValUtils.getComponentMetaDataExtractor().extract(facesContext, uiComponent)
-                .getInformation(PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class);
-
-        if(result.getBaseObject() == null && this.logger.isWarnEnabled())
-        {
-            this.logger.warn("no base object at " + result.getKey() +
-                    " component-id: " + uiComponent.getClientId(facesContext));
-        }
-
-        return result.getBaseObject() != null ? result : null;
-    }
-
-    private void initComponentWithPropertyDetails(
-            FacesContext facesContext, UIComponent uiComponent, PropertyDetails propertyDetails)
-    {
-        Class[] foundGroups = resolveGroups(facesContext, uiComponent);
-
-        if(foundGroups == null)
-        {
-            return;
-        }
-        
-        ElementDescriptor elementDescriptor = getDescriptorFor(
-                propertyDetails.getBaseObject().getClass(), propertyDetails.getProperty());
-
-        if(elementDescriptor == null)
-        {
-            return;
-        }
-
-        Map<String, Object> metaData;
-
-        for (ConstraintDescriptor<?> constraintDescriptor :
-                elementDescriptor.findConstraints().unorderedAndMatchingGroups(foundGroups).getConstraintDescriptors())
-        {
-            metaData = transformConstraintDescriptorToMetaData(constraintDescriptor);
-
-            if (metaData != null && !metaData.isEmpty())
-            {
-                ExtValUtils.configureComponentWithMetaData(facesContext, uiComponent, metaData);
-            }
-        }
-    }
-
-    private Class[] resolveGroups(FacesContext facesContext, UIComponent uiComponent)
-    {
-        return ExtValBeanValidationContext.getCurrentInstance().getGroups(
-                facesContext.getViewRoot().getViewId(),
-                uiComponent.getClientId(facesContext));
-    }
-
-    private ElementDescriptor getDescriptorFor(Class targetClass, String property)
-    {
-        BeanDescriptor beanDescriptor = ExtValBeanValidationContext.getCurrentInstance().getValidatorFactory()
-                .getValidator().getConstraintsForClass(targetClass);
-
-        return beanDescriptor.getConstraintsForProperty(property);
-    }
-
-    @ToDo(Priority.HIGH)
-    private Map<String, Object> transformConstraintDescriptorToMetaData(ConstraintDescriptor<?> constraintDescriptor)
-    {
-        Map<String, Object> result = null;
-        MetaDataTransformer metaDataTransformer;
-        MetaDataEntry entry;
-        /*
-         * per default
-         * org.apache.myfaces.extensions.validator.beanval.metadata.transformer.BeanValidationMetaDataTransformer
-         * is bound to BeanValidationStrategyAdapter
-         * don't use it directly - it's possible to deactivate
-         * org.apache.myfaces.extensions.validator.beanval.metadata.transformer.mapper
-         *    .DefaultBeanValidationStrategyToMetaDataTransformerNameMapper
-         */
-        metaDataTransformer = ExtValUtils.getMetaDataTransformerForValidationStrategy(
-                new BeanValidationStrategyAdapter(constraintDescriptor));
-
-        if (metaDataTransformer != null)
-        {
-            if (this.logger.isDebugEnabled())
-            {
-                this.logger.debug(metaDataTransformer.getClass().getName() + " instantiated");
-            }
-
-            entry = new MetaDataEntry();
-            entry.setKey(constraintDescriptor.getAnnotation().annotationType().getName());
-            entry.setValue(constraintDescriptor);
-            //TODO (?) add type of property for meta-data transformation (e.g. size: string vs. number)
-
-            result = metaDataTransformer.convertMetaData(entry);
-        }
-        return result;
-    }
-
     @Override
     protected boolean recordProcessedInformation()
     {
@@ -197,19 +90,18 @@
 
         PropertyInformation propertyInformation = metaDataExtractor.extract(facesContext, uiComponent);
 
-        boolean validateProperty = processBeanValidationForProperty(propertyInformation);
+        boolean validateProperty = hasBeanValidationConstraints(propertyInformation);
         try
         {
-            if(validateProperty)
+            if (validateProperty)
             {
                 if (logger.isTraceEnabled())
                 {
                     logger.trace("jsr303 start validation");
                 }
 
-                //e.g.: extract groups for validation
-                if(!ExtValUtils.executeGlobalBeforeValidationInterceptors(facesContext, uiComponent, convertedObject,
-                        PropertyInformation.class.getName(), propertyInformation, BeanValidationModuleKey.class))
+                if (!executeGlobalBeforeValidationInterceptors(
+                        facesContext, uiComponent, convertedObject, propertyInformation))
                 {
                     return;
                 }
@@ -219,30 +111,22 @@
         }
         finally
         {
-            if(validateProperty)
+            if (validateProperty)
             {
                 if (logger.isTraceEnabled())
                 {
                     logger.trace("jsr303 validation finished");
                 }
 
-                ExtValUtils.executeGlobalAfterValidationInterceptors(facesContext, uiComponent, convertedObject,
-                        PropertyInformation.class.getName(), propertyInformation, BeanValidationModuleKey.class);
+                executeGlobalAfterValidationInterceptors(
+                        facesContext, uiComponent, convertedObject, propertyInformation);
             }
         }
     }
 
-    protected boolean processBeanValidationForProperty(PropertyInformation propertyInformation)
+    protected boolean hasBeanValidationConstraints(PropertyInformation propertyInformation)
     {
-        PropertyDetails propertyDetails = (propertyInformation.getInformation(
-                PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class));
-
-        BeanDescriptor beanDescriptor = ExtValBeanValidationContext.getCurrentInstance().getValidatorFactory()
-                .getValidator().getConstraintsForClass(propertyDetails.getBaseObject().getClass());
-
-        ElementDescriptor elementDescriptor = beanDescriptor.getConstraintsForProperty(propertyDetails.getProperty());
-
-        return elementDescriptor != null;
+        return new BeanValidationInterceptorUtils(this.logger).hasBeanValidationConstraints(propertyInformation);
     }
 
     protected void processFieldValidation(FacesContext facesContext,
@@ -250,94 +134,33 @@
                                           Object convertedObject,
                                           PropertyInformation propertyInformation)
     {
-        Class baseBeanClass = (propertyInformation.getInformation(
-                PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class)).getBaseObject().getClass();
-
-        String propertyName = (propertyInformation.getInformation(
-                PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class)).getProperty();
-
-        ExtValBeanValidationContext beanValidationContext = ExtValBeanValidationContext.getCurrentInstance();
-
-        Class[] groups = beanValidationContext.getGroups(
-                facesContext.getViewRoot().getViewId(), uiComponent.getClientId(facesContext));
-
-        if(groups == null)
-        {
-            return;
-        }
-
-        Set<ConstraintViolation> violations = ExtValBeanValidationContext.getCurrentInstance().getValidatorFactory()
-                .usingContext()
-                .messageInterpolator(ExtValBeanValidationContext.getCurrentInstance().getMessageInterpolator())
-                .getValidator()
-                .validateValue(baseBeanClass, propertyName, convertedObject, groups);
-
-        List<String> violationMessages = new ArrayList<String>();
-        for(ConstraintViolation violation : violations)
-        {
-            String violationMessage = violation.getMessage();
-
-            String labeledMessage = "{0}: " + violationMessage;
-            ValidatorException validatorException = new ValidatorException(
-                    new FacesMessage(FacesMessage.SEVERITY_ERROR, labeledMessage, labeledMessage));
-
-            ExtValUtils.executeAfterThrowingInterceptors(
-                    uiComponent,
-                    null,
-                    convertedObject,
-                    validatorException,
-                    null);
-
-            //check if the message has changed
-            if (labeledMessage.equals(validatorException.getFacesMessage().getSummary()) ||
-                    labeledMessage.equals(validatorException.getFacesMessage().getDetail()))
-            {
-                violationMessages.add(violationMessage);
-            }
-            else
-            {
-                violationMessages.add(validatorException.getFacesMessage().getSummary());
-            }
-
-            if(!supportMultipleViolationsPerField())
-            {
-                break;
-            }
-        }
-
-        if(!violationMessages.isEmpty())
-        {
-            throwException(facesContext, uiComponent, violationMessages);
-        }
+        new BeanValidationInterceptorUtils(this.logger).validate(
+                facesContext, uiComponent, convertedObject, propertyInformation, supportMultipleViolationsPerField());
     }
 
-    //override this method in the jsf 2.0 version
-    protected void throwException(FacesContext facesContext, UIComponent uiComponent, List<String> violationMessages)
+    protected boolean supportMultipleViolationsPerField()
     {
-        if(supportMultipleViolationsPerField())
-        {
-            boolean firstMessage = false;
-            for(String message : violationMessages)
-            {
-                if(!firstMessage)
-                {
-                    firstMessage = true;
-                }
-                else
-                {
-                    facesContext.addMessage(uiComponent.getClientId(facesContext),
-                            new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message));
-                }
-            }
-        }
+        return BeanValidationUtils.supportMultipleViolationsPerField();
+    }
 
-        throw new ValidatorException(
-                new FacesMessage(FacesMessage.SEVERITY_ERROR, violationMessages.get(0), violationMessages.get(0)));
+    /*
+     * e.g. extract groups for validation
+     */
+    private boolean executeGlobalBeforeValidationInterceptors(FacesContext facesContext,
+                                                              UIComponent uiComponent,
+                                                              Object convertedObject,
+                                                              PropertyInformation propertyInformation)
+    {
+        return ExtValUtils.executeGlobalBeforeValidationInterceptors(facesContext, uiComponent, convertedObject,
+                PropertyInformation.class.getName(), propertyInformation, BeanValidationModuleKey.class);
     }
 
-    //override this method in the jsf 2.0 version
-    protected boolean supportMultipleViolationsPerField()
+    private void executeGlobalAfterValidationInterceptors(FacesContext facesContext,
+                                                          UIComponent uiComponent,
+                                                          Object convertedObject,
+                                                          PropertyInformation propertyInformation)
     {
-        return "true".equalsIgnoreCase(WebXmlParameter.ACTIVATE_MULTIPLE_VIOLATIONS_PER_FIELD);
+        ExtValUtils.executeGlobalAfterValidationInterceptors(facesContext, uiComponent, convertedObject,
+                PropertyInformation.class.getName(), propertyInformation, BeanValidationModuleKey.class);
     }
 }

Added: myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationInterceptorUtils.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationInterceptorUtils.java?rev=823706&view=auto
==============================================================================
--- myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationInterceptorUtils.java (added)
+++ myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationInterceptorUtils.java Fri Oct  9 21:49:39 2009
@@ -0,0 +1,299 @@
+/*
+ * 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.beanval;
+
+import org.apache.commons.logging.Log;
+import org.apache.myfaces.extensions.validator.beanval.validation.strategy.BeanValidationStrategyAdapter;
+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
+import org.apache.myfaces.extensions.validator.core.metadata.transformer.MetaDataTransformer;
+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.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 javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.ValidatorException;
+import javax.validation.ConstraintViolation;
+import javax.validation.metadata.BeanDescriptor;
+import javax.validation.metadata.ConstraintDescriptor;
+import javax.validation.metadata.ElementDescriptor;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Gerhard Petracek
+ * @since x.x.3
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+class BeanValidationInterceptorUtils
+{
+    private Log logger;
+
+    BeanValidationInterceptorUtils(Log logger)
+    {
+        this.logger = logger;
+    }
+
+    PropertyDetails extractPropertyDetails(FacesContext facesContext, UIComponent uiComponent)
+    {
+        PropertyDetails result = ExtValUtils.getComponentMetaDataExtractor().extract(facesContext, uiComponent)
+                .getInformation(PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class);
+
+        if (result.getBaseObject() == null && this.logger.isWarnEnabled())
+        {
+            this.logger.warn("no base object at " + result.getKey() +
+                    " component-id: " + uiComponent.getClientId(facesContext));
+        }
+
+        return result.getBaseObject() != null ? result : null;
+    }
+
+    void initComponentWithPropertyDetails(
+            FacesContext facesContext, UIComponent uiComponent, PropertyDetails propertyDetails)
+    {
+        Class[] foundGroups = resolveGroups(facesContext, uiComponent);
+
+        if (foundGroups == null)
+        {
+            return;
+        }
+
+        ElementDescriptor elementDescriptor = getDescriptorFor(
+                propertyDetails.getBaseObject().getClass(), propertyDetails.getProperty());
+
+        if (elementDescriptor == null)
+        {
+            return;
+        }
+
+        Map<String, Object> metaData;
+
+        for (ConstraintDescriptor<?> constraintDescriptor :
+                elementDescriptor.findConstraints().unorderedAndMatchingGroups(foundGroups).getConstraintDescriptors())
+        {
+            metaData = transformConstraintDescriptorToMetaData(constraintDescriptor);
+
+            if (metaData != null && !metaData.isEmpty())
+            {
+                ExtValUtils.configureComponentWithMetaData(facesContext, uiComponent, metaData);
+            }
+        }
+    }
+
+    @ToDo(Priority.HIGH)
+    private Map<String, Object> transformConstraintDescriptorToMetaData(ConstraintDescriptor<?> constraintDescriptor)
+    {
+        Map<String, Object> result = null;
+        MetaDataTransformer metaDataTransformer;
+        MetaDataEntry entry;
+        /*
+        * per default
+        * org.apache.myfaces.extensions.validator.beanval.metadata.transformer.BeanValidationMetaDataTransformer
+        * is bound to BeanValidationStrategyAdapter
+        * don't use it directly - it's possible to deactivate
+        * org.apache.myfaces.extensions.validator.beanval.metadata.transformer.mapper
+        *  .DefaultBeanValidationStrategyToMetaDataTransformerNameMapper
+        */
+        metaDataTransformer = ExtValUtils.getMetaDataTransformerForValidationStrategy(
+                new BeanValidationStrategyAdapter(constraintDescriptor));
+
+        if (metaDataTransformer != null)
+        {
+            if (this.logger.isDebugEnabled())
+            {
+                this.logger.debug(metaDataTransformer.getClass().getName() + " instantiated");
+            }
+
+            entry = new MetaDataEntry();
+            entry.setKey(constraintDescriptor.getAnnotation().annotationType().getName());
+            entry.setValue(constraintDescriptor);
+            //TODO (?) add type of property for meta-data transformation (e.g. size: string vs. number)
+
+            result = metaDataTransformer.convertMetaData(entry);
+        }
+        return result;
+    }
+
+    boolean hasBeanValidationConstraints(PropertyInformation propertyInformation)
+    {
+        PropertyDetails propertyDetails = getPropertyDetails(propertyInformation);
+
+        return getDescriptorFor(propertyDetails.getBaseObject().getClass(), propertyDetails.getProperty()) != null;
+    }
+
+    @SuppressWarnings({"unchecked"})
+    void validate(FacesContext facesContext,
+                  UIComponent uiComponent,
+                  Object convertedObject,
+                  PropertyInformation propertyInformation, boolean supportMultipleViolationsPerField)
+    {
+        Class baseBeanClass = getBaseClassType(propertyInformation);
+        String propertyName = getPropertyToValidate(propertyInformation);
+
+        Class[] groups = resolveGroups(facesContext, uiComponent);
+
+        if (groups == null)
+        {
+            return;
+        }
+
+        Set<ConstraintViolation> violations = ExtValBeanValidationContext.getCurrentInstance().getValidatorFactory()
+                .usingContext()
+                .messageInterpolator(ExtValBeanValidationContext.getCurrentInstance().getMessageInterpolator())
+                .getValidator()
+                .validateValue(baseBeanClass, propertyName, convertedObject, groups);
+
+        processConstraintViolations(
+                facesContext, uiComponent, convertedObject, violations, supportMultipleViolationsPerField);
+    }
+
+    private void processConstraintViolations(FacesContext facesContext,
+                                             UIComponent uiComponent,
+                                             Object convertedObject,
+                                             Set<ConstraintViolation> violations,
+                                             boolean supportMultipleViolationsPerField)
+    {
+        List<String> violationMessages = new ArrayList<String>();
+        for (ConstraintViolation violation : violations)
+        {
+            processConstraintViolation(uiComponent, convertedObject, violation, violationMessages);
+
+            if (!supportMultipleViolationsPerField)
+            {
+                break;
+            }
+        }
+
+        if (!violationMessages.isEmpty())
+        {
+            throwException(facesContext, uiComponent, violationMessages, supportMultipleViolationsPerField);
+        }
+    }
+
+    private void processConstraintViolation(UIComponent uiComponent,
+                                            Object convertedObject,
+                                            ConstraintViolation violation,
+                                            List<String> violationMessages)
+    {
+        String violationMessage = violation.getMessage();
+
+        String labeledMessage = "{0}: " + violationMessage;
+        ValidatorException validatorException = createValidatorException(labeledMessage);
+
+        executeAfterThrowingInterceptors(uiComponent, convertedObject, validatorException);
+
+        //check if the message has changed
+        if (isMessageTextUnchanged(validatorException, labeledMessage))
+        {
+            violationMessages.add(violationMessage);
+        }
+        else
+        {
+            violationMessages.add(validatorException.getFacesMessage().getSummary());
+        }
+    }
+
+    private void executeAfterThrowingInterceptors(UIComponent uiComponent,
+                                                  Object convertedObject,
+                                                  ValidatorException validatorException)
+    {
+        ExtValUtils.executeAfterThrowingInterceptors(
+                uiComponent,
+                null,
+                convertedObject,
+                validatorException,
+                null);
+    }
+
+    private boolean isMessageTextUnchanged(ValidatorException validatorException, String violationMessage)
+    {
+        return violationMessage.equals(validatorException.getFacesMessage().getSummary()) ||
+                violationMessage.equals(validatorException.getFacesMessage().getDetail());
+    }
+
+    private ValidatorException createValidatorException(String violationMessage)
+    {
+        return new ValidatorException(
+                ExtValUtils.createFacesMessage(FacesMessage.SEVERITY_ERROR, violationMessage, violationMessage));
+    }
+
+    private Class getBaseClassType(PropertyInformation propertyInformation)
+    {
+        return getPropertyDetails(propertyInformation).getBaseObject().getClass();
+    }
+
+    private String getPropertyToValidate(PropertyInformation propertyInformation)
+    {
+        return getPropertyDetails(propertyInformation).getProperty();
+    }
+
+    private PropertyDetails getPropertyDetails(PropertyInformation propertyInformation)
+    {
+        return propertyInformation.getInformation(
+                PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class);
+    }
+
+    //override this method in the jsf 2.0 version
+    private void throwException(FacesContext facesContext, UIComponent uiComponent,
+                                List<String> violationMessages, boolean supportMultipleViolationsPerField)
+    {
+        if (supportMultipleViolationsPerField)
+        {
+            boolean firstMessage = false;
+            for (String message : violationMessages)
+            {
+                if (!firstMessage)
+                {
+                    firstMessage = true;
+                }
+                else
+                {
+                    facesContext.addMessage(uiComponent.getClientId(facesContext),
+                            ExtValUtils.createFacesMessage(FacesMessage.SEVERITY_ERROR, message, message));
+                }
+            }
+        }
+
+        throw new ValidatorException(ExtValUtils.createFacesMessage(
+                FacesMessage.SEVERITY_ERROR, violationMessages.get(0), violationMessages.get(0)));
+    }
+
+    private Class[] resolveGroups(FacesContext facesContext, UIComponent uiComponent)
+    {
+        return ExtValBeanValidationContext.getCurrentInstance().getGroups(
+                facesContext.getViewRoot().getViewId(),
+                uiComponent.getClientId(facesContext));
+    }
+
+    private ElementDescriptor getDescriptorFor(Class targetClass, String property)
+    {
+        BeanDescriptor beanDescriptor = ExtValBeanValidationContext.getCurrentInstance().getValidatorFactory()
+                .getValidator().getConstraintsForClass(targetClass);
+
+        return beanDescriptor.getConstraintsForProperty(property);
+    }
+}
\ No newline at end of file

Modified: myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationPhaseListener.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationPhaseListener.java?rev=823706&r1=823705&r2=823706&view=diff
==============================================================================
--- myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationPhaseListener.java (original)
+++ myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationPhaseListener.java Fri Oct  9 21:49:39 2009
@@ -21,8 +21,8 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.myfaces.extensions.validator.beanval.ExtValBeanValidationContext;
-import org.apache.myfaces.extensions.validator.beanval.storage.ModelValidationEntry;
 import org.apache.myfaces.extensions.validator.beanval.annotation.ModelValidation;
+import org.apache.myfaces.extensions.validator.beanval.storage.ModelValidationEntry;
 import org.apache.myfaces.extensions.validator.internal.Priority;
 import org.apache.myfaces.extensions.validator.internal.ToDo;
 import org.apache.myfaces.extensions.validator.util.ExtValUtils;
@@ -59,12 +59,9 @@
             logger.trace("jsr303 start model validation");
         }
 
-        List<ModelValidationEntry> modelValidationEntries = ExtValBeanValidationContext.getCurrentInstance()
-                .getModelValidationEntriesToValidate();
-
         List<Object> processedValidationTargets = new ArrayList<Object>();
 
-        for (ModelValidationEntry modelValidationEntry : modelValidationEntries)
+        for (ModelValidationEntry modelValidationEntry : getModelValidationEntriesToValidate())
         {
             processModelValidation(modelValidationEntry, processedValidationTargets);
         }
@@ -75,6 +72,11 @@
         }
     }
 
+    private List<ModelValidationEntry> getModelValidationEntriesToValidate()
+    {
+        return ExtValBeanValidationContext.getCurrentInstance().getModelValidationEntriesToValidate();
+    }
+
     private void processModelValidation(
             ModelValidationEntry modelValidationEntry, List<Object> processedValidationTargets)
     {
@@ -91,39 +93,41 @@
                 processedValidationTargets.add(validationTarget);
             }
 
-            Set<ConstraintViolation<Object>> violations = ExtValBeanValidationContext.getCurrentInstance()
-                    .getValidatorFactory().usingContext()
-                    .messageInterpolator(ExtValBeanValidationContext.getCurrentInstance().getMessageInterpolator())
-                    .getValidator()
-                    .validate(validationTarget, modelValidationEntry.getGroups());
+            validateTarget(modelValidationEntry, validationTarget, modelValidationEntry.getGroups());
+        }
+    }
 
-            if (violations != null && violations.size() > 0)
+    private void validateTarget(ModelValidationEntry modelValidationEntry, Object validationTarget, Class[] groups)
+    {
+        Set<ConstraintViolation<Object>> violations = ExtValBeanValidationContext.getCurrentInstance()
+                .getValidatorFactory().usingContext()
+                .messageInterpolator(ExtValBeanValidationContext.getCurrentInstance().getMessageInterpolator())
+                .getValidator()
+                .validate(validationTarget, groups);
+
+        if (violations != null && violations.size() > 0)
+        {
+            FacesContext.getCurrentInstance().renderResponse();
+
+            //jsf 2.0 is able to display multiple messages per component - so process all violations
+            //jsf < 2.0 will just use the first one (it's only a little overhead)
+            Iterator violationsIterator = violations.iterator();
+            ConstraintViolation constraintViolation;
+            while (violationsIterator.hasNext())
             {
-                FacesContext.getCurrentInstance().renderResponse();
-
-                //jsf 2.0 is able to display multiple messages per component - so process all violations
-                //jsf < 2.0 will just use the first one (it's only a little overhead)
-                Iterator violationsIterator = violations.iterator();
-                ConstraintViolation constraintViolation;
-                while (violationsIterator.hasNext())
+                constraintViolation = (ConstraintViolation) violationsIterator.next();
+                if (modelValidationEntry.getMetaData().displayInline())
                 {
-                    constraintViolation = (ConstraintViolation) violationsIterator.next();
-                    if (modelValidationEntry.getMetaData().displayInline())
-                    {
-                        processConstraintViolation(constraintViolation, modelValidationEntry, validationTarget, true);
-                    }
-                    else
-                    {
-                        processConstraintViolation(constraintViolation, modelValidationEntry, validationTarget, false);
-                    }
+                    processConstraintViolation(constraintViolation, modelValidationEntry, validationTarget, true);
+                }
+                else
+                {
+                    processConstraintViolation(constraintViolation, modelValidationEntry, validationTarget, false);
                 }
             }
         }
     }
 
-    @SuppressWarnings({"ThrowableInstanceNeverThrown"})
-    @ToDo(value = Priority.HIGH, description = "use ExtValUtils#createFacesMessage" +
-            "check ExtValUtils#executeAfterThrowingInterceptors")
     private void processConstraintViolation(final ConstraintViolation violation,
                                             ModelValidationEntry modelValidationEntry,
                                             final Object validationTarget,
@@ -131,8 +135,7 @@
     {
         String violationMessage = violation.getMessage();
 
-        ValidatorException validatorException = new ValidatorException(
-                new FacesMessage(FacesMessage.SEVERITY_ERROR, violationMessage, violationMessage));
+        ValidatorException validatorException = createValidatorException(violationMessage);
 
         FacesContext facesContext = FacesContext.getCurrentInstance();
         UIComponent uiComponent = null;
@@ -144,48 +147,97 @@
             clientId = modelValidationEntry.getComponent().getClientId(facesContext);
         }
 
-        if (!ModelValidation.DEFAULT_MESSAGE.equals(modelValidationEntry.getMetaData().message()))
+        tryToChangeViolationMessage(modelValidationEntry, validationTarget, violation, validatorException);
+        executeValidationExceptionInterceptors(uiComponent, validationTarget, validatorException);
+        addViolationMessage(facesContext, clientId, violationMessage, validatorException);
+    }
+
+    private ValidatorException createValidatorException(String violationMessage)
+    {
+        return new ValidatorException(
+                ExtValUtils.createFacesMessage(FacesMessage.SEVERITY_ERROR, violationMessage, violationMessage));
+    }
+
+    private void tryToChangeViolationMessage(ModelValidationEntry modelValidationEntry,
+                                    Object validationTarget,
+                                    ConstraintViolation violation,
+                                    ValidatorException validatorException)
+    {
+        if (!isDefaultMessage(modelValidationEntry))
         {
-            String validationErrorMessage = ExtValBeanValidationContext.getCurrentInstance().getMessageInterpolator()
-                    .interpolate(modelValidationEntry.getMetaData().message(),
-                            new MessageInterpolator.Context()
+            String newValidationErrorMessage = interpolateValidationErrorMessage(
+                    modelValidationEntry, validationTarget, violation);
+
+            changeViolationMessage(validatorException.getFacesMessage(), newValidationErrorMessage);
+        }
+    }
+
+    private boolean isDefaultMessage(ModelValidationEntry modelValidationEntry)
+    {
+        return ModelValidation.DEFAULT_MESSAGE.equals(modelValidationEntry.getMetaData().message());
+    }
+
+    private String interpolateValidationErrorMessage(ModelValidationEntry modelValidationEntry,
+                                                     final Object validationTarget, final ConstraintViolation violation)
+    {
+        return ExtValBeanValidationContext.getCurrentInstance().getMessageInterpolator()
+                .interpolate(modelValidationEntry.getMetaData().message(),
+                        new MessageInterpolator.Context()
+                        {
+                            public ConstraintDescriptor<?> getConstraintDescriptor()
                             {
+                                return violation.getConstraintDescriptor();
+                            }
 
-                                public ConstraintDescriptor<?> getConstraintDescriptor()
-                                {
-                                    return violation.getConstraintDescriptor();
-                                }
-
-                                public Object getValidatedValue()
-                                {
-                                    return validationTarget;
-                                }
+                            public Object getValidatedValue()
+                            {
+                                return validationTarget;
                             }
-                    );
+                        }
+                );
+    }
 
-            validatorException.getFacesMessage().setSummary(validationErrorMessage);
-            validatorException.getFacesMessage().setDetail(validationErrorMessage);
-        }
+    private void changeViolationMessage(FacesMessage facesMessage, String newMessage)
+    {
+        facesMessage.setSummary(newMessage);
+        facesMessage.setDetail(newMessage);
+    }
 
+    @ToDo(value = Priority.HIGH, description = "test compatibility")
+    private void executeValidationExceptionInterceptors(
+            UIComponent uiComponent, Object validationTarget, ValidatorException validatorException)
+    {
         ExtValUtils.executeAfterThrowingInterceptors(
                 uiComponent,
                 null,
                 validationTarget,
                 validatorException,
                 null);
+    }
 
-        if (violationMessage.equals(validatorException.getFacesMessage().getSummary()) ||
-                violationMessage.equals(validatorException.getFacesMessage().getDetail()))
+    private void addViolationMessage(
+            FacesContext facesContext, String clientId, String violationMessage, ValidatorException validatorException)
+    {
+        if (isMessageTextUnchanged(validatorException, violationMessage))
         {
+            //use old message text
             facesContext.addMessage(clientId,
-                    new FacesMessage(FacesMessage.SEVERITY_ERROR, violationMessage, violationMessage));
+                    ExtValUtils.createFacesMessage(validatorException.getFacesMessage().getSeverity(),
+                            violationMessage, violationMessage));
         }
         else
         {
+            //use new message text
             facesContext.addMessage(clientId, validatorException.getFacesMessage());
         }
     }
 
+    private boolean isMessageTextUnchanged(ValidatorException validatorException, String violationMessage)
+    {
+        return violationMessage.equals(validatorException.getFacesMessage().getSummary()) ||
+                violationMessage.equals(validatorException.getFacesMessage().getDetail());
+    }
+
     public void beforePhase(PhaseEvent phaseEvent)
     {
         //do nothing

Added: myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/util/BeanValidationUtils.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/util/BeanValidationUtils.java?rev=823706&view=auto
==============================================================================
--- myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/util/BeanValidationUtils.java (added)
+++ myfaces/extensions/validator/trunk/validation-modules/bean-validation/src/main/java/util/BeanValidationUtils.java Fri Oct  9 21:49:39 2009
@@ -0,0 +1,40 @@
+/*
+ * 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 util;
+
+import org.apache.myfaces.extensions.validator.core.WebXmlParameter;
+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;
+
+/**
+ * @author Gerhard Petracek
+ * @since x.x.3
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public class BeanValidationUtils
+{
+    @ToDo(value = Priority.LOW, description = "use it also in ModelValidationPhaseListener" +
+            "attention: only add one message per client id")
+    public static boolean supportMultipleViolationsPerField()
+    {
+        return "true".equalsIgnoreCase(WebXmlParameter.ACTIVATE_MULTIPLE_VIOLATIONS_PER_FIELD);
+    }
+}