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/11/03 19:30:35 UTC

svn commit: r832500 [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/util/ExtValBeanValidationMetaDataInternals.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/ExtValBeanValidationMetaDataInternals.java?rev=832500&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/ExtValBeanValidationMetaDataInternals.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/ExtValBeanValidationMetaDataInternals.java Tue Nov  3 18:30:34 2009
@@ -0,0 +1,665 @@
+/*
+ * 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.commons.logging.Log;
+import org.apache.myfaces.extensions.validator.beanval.ExtValBeanValidationContext;
+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.el.ELHelper;
+import org.apache.myfaces.extensions.validator.core.el.ValueBindingExpression;
+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
+import org.apache.myfaces.extensions.validator.core.validation.message.FacesMessageHolder;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+import org.apache.myfaces.extensions.validator.util.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;
+
+/**
+ * @author Gerhard Petracek
+ * @since x.x.3
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+class ExtValBeanValidationMetaDataInternals
+{
+    private Log logger;
+    private LabeledMessageInternals labeledMessageInternals = new LabeledMessageInternals();
+
+    ExtValBeanValidationMetaDataInternals(Log logger)
+    {
+        this.logger = logger;
+    }
+
+    void extractExtValBeanValidationMetaData(PropertyDetails propertyDetails,
+                                             boolean processModelValidation,
+                                             String[] key,
+                                             Object firstBean,
+                                             List<Class> foundGroupsForPropertyValidation,
+                                             List<Class> restrictedGroupsForPropertyValidation,
+                                             List<ModelValidationEntry> modelValidationEntryList,
+                                             List<Class> restrictedGroupsForModelValidation)
+    {
+        inspectFirstBean(processModelValidation,
+                firstBean,
+                foundGroupsForPropertyValidation,
+                restrictedGroupsForPropertyValidation,
+                modelValidationEntryList,
+                restrictedGroupsForModelValidation);
+
+        inspectFirstProperty(processModelValidation,
+                key,
+                firstBean,
+                foundGroupsForPropertyValidation,
+                restrictedGroupsForPropertyValidation,
+                modelValidationEntryList,
+                restrictedGroupsForModelValidation);
+
+        inspectBaseOfProperty(propertyDetails,
+                processModelValidation,
+                foundGroupsForPropertyValidation,
+                restrictedGroupsForPropertyValidation,
+                modelValidationEntryList,
+                restrictedGroupsForModelValidation);
+
+        inspectLastProperty(propertyDetails,
+                processModelValidation,
+                foundGroupsForPropertyValidation,
+                restrictedGroupsForPropertyValidation,
+                modelValidationEntryList,
+                restrictedGroupsForModelValidation);
+    }
+
+    void processExtValBeanValidationMetaData(UIComponent component,
+                                             PropertyDetails propertyDetails,
+                                             List<Class> foundGroupsForPropertyValidation,
+                                             List<Class> restrictedGroupsForPropertyValidation,
+                                             List<ModelValidationEntry> modelValidationEntryList,
+                                             List<Class> restrictedGroupsForModelValidation)
+    {
+        ExtValBeanValidationContext extValBeanValidationContext = ExtValBeanValidationContext.getCurrentInstance();
+        String currentViewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();
+
+        String clientId = component.getClientId(FacesContext.getCurrentInstance());
+
+        processFoundGroups(extValBeanValidationContext, currentViewId, clientId,
+                foundGroupsForPropertyValidation);
+
+        processRestrictedGroups(extValBeanValidationContext, currentViewId, clientId,
+                restrictedGroupsForPropertyValidation);
+
+        initModelValidation(extValBeanValidationContext, component, propertyDetails,
+                modelValidationEntryList, restrictedGroupsForModelValidation);
+    }
+
+    private void inspectFirstBean(boolean processModelValidation,
+                                  Object firstBean,
+                                  List<Class> foundGroupsForPropertyValidation,
+                                  List<Class> restrictedGroupsForPropertyValidation,
+                                  List<ModelValidationEntry> modelValidationEntryList,
+                                  List<Class> restrictedGroupsForModelValidation)
+    {
+        processClass(firstBean,
+                foundGroupsForPropertyValidation,
+                restrictedGroupsForPropertyValidation,
+                modelValidationEntryList,
+                restrictedGroupsForModelValidation,
+                processModelValidation);
+    }
+
+    private void inspectFirstProperty(boolean processModelValidation,
+                                      String[] key,
+                                      Object firstBean,
+                                      List<Class> foundGroupsForPropertyValidation,
+                                      List<Class> restrictedGroupsForPropertyValidation,
+                                      List<ModelValidationEntry> modelValidationEntryList,
+                                      List<Class> restrictedGroupsForModelValidation)
+    {
+        processFieldsAndProperties(key[0] + "." + key[1],
+                firstBean,
+                key[1],
+                foundGroupsForPropertyValidation,
+                restrictedGroupsForPropertyValidation,
+                modelValidationEntryList,
+                restrictedGroupsForModelValidation,
+                processModelValidation);
+    }
+
+    private void inspectBaseOfProperty(PropertyDetails propertyDetails,
+                                       boolean processModelValidation,
+                                       List<Class> foundGroupsForPropertyValidation,
+                                       List<Class> restrictedGroupsForPropertyValidation,
+                                       List<ModelValidationEntry> modelValidationEntryList,
+                                       List<Class> restrictedGroupsForModelValidation)
+    {
+        processClass(propertyDetails.getBaseObject(),
+                foundGroupsForPropertyValidation,
+                restrictedGroupsForPropertyValidation,
+                modelValidationEntryList,
+                restrictedGroupsForModelValidation,
+                processModelValidation);
+    }
+
+    private void inspectLastProperty(PropertyDetails propertyDetails,
+                                     boolean processModelValidation,
+                                     List<Class> foundGroupsForPropertyValidation,
+                                     List<Class> restrictedGroupsForPropertyValidation,
+                                     List<ModelValidationEntry> modelValidationEntryList,
+                                     List<Class> restrictedGroupsForModelValidation)
+    {
+        processFieldsAndProperties(
+                propertyDetails.getKey(),
+                propertyDetails.getBaseObject(),
+                propertyDetails.getProperty(),
+                foundGroupsForPropertyValidation,
+                restrictedGroupsForPropertyValidation,
+                modelValidationEntryList,
+                restrictedGroupsForModelValidation,
+                processModelValidation);
+    }
+
+    private void processClass(Object objectToInspect,
+                              List<Class> foundGroupsForPropertyValidation,
+                              List<Class> restrictedGroupsForPropertyValidation,
+                              List<ModelValidationEntry> modelValidationEntryList,
+                              List<Class> restrictedGroupsForModelValidation,
+                              boolean processModelValidation)
+    {
+        Class classToInspect = objectToInspect.getClass();
+        while (!Object.class.getName().equals(classToInspect.getName()))
+        {
+            transferGroupValidationInformationToFoundGroups(objectToInspect,
+                    foundGroupsForPropertyValidation,
+                    restrictedGroupsForPropertyValidation,
+                    modelValidationEntryList,
+                    restrictedGroupsForModelValidation,
+                    processModelValidation);
+
+            processInterfaces(objectToInspect.getClass(), objectToInspect,
+                    foundGroupsForPropertyValidation,
+                    restrictedGroupsForPropertyValidation,
+                    modelValidationEntryList,
+                    restrictedGroupsForModelValidation,
+                    processModelValidation);
+
+            classToInspect = classToInspect.getSuperclass();
+        }
+    }
+
+    private void processFieldsAndProperties(String key,
+                                            Object base,
+                                            String property,
+                                            List<Class> foundGroupsForPropertyValidation,
+                                            List<Class> restrictedGroupsForPropertyValidation,
+                                            List<ModelValidationEntry> modelValidationEntryList,
+                                            List<Class> restrictedGroupsForModelValidation,
+                                            boolean processModelValidation)
+    {
+        PropertyInformation propertyInformation = new DefaultGroupControllerScanningExtractor()
+                .extract(FacesContext.getCurrentInstance(), new PropertyDetails(key, base, property));
+
+        for (MetaDataEntry metaDataEntry : propertyInformation.getMetaDataEntries())
+        {
+            if (metaDataEntry.getValue() instanceof BeanValidation)
+            {
+                tryToProcessMetaData((BeanValidation) metaDataEntry.getValue(),
+                        tryToCreateNewTarget(base, property),
+                        foundGroupsForPropertyValidation,
+                        restrictedGroupsForPropertyValidation,
+                        modelValidationEntryList,
+                        restrictedGroupsForModelValidation,
+                        processModelValidation);
+            }
+            else if (metaDataEntry.getValue() instanceof BeanValidation.List)
+            {
+                for (BeanValidation currentBeanValidation : ((BeanValidation.List) metaDataEntry.getValue()).value())
+                {
+                    tryToProcessMetaData(currentBeanValidation,
+                            tryToCreateNewTarget(base, property),
+                            foundGroupsForPropertyValidation,
+                            restrictedGroupsForPropertyValidation,
+                            modelValidationEntryList,
+                            restrictedGroupsForModelValidation,
+                            processModelValidation);
+                }
+            }
+        }
+    }
+
+    private Object tryToCreateNewTarget(Object base, String property)
+    {
+        Object result = getValueOfProperty(base, property);
+
+        if (result == null)
+        {
+            return base;
+        }
+
+        return result;
+    }
+
+    private Object getValueOfProperty(Object base, String property)
+    {
+        property = property.substring(0, 1).toUpperCase() + property.substring(1, property.length());
+        Method targetMethod = ReflectionUtils.tryToGetMethod(base.getClass(), "get" + property);
+
+        if (targetMethod == null)
+        {
+            targetMethod = ReflectionUtils.tryToGetMethod(base.getClass(), "is" + property);
+        }
+
+        if (targetMethod == null)
+        {
+            throw new IllegalStateException(
+                    "class " + base.getClass() + " has no public get/is " + property.toLowerCase());
+        }
+        return ReflectionUtils.tryToInvokeMethod(base, targetMethod);
+    }
+
+    private void processFoundGroups(ExtValBeanValidationContext extValBeanValidationContext,
+                                    String currentViewId,
+                                    String clientId,
+                                    List<Class> foundGroupsForPropertyValidation)
+    {
+        /*
+         * add found groups to context
+         */
+        for (Class currentGroupClass : foundGroupsForPropertyValidation)
+        {
+            extValBeanValidationContext.addGroup(currentGroupClass, currentViewId, clientId);
+        }
+    }
+
+    private void processRestrictedGroups(ExtValBeanValidationContext extValBeanValidationContext,
+                                         String currentViewId,
+                                         String clientId,
+                                         List<Class> restrictedGroupsForPropertyValidation)
+    {
+        /*
+         * add restricted groups
+         */
+        for (Class currentGroupClass : restrictedGroupsForPropertyValidation)
+        {
+            extValBeanValidationContext.restrictGroup(currentGroupClass, currentViewId, clientId);
+        }
+    }
+
+    private void initModelValidation(ExtValBeanValidationContext extValBeanValidationContext,
+                                     UIComponent component,
+                                     PropertyDetails propertyDetails,
+                                     List<ModelValidationEntry> modelValidationEntryList,
+                                     List<Class> restrictedGroupsForModelValidation)
+    {
+        /*
+         * add model validation entry list
+         */
+        for (ModelValidationEntry modelValidationEntry : modelValidationEntryList)
+        {
+            for (Class restrictedGroup : restrictedGroupsForModelValidation)
+            {
+                modelValidationEntry.removeGroup(restrictedGroup);
+            }
+
+            if (modelValidationEntry.getGroups().length > 0)
+            {
+                if (modelValidationEntry.getValidationTargets().isEmpty())
+                {
+                    modelValidationEntry.addValidationTarget(propertyDetails.getBaseObject());
+                }
+                modelValidationEntry.setComponent(component);
+                extValBeanValidationContext.addModelValidationEntry(modelValidationEntry);
+            }
+        }
+    }
+
+    private void transferGroupValidationInformationToFoundGroups(
+            Object objectToInspect,
+            List<Class> foundGroupsForPropertyValidation,
+            List<Class> restrictedGroupsForPropertyValidation,
+            List<ModelValidationEntry> modelValidationEntryList,
+            List<Class> restrictedGroupsForModelValidation,
+            boolean processModelValidation)
+    {
+        if (objectToInspect.getClass().isAnnotationPresent(BeanValidation.class))
+        {
+            tryToProcessMetaData(objectToInspect.getClass().getAnnotation(BeanValidation.class),
+                    objectToInspect,
+                    foundGroupsForPropertyValidation,
+                    restrictedGroupsForPropertyValidation,
+                    modelValidationEntryList,
+                    restrictedGroupsForModelValidation,
+                    processModelValidation);
+        }
+        else if (objectToInspect.getClass().isAnnotationPresent(BeanValidation.List.class))
+        {
+            for (BeanValidation currentBeanValidation :
+                    (objectToInspect.getClass().getAnnotation(BeanValidation.List.class)).value())
+            {
+                tryToProcessMetaData(currentBeanValidation,
+                        objectToInspect,
+                        foundGroupsForPropertyValidation,
+                        restrictedGroupsForPropertyValidation,
+                        modelValidationEntryList,
+                        restrictedGroupsForModelValidation,
+                        processModelValidation);
+            }
+        }
+    }
+
+    private void processInterfaces(Class currentClass,
+                                   Object metaDataSourceObject,
+                                   List<Class> foundGroupsForPropertyValidation,
+                                   List<Class> restrictedGroupsForPropertyValidation,
+                                   List<ModelValidationEntry> modelValidationEntryList,
+                                   List<Class> restrictedGroupsForModelValidation,
+                                   boolean processModelValidation)
+    {
+        for (Class currentInterface : currentClass.getInterfaces())
+        {
+            transferGroupValidationInformationToFoundGroups(metaDataSourceObject,
+                    foundGroupsForPropertyValidation,
+                    restrictedGroupsForPropertyValidation,
+                    modelValidationEntryList,
+                    restrictedGroupsForModelValidation,
+                    processModelValidation);
+
+            processInterfaces(currentInterface, metaDataSourceObject,
+                    foundGroupsForPropertyValidation,
+                    restrictedGroupsForPropertyValidation,
+                    modelValidationEntryList,
+                    restrictedGroupsForModelValidation,
+                    processModelValidation);
+        }
+    }
+
+    private void tryToProcessMetaData(BeanValidation beanValidation,
+                                      Object metaDataSourceObject,
+                                      List<Class> foundGroupsForPropertyValidation,
+                                      List<Class> restrictedGroupsForPropertyValidation,
+                                      List<ModelValidationEntry> modelValidationEntryList,
+                                      List<Class> restrictedGroupsForModelValidation,
+                                      boolean processModelValidation)
+    {
+        for (String currentViewId : beanValidation.viewIds())
+        {
+            if (useMetaDataForViewId(beanValidation, currentViewId))
+            {
+                processMetaData(beanValidation,
+                        metaDataSourceObject,
+                        foundGroupsForPropertyValidation,
+                        restrictedGroupsForPropertyValidation,
+                        modelValidationEntryList,
+                        restrictedGroupsForModelValidation,
+                        processModelValidation);
+                break;
+            }
+        }
+    }
+
+    private boolean useMetaDataForViewId(BeanValidation beanValidation, String currentViewId)
+    {
+        return (currentViewId.equals(FacesContext.getCurrentInstance().getViewRoot().getViewId()) ||
+                currentViewId.equals("*")) && isValidationPermitted(beanValidation);
+    }
+
+    private void processMetaData(BeanValidation beanValidation,
+                                 Object metaDataSourceObject,
+                                 List<Class> foundGroupsForPropertyValidation,
+                                 List<Class> restrictedGroupsForPropertyValidation,
+                                 List<ModelValidationEntry> modelValidationEntryList,
+                                 List<Class> restrictedGroupsForModelValidation,
+                                 boolean processModelValidation)
+    {
+        if (processModelValidation && isModelValidation(beanValidation))
+        {
+            addModelValidationEntry(
+                    beanValidation, metaDataSourceObject,
+                    modelValidationEntryList, restrictedGroupsForModelValidation);
+        }
+        else if (!isModelValidation(beanValidation))
+        {
+            processGroups(
+                    beanValidation, foundGroupsForPropertyValidation, restrictedGroupsForPropertyValidation);
+        }
+    }
+
+    private boolean isValidationPermitted(BeanValidation beanValidation)
+    {
+        ELHelper elHelper = ExtValUtils.getELHelper();
+
+        for (String condition : beanValidation.conditions())
+        {
+            if (elHelper.isELTermWellFormed(condition) &&
+                    elHelper.isELTermValid(FacesContext.getCurrentInstance(), condition))
+            {
+                if (Boolean.TRUE.equals(elHelper.getValueOfExpression(
+                        FacesContext.getCurrentInstance(), new ValueBindingExpression(condition))))
+                {
+                    return true;
+                }
+            }
+            else
+            {
+                if (this.logger.isErrorEnabled())
+                {
+                    this.logger.error("an invalid condition is used: " + condition);
+                }
+            }
+        }
+        return false;
+    }
+
+    private boolean isModelValidation(BeanValidation beanValidation)
+    {
+        return beanValidation.modelValidation().isActive();
+    }
+
+    private void addModelValidationEntry(BeanValidation beanValidation,
+                                         Object metaDataSourceObject,
+                                         List<ModelValidationEntry> modelValidationEntryList,
+                                         List<Class> restrictedGroupsForModelValidation)
+    {
+        ModelValidationEntry modelValidationEntry = new ModelValidationEntry();
+
+        modelValidationEntry.setGroups(Arrays.asList(beanValidation.useGroups()));
+        modelValidationEntry.setDisplayMessageInline(beanValidation.modelValidation().displayInline());
+        modelValidationEntry.setCustomMessage(beanValidation.modelValidation().message());
+        modelValidationEntry.setMetaDataSourceObject(metaDataSourceObject);
+
+        Object validationTarget;
+        for (String validationTargetExpression : beanValidation.modelValidation().validationTargets())
+        {
+            if (ModelValidation.DEFAULT_TARGET.equals(validationTargetExpression))
+            {
+                continue;
+            }
+
+            validationTarget = tryToResolveValidationTargetExpression(validationTargetExpression);
+            if (validationTarget != null)
+            {
+                modelValidationEntry.addValidationTarget(validationTarget);
+            }
+        }
+
+        if (beanValidation.restrictGroups().length > 0)
+        {
+            restrictedGroupsForModelValidation.addAll(Arrays.asList(beanValidation.restrictGroups()));
+        }
+
+        if (modelValidationEntry.getValidationTargets().isEmpty())
+        {
+            modelValidationEntry.addValidationTarget(metaDataSourceObject);
+        }
+
+        modelValidationEntryList.add(modelValidationEntry);
+    }
+
+    private Object tryToResolveValidationTargetExpression(String validationTargetExpression)
+    {
+        ValueBindingExpression valueBindingExpression = new ValueBindingExpression(validationTargetExpression);
+        return ExtValUtils.getELHelper()
+                .getValueOfExpression(FacesContext.getCurrentInstance(), valueBindingExpression);
+    }
+
+    private void processGroups(BeanValidation beanValidation,
+                               List<Class> foundGroupsForPropertyValidation,
+                               List<Class> restrictedGroupsForPropertyValidation)
+    {
+        foundGroupsForPropertyValidation.addAll(Arrays.asList(beanValidation.useGroups()));
+
+        if (beanValidation.restrictGroups().length > 0)
+        {
+            restrictedGroupsForPropertyValidation.addAll(Arrays.asList(beanValidation.restrictGroups()));
+        }
+    }
+
+    String createLabeledMessage(String violationMessage)
+    {
+        return labeledMessageInternals.createLabeledMessage(violationMessage);
+    }
+
+    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;
+    }
+
+    void processFacesMessage(FacesContext facesContext, UIComponent uiComponent,
+                             List<FacesMessageHolder> facesMessageHolderList, FacesMessage facesMessage)
+    {
+        FacesMessageHolder facesMessageHolder = new FacesMessageHolder(facesMessage);
+
+        facesMessageHolder.setClientId(uiComponent.getClientId(facesContext));
+
+        facesMessageHolderList.add(facesMessageHolder);
+    }
+
+    boolean executeAfterThrowingInterceptors(UIComponent uiComponent,
+                                             Object convertedObject,
+                                             ValidatorException validatorException)
+    {
+        return ExtValUtils.executeAfterThrowingInterceptors(
+                uiComponent,
+                null,
+                convertedObject,
+                validatorException,
+                null);
+    }
+
+    boolean isMessageTextUnchanged(ValidatorException validatorException, String violationMessage)
+    {
+        return violationMessage.equals(validatorException.getFacesMessage().getSummary()) ||
+                violationMessage.equals(validatorException.getFacesMessage().getDetail());
+    }
+
+    ValidatorException createValidatorException(String violationMessage, FacesMessage.Severity severity)
+    {
+        return new ValidatorException(
+                ExtValUtils.createFacesMessage(severity, violationMessage, violationMessage));
+    }
+
+    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;
+    }
+
+    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;
+    }
+
+    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());
+            }
+        }
+    }
+
+    void addMessagesWithLowSeverity(List<FacesMessageHolder> facesMessageHolderListWithLowSeverity)
+    {
+        for (FacesMessageHolder facesMessageHolder : facesMessageHolderListWithLowSeverity)
+        {
+            ExtValUtils.tryToAddViolationMessageForComponentId(
+                    facesMessageHolder.getClientId(), facesMessageHolder.getFacesMessage());
+        }
+    }
+}

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=832500&r1=832499&r2=832500&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 Tue Nov  3 18:30:34 2009
@@ -20,16 +20,16 @@
 
 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.BeanValidationModuleKey;
+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.beanval.util.BeanValidationUtils;
-import org.apache.myfaces.extensions.validator.core.validation.message.FacesMessageHolder;
-import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
 import org.apache.myfaces.extensions.validator.core.property.DefaultPropertyInformation;
-import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;
 import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;
+import org.apache.myfaces.extensions.validator.core.validation.message.FacesMessageHolder;
 import org.apache.myfaces.extensions.validator.util.ExtValUtils;
 
 import javax.faces.component.UIComponent;
@@ -65,7 +65,7 @@
             logger.trace("jsr303 start model validation");
         }
 
-        List<Object> processedValidationTargets = new ArrayList<Object>();
+        Map<Object, List<Class>> processedValidationTargets = new HashMap<Object, List<Class>>();
 
         Map<String, ModelValidationResult> results = new HashMap<String, ModelValidationResult>();
 
@@ -74,7 +74,7 @@
             processModelValidation(modelValidationEntry, processedValidationTargets, results);
         }
 
-        processViolations(results);
+        processModelValidationResults(results);
 
         executeGlobalAfterValidationInterceptorsFor(results);
 
@@ -90,34 +90,121 @@
     }
 
     private void processModelValidation(ModelValidationEntry modelValidationEntry,
-                                        List<Object> processedValidationTargets,
+                                        Map<Object, List<Class>> processedValidationTargets,
                                         Map<String, ModelValidationResult> results)
     {
         FacesContext facesContext = FacesContext.getCurrentInstance();
         PropertyInformation propertyInformation;
+        Set<ConstraintViolation<Object>> violations;
+        Class[] groupsToValidate;
 
         for (Object validationTarget : modelValidationEntry.getValidationTargets())
         {
             propertyInformation = createPropertyInformation(modelValidationEntry, validationTarget);
 
-            if(!executeGlobalBeforeValidationInterceptors(
+            if (!executeGlobalBeforeValidationInterceptors(
                     facesContext, modelValidationEntry.getComponent(), validationTarget, propertyInformation))
             {
                 return;
             }
 
-            if (processedValidationTargets.contains(validationTarget) &&
-                    !modelValidationEntry.isDisplayMessageInline())
+            groupsToValidate = filterGroupsToValidate(
+                    modelValidationEntry, validationTarget, processedValidationTargets);
+
+            //TODO
+            if (!addProcessedTarget(
+                    modelValidationEntry, processedValidationTargets, validationTarget, groupsToValidate))
             {
                 continue;
             }
 
-            if (!processedValidationTargets.contains(validationTarget))
+            violations = validateTarget(validationTarget, groupsToValidate);
+
+            if (violations != null && !violations.isEmpty())
             {
-                processedValidationTargets.add(validationTarget);
+                processViolations(facesContext, modelValidationEntry, validationTarget, violations, results);
+            }
+        }
+    }
+
+    private Class[] filterGroupsToValidate(ModelValidationEntry modelValidationEntry,
+                                           Object validationTarget,
+                                           Map<Object, List<Class>> processedValidationTargets)
+    {
+        if(!processedValidationTargets.containsKey(validationTarget))
+        {
+            return modelValidationEntry.getGroups();
+        }
+
+        List<Class> result = new ArrayList<Class>();
+        List<Class> validatedGroups = processedValidationTargets.get(validationTarget);
+
+        for(Class group : modelValidationEntry.getGroups())
+        {
+            if(!validatedGroups.contains(group))
+            {
+                result.add(group);
+            }
+        }
+        return result.toArray(new Class[result.size()]);
+    }
+
+    private boolean addProcessedTarget(ModelValidationEntry modelValidationEntry,
+                                             Map<Object, List<Class>> processedValidationTargets,
+                                             Object validationTarget,
+                                             Class[] groups)
+    {
+        if (isTargetAlreadyProcessedForGroups(
+                processedValidationTargets, validationTarget, groups) &&
+                !modelValidationEntry.isDisplayMessageInline())
+        {
+            return false;
+        }
+
+        if (!isTargetAlreadyProcessedForGroups(
+                processedValidationTargets, validationTarget, groups))
+        {
+            addTarget(processedValidationTargets, validationTarget, groups);
+        }
+        return true;
+    }
+
+    private boolean isTargetAlreadyProcessedForGroups(
+            Map<Object, List<Class>> processedValidationTargets, Object validationTarget, Class[] groups)
+    {
+        List<Class> groupList;
+        if(processedValidationTargets.containsKey(validationTarget))
+        {
+            groupList = processedValidationTargets.get(processedValidationTargets);
+
+            for(Class group : groups)
+            {
+                if(!groupList.contains(group))
+                {
+                    return false;
+                }
             }
+            return true;
+        }
+        return false;
+    }
+
+    private void addTarget(
+            Map<Object, List<Class>> processedValidationTargets, Object validationTarget, Class[] groups)
+    {
+        if(!processedValidationTargets.containsKey(validationTarget))
+        {
+            processedValidationTargets.put(validationTarget, new ArrayList<Class>());
+        }
+
+        List<Class> validatedGroups = processedValidationTargets.get(validationTarget);
 
-            validateTarget(modelValidationEntry, validationTarget, modelValidationEntry.getGroups(), results);
+        for(Class group : groups)
+        {
+            if(!validatedGroups.contains(group))
+            {
+                validatedGroups.add(group);
+            }
         }
     }
 
@@ -127,7 +214,7 @@
         PropertyInformation propertyInformation;
         PropertyDetails propertyDetails;
         propertyInformation = new DefaultPropertyInformation();
-        if(modelValidationEntry.getComponent() != null)
+        if (modelValidationEntry.getComponent() != null)
         {
             propertyDetails = ExtValUtils.getELHelper()
                     .getPropertyDetailsOfValueBinding(modelValidationEntry.getComponent());
@@ -157,56 +244,85 @@
         ExtValUtils.executeGlobalAfterValidationInterceptors(facesContext, uiComponent, validationTarget,
                 PropertyInformation.class.getName(), propertyInformation, BeanValidationModuleKey.class);
     }
-    
-    private void validateTarget(ModelValidationEntry modelValidationEntry,
-                                Object validationTarget,
-                                Class[] groups,
-                                Map<String, ModelValidationResult> results)
+
+    private Set<ConstraintViolation<Object>> validateTarget(Object validationTarget, Class[] groups)
     {
-        Set<ConstraintViolation<Object>> violations = ExtValBeanValidationContext.getCurrentInstance()
+        return ExtValBeanValidationContext.getCurrentInstance()
                 .getValidatorFactory().usingContext()
                 .messageInterpolator(ExtValBeanValidationContext.getCurrentInstance().getMessageInterpolator())
                 .getValidator()
                 .validate(validationTarget, groups);
+    }
 
-        if (violations != null && !violations.isEmpty())
+    private void processViolations(FacesContext facesContext,
+                                   ModelValidationEntry modelValidationEntry,
+                                   Object validationTarget,
+                                   Set<ConstraintViolation<Object>> violations,
+                                   Map<String, ModelValidationResult> results)
+    {
+        //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<ConstraintViolation<Object>> violationsIterator = violations.iterator();
+        ConstraintViolation<Object> constraintViolation;
+        ModelValidationResult result;
+        while (violationsIterator.hasNext())
         {
-            FacesContext facesContext = FacesContext.getCurrentInstance();
+            tryToCreateModelValidationResult(facesContext, modelValidationEntry, results);
 
-            //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 = resolveModelValidationResult(facesContext, modelValidationEntry, results);
 
-                result = results.get(modelValidationEntry.getComponent().getClientId(facesContext));
+            constraintViolation = violationsIterator.next();
+            addViolationMessage(modelValidationEntry, validationTarget, constraintViolation, result);
+        }
+    }
 
-                constraintViolation = (ConstraintViolation) violationsIterator.next();
-                if (modelValidationEntry.isDisplayMessageInline())
-                {
-                    result.addFacesMessageHolder(createFacesMessageHolderForConstraintViolation(
-                            constraintViolation, modelValidationEntry, validationTarget, true));
-                }
-                else
-                {
-                    result.addFacesMessageHolder(createFacesMessageHolderForConstraintViolation(
-                            constraintViolation, modelValidationEntry, validationTarget, false));
-                }
-            }
+    private void tryToCreateModelValidationResult(FacesContext facesContext,
+                                                  ModelValidationEntry modelValidationEntry,
+                                                  Map<String, ModelValidationResult> results)
+    {
+        ModelValidationResult result;
+        if (!isModelValidationResultAvailableFor(facesContext, modelValidationEntry, results))
+        {
+            result = new ModelValidationResult();
+            results.put(modelValidationEntry.getComponent().getClientId(facesContext), result);
+        }
+    }
+
+    private ModelValidationResult resolveModelValidationResult(FacesContext facesContext,
+                                                               ModelValidationEntry modelValidationEntry,
+                                                               Map<String, ModelValidationResult> results)
+    {
+        return results.get(modelValidationEntry.getComponent().getClientId(facesContext));
+    }
+
+    private boolean isModelValidationResultAvailableFor(FacesContext facesContext,
+                                                        ModelValidationEntry modelValidationEntry,
+                                                        Map<String, ModelValidationResult> results)
+    {
+        return results.containsKey(modelValidationEntry.getComponent().getClientId(facesContext));
+    }
+
+    private void addViolationMessage(ModelValidationEntry modelValidationEntry,
+                                     Object validationTarget,
+                                     ConstraintViolation<Object> constraintViolation,
+                                     ModelValidationResult result)
+    {
+        if (modelValidationEntry.isDisplayMessageInline())
+        {
+            result.addFacesMessageHolder(createFacesMessageHolderForConstraintViolation(
+                    constraintViolation, modelValidationEntry, validationTarget, true));
+        }
+        else
+        {
+            result.addFacesMessageHolder(createFacesMessageHolderForConstraintViolation(
+                    constraintViolation, modelValidationEntry, validationTarget, false));
         }
     }
 
     private FacesMessageHolder createFacesMessageHolderForConstraintViolation(final ConstraintViolation violation,
-                                                                        ModelValidationEntry modelValidationEntry,
-                                                                        final Object validationTarget,
-                                                                        boolean displayAtComponent)
+                                                                              ModelValidationEntry modelValidationEntry,
+                                                                              final Object validationTarget,
+                                                                              boolean displayAtComponent)
     {
         final String newViolationMessage = tryToChangeViolationMessage(
                 modelValidationEntry, validationTarget, violation);
@@ -310,7 +426,7 @@
                 );
     }
 
-    private void processViolations(Map<String, ModelValidationResult> results)
+    private void processModelValidationResults(Map<String, ModelValidationResult> results)
     {
         for (ModelValidationResult result : results.values())
         {
@@ -324,10 +440,10 @@
         UIComponent component;
         for (ModelValidationResult result : results.values())
         {
-            for(FacesMessageHolder facesMessageHolder : result.getFacesMessageHolderList())
+            for (FacesMessageHolder facesMessageHolder : result.getFacesMessageHolderList())
             {
                 component = null;
-                if(facesMessageHolder.getClientId() != null && !facesMessageHolder.getClientId().equals("*"))
+                if (facesMessageHolder.getClientId() != null && !facesMessageHolder.getClientId().equals("*"))
                 {
                     component = facesContext.getViewRoot().findComponent(facesMessageHolder.getClientId());
                 }

Modified: myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationSkipValidationEvaluator.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/PropertyValidationSkipValidationEvaluator.java?rev=832500&r1=832499&r2=832500&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationSkipValidationEvaluator.java (original)
+++ myfaces/extensions/validator/branches/branch_for_jsf_1_1/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationSkipValidationEvaluator.java Tue Nov  3 18:30:34 2009
@@ -24,13 +24,11 @@
 import org.apache.myfaces.extensions.validator.core.validation.SkipValidationEvaluator;
 import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
 import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;
-import org.apache.myfaces.extensions.validator.core.storage.FacesInformationStorage;
 import org.apache.myfaces.extensions.validator.util.PropertyValidationUtils;
-import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+import org.apache.myfaces.extensions.validator.util.JsfUtils;
 
 import javax.faces.context.FacesContext;
 import javax.faces.component.UIComponent;
-import javax.faces.event.PhaseId;
 import java.util.List;
 
 /**
@@ -47,23 +45,13 @@
     {
         boolean result = false;
         
-        if(isRenderResponsePhase())
+        if(JsfUtils.isRenderResponsePhase())
         {
             result = !isClientSideValidationEnabled(metaDataEntry);
         }
         return result || PropertyValidationUtils.isValidationSkipped(facesContext, validationStrategy, metaDataEntry);
     }
 
-    private boolean isRenderResponsePhase()
-    {
-        return PhaseId.RENDER_RESPONSE.equals(getFacesInformationStorage().getCurrentPhaseId());
-    }
-
-    private FacesInformationStorage getFacesInformationStorage()
-    {
-        return ExtValUtils.getStorage(FacesInformationStorage.class, FacesInformationStorage.class.getName());
-    }
-
     @SuppressWarnings({"unchecked"})
     private boolean isClientSideValidationEnabled(MetaDataEntry entry)
     {
@@ -72,4 +60,4 @@
 
         return keysToDisable == null || !keysToDisable.contains(entry.getKey());
     }
-}
\ No newline at end of file
+}