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/22 21:46:30 UTC

svn commit: r828830 [2/2] - in /myfaces/extensions/validator/branches/branch_for_jsf_1_1: core/src/main/java/org/apache/myfaces/extensions/validator/core/ core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ core/src/main/java/o...

Added: myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/payload/ViolationSeverity.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/payload/ViolationSeverity.java?rev=828830&view=auto
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/payload/ViolationSeverity.java (added)
+++ myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/payload/ViolationSeverity.java Thu Oct 22 19:46:27 2009
@@ -0,0 +1,53 @@
+/*
+ * 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.payload;
+
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+
+import javax.validation.Payload;
+import javax.faces.application.FacesMessage;
+
+/**
+ * @author Gerhard Petracek
+ * @since x.x.3
+ */
+@UsageInformation(UsageCategory.API)
+public interface ViolationSeverity
+{
+    interface Info extends Payload
+    {
+        FacesMessage.Severity VALUE = FacesMessage.SEVERITY_INFO;
+    }
+
+    interface Warn extends Payload
+    {
+        FacesMessage.Severity VALUE = FacesMessage.SEVERITY_WARN;
+    }
+
+    interface Error extends Payload
+    {
+        FacesMessage.Severity VALUE = FacesMessage.SEVERITY_ERROR;
+    }
+
+    interface Fatal extends Payload
+    {
+        FacesMessage.Severity VALUE = FacesMessage.SEVERITY_FATAL;
+    }
+}

Modified: myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/DefaultBeanValidationGroupStorage.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/DefaultBeanValidationGroupStorage.java?rev=828830&r1=828829&r2=828830&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/DefaultBeanValidationGroupStorage.java (original)
+++ myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/DefaultBeanValidationGroupStorage.java Thu Oct 22 19:46:27 2009
@@ -32,9 +32,9 @@
 public class DefaultBeanValidationGroupStorage extends DefaultGroupStorage
 {
     @Override
-    public Class[] getGroups(String viewId, String componentId)
+    public Class[] getGroups(String viewId, String clientId)
     {
-        Class[] result = super.getGroups(viewId, componentId);
+        Class[] result = super.getGroups(viewId, clientId);
 
         if(result == null)
         {

Modified: myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/DefaultModelValidationStorage.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/DefaultModelValidationStorage.java?rev=828830&r1=828829&r2=828830&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/DefaultModelValidationStorage.java (original)
+++ myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/DefaultModelValidationStorage.java Thu Oct 22 19:46:27 2009
@@ -48,21 +48,21 @@
     {
         modelValidationEntry.setComponent(component);
 
-        String componentId = null;
+        String clientId = null;
 
         if(component != null)
         {
-            componentId = component.getClientId(FacesContext.getCurrentInstance());
-            this.componentsOfRequest.add(componentId);
+            clientId = component.getClientId(FacesContext.getCurrentInstance());
+            this.componentsOfRequest.add(clientId);
         }
 
         List<ModelValidationEntry> modelValidationEntryList =
-                this.modelValidationEntries.get(GroupUtils.getGroupKey(viewId, componentId));
+                this.modelValidationEntries.get(GroupUtils.getGroupKey(viewId, clientId));
 
         if(modelValidationEntryList == null)
         {
             modelValidationEntryList = new ArrayList<ModelValidationEntry>();
-            this.modelValidationEntries.put(GroupUtils.getGroupKey(viewId, componentId), modelValidationEntryList);
+            this.modelValidationEntries.put(GroupUtils.getGroupKey(viewId, clientId), modelValidationEntryList);
         }
 
         if(!modelValidationEntryList.contains(modelValidationEntry))
@@ -116,7 +116,7 @@
         return getModelValidationEntries(viewId, null);
     }
 
-    private List<ModelValidationEntry> getModelValidationEntries(String viewId, String componentId)
+    private List<ModelValidationEntry> getModelValidationEntries(String viewId, String clientId)
     {
         if(this.modelValidationEntries.size() < 1)
         {
@@ -127,14 +127,14 @@
         String key;
         List<ModelValidationEntry> resultListForPage = null;
 
-        if(!"*".equals(componentId))
+        if(!"*".equals(clientId))
         {
             key = GroupUtils.getGroupKey(viewId, null);
             resultListForPage =
                     buildModelValidationEntryList(key, this.modelValidationEntries);
         }
 
-        key = GroupUtils.getGroupKey(viewId, componentId);
+        key = GroupUtils.getGroupKey(viewId, clientId);
         List<ModelValidationEntry> resultListForComponent =
                 buildModelValidationEntryList(key, this.modelValidationEntries);
 

Modified: myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/util/BeanValidationUtils.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/util/BeanValidationUtils.java?rev=828830&r1=828829&r2=828830&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/util/BeanValidationUtils.java (original)
+++ myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/util/BeanValidationUtils.java Thu Oct 22 19:46:27 2009
@@ -24,8 +24,10 @@
 import org.apache.myfaces.extensions.validator.beanval.annotation.BeanValidation;
 import org.apache.myfaces.extensions.validator.beanval.annotation.ModelValidation;
 import org.apache.myfaces.extensions.validator.beanval.annotation.extractor.DefaultGroupControllerScanningExtractor;
+import org.apache.myfaces.extensions.validator.beanval.payload.ViolationSeverity;
 import org.apache.myfaces.extensions.validator.beanval.storage.ModelValidationEntry;
 import org.apache.myfaces.extensions.validator.core.WebXmlParameter;
+import org.apache.myfaces.extensions.validator.core.validation.message.FacesMessageHolder;
 import org.apache.myfaces.extensions.validator.core.el.ELHelper;
 import org.apache.myfaces.extensions.validator.core.el.ValueBindingExpression;
 import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
@@ -38,12 +40,17 @@
 import org.apache.myfaces.extensions.validator.util.ExtValUtils;
 import org.apache.myfaces.extensions.validator.util.ReflectionUtils;
 
+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.Payload;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Set;
 
 /**
  * @author Gerhard Petracek
@@ -53,8 +60,9 @@
 public class BeanValidationUtils
 {
     private static final Log LOG = LogFactory.getLog(BeanValidationUtils.class);
+    private static LabeledMessageInternals labeledMessageInternals = new LabeledMessageInternals();
 
-    @ToDo(value = Priority.LOW, description = "use it also in ModelValidationPhaseListener" +
+    @ToDo(value = Priority.HIGH, description = "use it - also in ModelValidationPhaseListener" +
             "attention: only add one message per client id")
     public static boolean supportMultipleViolationsPerField()
     {
@@ -461,4 +469,179 @@
         }
         return ReflectionUtils.tryToInvokeMethod(base, targetMethod);
     }
+
+    public static void processConstraintViolations(FacesContext facesContext,
+                                                   UIComponent uiComponent,
+                                                   Object convertedObject,
+                                                   Set<ConstraintViolation> violations,
+                                                   boolean firstErrorCausesAnException)
+    {
+        List<FacesMessageHolder> facesMessageHolderList = new ArrayList<FacesMessageHolder>();
+        FacesMessageHolder facesMessageHolder;
+
+        for (ConstraintViolation violation : violations)
+        {
+            facesMessageHolder = new FacesMessageHolder(
+                    createFacesMessageForConstraintViolation(uiComponent, convertedObject, violation));
+            facesMessageHolder.setClientId(uiComponent.getClientId(facesContext));
+
+            facesMessageHolderList.add(facesMessageHolder);
+        }
+
+        processViolationMessages(facesMessageHolderList, firstErrorCausesAnException);
+    }
+
+    @ToDo(value = Priority.HIGH, description = "support severity.warn and .info")
+    public static FacesMessage createFacesMessageForConstraintViolation(UIComponent uiComponent,
+                                                                        Object convertedObject,
+                                                                        ConstraintViolation violation)
+    {
+        String violationMessage = violation.getMessage();
+
+        String labeledMessage = createLabeledMessage(violationMessage);
+
+        FacesMessage.Severity severity = calcSeverity(violation);
+
+        ValidatorException validatorException = createValidatorException(labeledMessage, severity);
+
+        executeAfterThrowingInterceptors(uiComponent, convertedObject, validatorException);
+
+        if (isMessageTextUnchanged(validatorException, labeledMessage))
+        {
+            return ExtValUtils.createFacesMessage(severity, violationMessage, violationMessage);
+        }
+        else
+        {
+            String newMessage = validatorException.getFacesMessage().getSummary();
+            return ExtValUtils.createFacesMessage(severity, newMessage, newMessage);
+        }
+    }
+
+    private static String createLabeledMessage(String violationMessage)
+    {
+        return labeledMessageInternals.createLabeledMessage(violationMessage);
+    }
+
+    private static FacesMessage.Severity calcSeverity(ConstraintViolation<?> violation)
+    {
+        for (Class<? extends Payload> payload : violation.getConstraintDescriptor().getPayload())
+        {
+            if (ViolationSeverity.Warn.class.isAssignableFrom(payload))
+            {
+                return FacesMessage.SEVERITY_WARN;
+            }
+            else if (ViolationSeverity.Info.class.isAssignableFrom(payload))
+            {
+                return FacesMessage.SEVERITY_INFO;
+            }
+            else if (ViolationSeverity.Fatal.class.isAssignableFrom(payload))
+            {
+                return FacesMessage.SEVERITY_FATAL;
+            }
+        }
+        return FacesMessage.SEVERITY_ERROR;
+    }
+
+    private static void executeAfterThrowingInterceptors(UIComponent uiComponent,
+                                                         Object convertedObject,
+                                                         ValidatorException validatorException)
+    {
+        ExtValUtils.executeAfterThrowingInterceptors(
+                uiComponent,
+                null,
+                convertedObject,
+                validatorException,
+                null);
+    }
+
+    private static boolean isMessageTextUnchanged(ValidatorException validatorException, String violationMessage)
+    {
+        return violationMessage.equals(validatorException.getFacesMessage().getSummary()) ||
+                violationMessage.equals(validatorException.getFacesMessage().getDetail());
+    }
+
+    private static ValidatorException createValidatorException(String violationMessage, FacesMessage.Severity severity)
+    {
+        return new ValidatorException(
+                ExtValUtils.createFacesMessage(severity, violationMessage, violationMessage));
+    }
+
+    public static void processViolationMessages(List<FacesMessageHolder> violationMessageHolderList,
+                                                boolean firstErrorCausesAnException)
+    {
+        List<FacesMessageHolder> facesMessageListWithLowSeverity =
+                getFacesMessageListWithLowSeverity(violationMessageHolderList);
+        List<FacesMessageHolder> facesMessageListWithHighSeverity =
+                getFacesMessageListWithHighSeverity(violationMessageHolderList);
+
+        addMessagesWithHighSeverity(facesMessageListWithHighSeverity, firstErrorCausesAnException);
+        addMessagesWithLowSeverity(facesMessageListWithLowSeverity);
+
+        if (!facesMessageListWithHighSeverity.isEmpty() && firstErrorCausesAnException)
+        {
+            FacesMessageHolder facesMessageHolder = facesMessageListWithHighSeverity.iterator().next();
+            ExtValUtils.tryToThrowValidatorExceptionForComponentId(
+                    facesMessageHolder.getClientId(), facesMessageHolder.getFacesMessage(), null);
+        }
+    }
+
+    private static List<FacesMessageHolder> getFacesMessageListWithLowSeverity(
+            List<FacesMessageHolder> violationMessages)
+    {
+        List<FacesMessageHolder> result = new ArrayList<FacesMessageHolder>();
+
+        for (FacesMessageHolder facesMessageHolder : violationMessages)
+        {
+            if (FacesMessage.SEVERITY_WARN.equals(facesMessageHolder.getFacesMessage().getSeverity()) ||
+                    FacesMessage.SEVERITY_INFO.equals(facesMessageHolder.getFacesMessage().getSeverity()))
+            {
+                result.add(facesMessageHolder);
+            }
+        }
+        return result;
+    }
+
+    private static List<FacesMessageHolder> getFacesMessageListWithHighSeverity(
+            List<FacesMessageHolder> violationMessageHolderList)
+    {
+        List<FacesMessageHolder> result = new ArrayList<FacesMessageHolder>();
+
+        for (FacesMessageHolder facesMessageHolder : violationMessageHolderList)
+        {
+            if (FacesMessage.SEVERITY_ERROR.equals(facesMessageHolder.getFacesMessage().getSeverity()) ||
+                    FacesMessage.SEVERITY_FATAL.equals(facesMessageHolder.getFacesMessage().getSeverity()))
+            {
+                result.add(facesMessageHolder);
+            }
+        }
+        return result;
+    }
+
+    private static void addMessagesWithHighSeverity(List<FacesMessageHolder> facesMessageHolderListWithHighSeverity,
+                                                    boolean firstErrorCausesAnException)
+    {
+        boolean firstMessage = true;
+        for (FacesMessageHolder facesMessageHolder : facesMessageHolderListWithHighSeverity)
+        {
+            if (firstMessage && firstErrorCausesAnException)
+            {
+                //the first error will be thrown as exception
+                firstMessage = false;
+            }
+            else
+            {
+                ExtValUtils.tryToAddViolationMessageForComponentId(
+                        facesMessageHolder.getClientId(), facesMessageHolder.getFacesMessage());
+            }
+        }
+    }
+
+    private static void addMessagesWithLowSeverity(List<FacesMessageHolder> facesMessageHolderListWithLowSeverity)
+    {
+        for (FacesMessageHolder facesMessageHolder : facesMessageHolderListWithLowSeverity)
+        {
+            ExtValUtils.tryToAddViolationMessageForComponentId(
+                    facesMessageHolder.getClientId(), facesMessageHolder.getFacesMessage());
+        }
+    }
 }

Added: myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/util/LabeledMessageInternals.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/util/LabeledMessageInternals.java?rev=828830&view=auto
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/util/LabeledMessageInternals.java (added)
+++ myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/util/LabeledMessageInternals.java Thu Oct 22 19:46:27 2009
@@ -0,0 +1,67 @@
+/*
+ * 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.util;
+
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.util.JsfUtils;
+
+import java.util.MissingResourceException;
+
+/**
+ * @author Gerhard Petracek
+ * @since x.x.3
+ */
+@UsageInformation(UsageCategory.API)
+class LabeledMessageInternals
+{
+    //there is no concurrency issue here - it always leads to the same result
+    private final String defaultLabelMessageTemplate = "{1}: {0}";
+    private String labelMessageTemplate = defaultLabelMessageTemplate;
+    private static final String JAVAX_FACES_VALIDATOR_BEANVALIDATOR_MESSAGE =
+            "javax.faces.validator.BeanValidator.MESSAGE";
+
+    String createLabeledMessage(String violationMessage)
+    {
+        if(labelMessageTemplate == null)
+        {
+            return this.defaultLabelMessageTemplate.replace("{0}", violationMessage);
+        }
+
+        this.labelMessageTemplate = loadStandardMessageTemplate();
+
+        if(labelMessageTemplate == null)
+        {
+            return createLabeledMessage(violationMessage);
+        }
+        return labelMessageTemplate.replace("{0}", violationMessage);
+    }
+
+    private String loadStandardMessageTemplate()
+    {
+        try
+        {
+            return JsfUtils.getDefaultFacesMessageBundle().getString(JAVAX_FACES_VALIDATOR_BEANVALIDATOR_MESSAGE);
+        }
+        catch (MissingResourceException e)
+        {
+            return null;
+        }
+    }
+}

Modified: myfaces/extensions/validator/branches/branch_for_jsf_1_1/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/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationPhaseListener.java?rev=828830&r1=828829&r2=828830&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationPhaseListener.java (original)
+++ myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationPhaseListener.java Thu Oct 22 19:46:27 2009
@@ -23,20 +23,22 @@
 import org.apache.myfaces.extensions.validator.beanval.ExtValBeanValidationContext;
 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.beanval.util.BeanValidationUtils;
 import org.apache.myfaces.extensions.validator.internal.ToDo;
-import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+import org.apache.myfaces.extensions.validator.internal.Priority;
+import org.apache.myfaces.extensions.validator.core.validation.message.FacesMessageHolder;
 
-import javax.faces.application.FacesMessage;
 import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
 import javax.faces.event.PhaseEvent;
 import javax.faces.event.PhaseId;
 import javax.faces.event.PhaseListener;
-import javax.faces.validator.ValidatorException;
 import javax.validation.ConstraintViolation;
 import javax.validation.MessageInterpolator;
+import javax.validation.Path;
 import javax.validation.metadata.ConstraintDescriptor;
+import java.util.Map;
+import java.util.HashMap;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -61,11 +63,15 @@
 
         List<Object> processedValidationTargets = new ArrayList<Object>();
 
+        Map<String, ModelValidationResult> results = new HashMap<String, ModelValidationResult>();
+
         for (ModelValidationEntry modelValidationEntry : getModelValidationEntriesToValidate())
         {
-            processModelValidation(modelValidationEntry, processedValidationTargets);
+            processModelValidation(modelValidationEntry, processedValidationTargets, results);
         }
 
+        processViolations(results);
+
         if (logger.isTraceEnabled())
         {
             logger.trace("jsr303 validation finished");
@@ -77,8 +83,9 @@
         return ExtValBeanValidationContext.getCurrentInstance().getModelValidationEntriesToValidate();
     }
 
-    private void processModelValidation(
-            ModelValidationEntry modelValidationEntry, List<Object> processedValidationTargets)
+    private void processModelValidation(ModelValidationEntry modelValidationEntry,
+                                        List<Object> processedValidationTargets,
+                                        Map<String, ModelValidationResult> results)
     {
         for (Object validationTarget : modelValidationEntry.getValidationTargets())
         {
@@ -93,11 +100,15 @@
                 processedValidationTargets.add(validationTarget);
             }
 
-            validateTarget(modelValidationEntry, validationTarget, modelValidationEntry.getGroups());
+            validateTarget(modelValidationEntry, validationTarget, modelValidationEntry.getGroups(), results);
         }
     }
 
-    private void validateTarget(ModelValidationEntry modelValidationEntry, Object validationTarget, Class[] groups)
+    @ToDo(value = Priority.HIGH, description = "refactor and remove FacesContext#renderResponse")
+    private void validateTarget(ModelValidationEntry modelValidationEntry,
+                                Object validationTarget,
+                                Class[] groups,
+                                Map<String, ModelValidationResult> results)
     {
         Set<ConstraintViolation<Object>> violations = ExtValBeanValidationContext.getCurrentInstance()
                 .getValidatorFactory().usingContext()
@@ -105,71 +116,120 @@
                 .getValidator()
                 .validate(validationTarget, groups);
 
-        if (violations != null && violations.size() > 0)
+        if (violations != null && !violations.isEmpty())
         {
-            FacesContext.getCurrentInstance().renderResponse();
+            FacesContext facesContext = FacesContext.getCurrentInstance();
+            facesContext.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;
+            ModelValidationResult result;
             while (violationsIterator.hasNext())
             {
+                if (!results.containsKey(modelValidationEntry.getComponent().getClientId(facesContext)))
+                {
+                    result = new ModelValidationResult();
+                    results.put(modelValidationEntry.getComponent().getClientId(facesContext), result);
+                }
+
+                result = results.get(modelValidationEntry.getComponent().getClientId(facesContext));
+
                 constraintViolation = (ConstraintViolation) violationsIterator.next();
                 if (modelValidationEntry.getMetaData().displayInline())
                 {
-                    processConstraintViolation(constraintViolation, modelValidationEntry, validationTarget, true);
+                    result.addFacesMessageHolder(createFacesMessageHolderForConstraintViolation(
+                            constraintViolation, modelValidationEntry, validationTarget, true));
                 }
                 else
                 {
-                    processConstraintViolation(constraintViolation, modelValidationEntry, validationTarget, false);
+                    result.addFacesMessageHolder(createFacesMessageHolderForConstraintViolation(
+                            constraintViolation, modelValidationEntry, validationTarget, false));
                 }
             }
         }
     }
 
-    private void processConstraintViolation(final ConstraintViolation violation,
-                                            ModelValidationEntry modelValidationEntry,
-                                            final Object validationTarget,
-                                            boolean displayAtComponent)
+    private FacesMessageHolder createFacesMessageHolderForConstraintViolation(final ConstraintViolation violation,
+                                                                        ModelValidationEntry modelValidationEntry,
+                                                                        final Object validationTarget,
+                                                                        boolean displayAtComponent)
     {
-        String violationMessage = violation.getMessage();
+        final String newViolationMessage = tryToChangeViolationMessage(
+                modelValidationEntry, validationTarget, violation);
+
+        ConstraintViolation newConstraintViolation = new ConstraintViolation()
+        {
+            private ConstraintViolation wrapped = violation;
+
+            public String getMessage()
+            {
+                return newViolationMessage;
+            }
+
+            public String getMessageTemplate()
+            {
+                return wrapped.getMessageTemplate();
+            }
+
+            public Object getRootBean()
+            {
+                return wrapped.getRootBean();
+            }
+
+            public Class getRootBeanClass()
+            {
+                return wrapped.getRootBeanClass();
+            }
+
+            public Object getLeafBean()
+            {
+                return wrapped.getLeafBean();
+            }
+
+            public Path getPropertyPath()
+            {
+                return wrapped.getPropertyPath();
+            }
+
+            public Object getInvalidValue()
+            {
+                return wrapped.getInvalidValue();
+            }
+
+            public ConstraintDescriptor getConstraintDescriptor()
+            {
+                return wrapped.getConstraintDescriptor();
+            }
+        };
 
-        ValidatorException validatorException = createValidatorException(violationMessage);
 
-        FacesContext facesContext = FacesContext.getCurrentInstance();
         UIComponent uiComponent = null;
         String clientId = null;
 
         if (displayAtComponent)
         {
             uiComponent = modelValidationEntry.getComponent();
-            clientId = modelValidationEntry.getComponent().getClientId(facesContext);
+            clientId = uiComponent.getClientId(FacesContext.getCurrentInstance());
         }
 
-        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));
+        FacesMessageHolder result = new FacesMessageHolder(BeanValidationUtils
+                .createFacesMessageForConstraintViolation(uiComponent, validationTarget, newConstraintViolation));
+        result.setClientId(clientId);
+        return result;
     }
 
-    private void tryToChangeViolationMessage(ModelValidationEntry modelValidationEntry,
-                                    Object validationTarget,
-                                    ConstraintViolation violation,
-                                    ValidatorException validatorException)
+    private String tryToChangeViolationMessage(ModelValidationEntry modelValidationEntry,
+                                               Object validationTarget,
+                                               ConstraintViolation violation)
     {
         if (!isDefaultMessage(modelValidationEntry))
         {
-            String newValidationErrorMessage = interpolateValidationErrorMessage(
-                    modelValidationEntry, validationTarget, violation);
-
-            changeViolationMessage(validatorException.getFacesMessage(), newValidationErrorMessage);
+            return interpolateValidationErrorMessage(
+                    modelValidationEntry.getMetaData().message(), validationTarget, violation);
         }
+        return violation.getMessage();
     }
 
     private boolean isDefaultMessage(ModelValidationEntry modelValidationEntry)
@@ -177,11 +237,12 @@
         return ModelValidation.DEFAULT_MESSAGE.equals(modelValidationEntry.getMetaData().message());
     }
 
-    private String interpolateValidationErrorMessage(ModelValidationEntry modelValidationEntry,
+    private String interpolateValidationErrorMessage(String extValInlineMessage,
                                                      final Object validationTarget, final ConstraintViolation violation)
     {
         return ExtValBeanValidationContext.getCurrentInstance().getMessageInterpolator()
-                .interpolate(modelValidationEntry.getMetaData().message(),
+                .interpolate(
+                        extValInlineMessage,
                         new MessageInterpolator.Context()
                         {
                             public ConstraintDescriptor<?> getConstraintDescriptor()
@@ -197,47 +258,14 @@
                 );
     }
 
-    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);
-    }
-
-    private void addViolationMessage(
-            FacesContext facesContext, String clientId, String violationMessage, ValidatorException validatorException)
+    private void processViolations(Map<String, ModelValidationResult> results)
     {
-        if (isMessageTextUnchanged(validatorException, violationMessage))
-        {
-            //use old message text
-            facesContext.addMessage(clientId,
-                    ExtValUtils.createFacesMessage(validatorException.getFacesMessage().getSeverity(),
-                            violationMessage, violationMessage));
-        }
-        else
+        for (ModelValidationResult result : results.values())
         {
-            //use new message text
-            facesContext.addMessage(clientId, validatorException.getFacesMessage());
+            BeanValidationUtils.processViolationMessages(result.getFacesMessageHolderList(), false);
         }
     }
 
-    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/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationResult.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationResult.java?rev=828830&view=auto
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationResult.java (added)
+++ myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationResult.java Thu Oct 22 19:46:27 2009
@@ -0,0 +1,49 @@
+/*
+ * 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.validation;
+
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.ToDo;
+import org.apache.myfaces.extensions.validator.internal.Priority;
+import org.apache.myfaces.extensions.validator.core.validation.message.FacesMessageHolder;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * @author Gerhard Petracek
+ * @since x.x.3
+ */
+@ToDo(value = Priority.LOW, description = "refactor")
+@UsageInformation(UsageCategory.INTERNAL)
+class ModelValidationResult
+{
+    private List<FacesMessageHolder> facesMessageHolderList = new ArrayList<FacesMessageHolder>();
+
+    public void addFacesMessageHolder(FacesMessageHolder facesMessageHolder)
+    {
+        this.facesMessageHolderList.add(facesMessageHolder);
+    }
+
+    public List<FacesMessageHolder> getFacesMessageHolderList()
+    {
+        return facesMessageHolderList;
+    }
+}

Modified: myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/CrossValidationPhaseListener.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/CrossValidationPhaseListener.java?rev=828830&r1=828829&r2=828830&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/CrossValidationPhaseListener.java (original)
+++ myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/CrossValidationPhaseListener.java Thu Oct 22 19:46:27 2009
@@ -121,10 +121,10 @@
                         if (facesMessage != null &&
                                 facesMessage.getSummary() != null && facesMessage.getDetail() != null)
                         {
-                            event.getFacesContext().addMessage(entry.getClientId(), facesMessage);
+                            ExtValUtils.tryToAddViolationMessageForComponentId(entry.getClientId(), facesMessage);
                         }
 
-                        event.getFacesContext().renderResponse();
+                        ExtValUtils.tryToBlocksNavigationForComponentId(entry.getClientId(), facesMessage);
                     }
                 }
                 finally

Modified: myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/AbstractCompareStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/AbstractCompareStrategy.java?rev=828830&r1=828829&r2=828830&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/AbstractCompareStrategy.java (original)
+++ myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/AbstractCompareStrategy.java Thu Oct 22 19:46:27 2009
@@ -166,7 +166,7 @@
                     entryOfTarget.getComponent(), entryOfTarget.getMetaDataEntry(),
                     entryOfTarget.getConvertedObject(), validatorException, this))
             {
-                facesContext.addMessage(entryOfTarget.getClientId(),
+                ExtValUtils.tryToAddViolationMessageForComponentId(entryOfTarget.getClientId(),
                         ExtValUtils.convertFacesMessage(validatorException.getFacesMessage()));
             }
         }
@@ -184,7 +184,7 @@
         if (message.getSummary() != null || message.getDetail() != null)
         {
             //TODO
-            throw new ValidatorException(message);
+            ExtValUtils.tryToThrowValidatorExceptionForComponent(entryOfSource.getComponent(), message, null);
         }
         else
         {
@@ -206,12 +206,13 @@
             if (message.getSummary() != null || message.getDetail() != null)
             {
                 //TODO
-                throw new ValidatorException(message);
+                ExtValUtils.tryToThrowValidatorExceptionForComponent(entryOfSource.getComponent(), message, null);
             }
         }
 
         //just throw a new message - the error message is at the target
-        throw new ValidatorException(new FacesMessage());
+        ExtValUtils.tryToThrowValidatorExceptionForComponent(
+                entryOfSource.getComponent(), new FacesMessage(FacesMessage.SEVERITY_ERROR, null, null), null);
     }
 
     protected FacesMessage getSourceComponentErrorMessage(Annotation annotation, String summary, String detail)

Modified: myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/test/java/org/apache/myfaces/extensions/validator/test/core/interceptor/RegistrationPropertyValidationInterceptorTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/test/java/org/apache/myfaces/extensions/validator/test/core/interceptor/RegistrationPropertyValidationInterceptorTestCase.java?rev=828830&r1=828829&r2=828830&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/test/java/org/apache/myfaces/extensions/validator/test/core/interceptor/RegistrationPropertyValidationInterceptorTestCase.java (original)
+++ myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/test/java/org/apache/myfaces/extensions/validator/test/core/interceptor/RegistrationPropertyValidationInterceptorTestCase.java Thu Oct 22 19:46:27 2009
@@ -22,6 +22,7 @@
 import org.apache.myfaces.extensions.validator.core.ExtValContext;
 import org.apache.myfaces.extensions.validator.core.InvocationOrder;
 import org.apache.myfaces.extensions.validator.core.interceptor.PropertyValidationInterceptor;
+import org.apache.myfaces.extensions.validator.core.interceptor.FacesMessagePropertyValidationInterceptor;
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
@@ -57,7 +58,7 @@
 
         List<PropertyValidationInterceptor> result = ExtValContext.getContext().getPropertyValidationInterceptors();
 
-        int resultLength = 5;
+        int resultLength = 6;
         assertEquals(resultLength, result.size());
 
         for(int i = 0; i < resultLength; i++)
@@ -74,9 +75,12 @@
                     assertEquals(TestMetaDataExtractionInterceptor3.class, result.get(i).getClass());
                     break;
                 case 3:
-                    assertEquals(TestMetaDataExtractionInterceptor1000.class, result.get(i).getClass());
+                    assertEquals(FacesMessagePropertyValidationInterceptor.class, result.get(i).getClass());
                     break;
                 case 4:
+                    assertEquals(TestMetaDataExtractionInterceptor1000.class, result.get(i).getClass());
+                    break;
+                case 5:
                     assertEquals(TestComponentInitializer.class, result.get(i).getClass());
                     break;
             }

Modified: myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/test/java/org/apache/myfaces/extensions/validator/test/core/interceptor/RegistrationValidationExceptionInterceptorTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/test/java/org/apache/myfaces/extensions/validator/test/core/interceptor/RegistrationValidationExceptionInterceptorTestCase.java?rev=828830&r1=828829&r2=828830&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/test/java/org/apache/myfaces/extensions/validator/test/core/interceptor/RegistrationValidationExceptionInterceptorTestCase.java (original)
+++ myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/test/java/org/apache/myfaces/extensions/validator/test/core/interceptor/RegistrationValidationExceptionInterceptorTestCase.java Thu Oct 22 19:46:27 2009
@@ -25,6 +25,7 @@
 import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
 import org.apache.myfaces.extensions.validator.core.interceptor.ValidationExceptionInterceptor;
 import org.apache.myfaces.extensions.validator.core.interceptor.HtmlCoreComponentsValidationExceptionInterceptor;
+import org.apache.myfaces.extensions.validator.core.interceptor.ViolationSeverityValidationExceptionInterceptor;
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
@@ -59,7 +60,7 @@
 
         List<ValidationExceptionInterceptor> result = ExtValContext.getContext().getValidationExceptionInterceptors();
 
-        int resultLength = 6;
+        int resultLength = 7;
         assertEquals(resultLength, result.size());
 
         for(int i = 0; i < resultLength; i++)
@@ -76,12 +77,15 @@
                     assertEquals(TestValidationExceptionInterceptor3.class, result.get(i).getClass());
                     break;
                 case 3:
-                    assertEquals(HtmlCoreComponentsValidationExceptionInterceptor.class, result.get(i).getClass());
+                    assertEquals(ViolationSeverityValidationExceptionInterceptor.class, result.get(i).getClass());
                     break;
                 case 4:
-                    assertEquals(TestValidationExceptionInterceptor1000.class, result.get(i).getClass());
+                    assertEquals(HtmlCoreComponentsValidationExceptionInterceptor.class, result.get(i).getClass());
                     break;
                 case 5:
+                    assertEquals(TestValidationExceptionInterceptor1000.class, result.get(i).getClass());
+                    break;
+                case 6:
                     assertEquals(TestValidationExceptionInterceptor.class, result.get(i).getClass());
                     break;
             }