You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ja...@apache.org on 2010/01/27 14:31:38 UTC

svn commit: r903632 - in /myfaces/core/trunk/impl/src/main/java/org/apache/myfaces: config/ view/facelets/ view/facelets/impl/ view/facelets/tag/jsf/

Author: jakobk
Date: Wed Jan 27 13:31:38 2010
New Revision: 903632

URL: http://svn.apache.org/viewvc?rev=903632&view=rev
Log:
MYFACES-2511 Handle javax.faces.validator.DISABLE_DEFAULT_BEAN_VALIDATOR correctly

Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/AbstractFaceletContext.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ValidatorTagHandlerDelegate.java

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java?rev=903632&r1=903631&r2=903632&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java Wed Jan 27 13:31:38 2010
@@ -71,6 +71,7 @@
 import javax.faces.lifecycle.LifecycleFactory;
 import javax.faces.render.RenderKit;
 import javax.faces.render.RenderKitFactory;
+import javax.faces.validator.BeanValidator;
 import javax.faces.webapp.FacesServlet;
 
 import org.apache.myfaces.application.ApplicationFactoryImpl;
@@ -1707,8 +1708,15 @@
             application.addValidator(validatorId, dispenser.getValidatorClass(validatorId));
         }
 
+        String disabled = _externalContext.getInitParameter(BeanValidator.DISABLE_DEFAULT_BEAN_VALIDATOR_PARAM_NAME);
+        boolean defaultBeanValidatorDisabled = (disabled != null && disabled.toLowerCase().equals("true"));
         for (String validatorId : dispenser.getDefaultValidatorIds())
         {
+            if (defaultBeanValidatorDisabled && validatorId.equals(BeanValidator.VALIDATOR_ID))
+            {
+                // do not add it as a default validator
+                continue;
+            }
             application.addDefaultValidatorId(validatorId);
         }
 

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/AbstractFaceletContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/AbstractFaceletContext.java?rev=903632&r1=903631&r2=903632&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/AbstractFaceletContext.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/AbstractFaceletContext.java Wed Jan 27 13:31:38 2010
@@ -208,4 +208,24 @@
      */
     public abstract void pushExcludedValidatorIdToStack(String validatorId);
     
+    /**
+     * Gets all validationIds on the stack.
+     * @return
+     * @since 2.0
+     */
+    public abstract Iterator<String> getEnclosingValidatorIds();
+    
+    /**
+     * Removes top of stack.
+     * @since 2.0
+     */
+    public abstract void popEnclosingValidatorIdToStack();
+    
+    /**
+     * Pushes validatorId to the stack of all enclosing validatorIds.
+     * @param validatorId
+     * @since 2.0
+     */
+    public abstract void pushEnclosingValidatorIdToStack(String validatorId);
+    
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java?rev=903632&r1=903631&r2=903632&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java Wed Jan 27 13:31:38 2010
@@ -70,6 +70,8 @@
     public final static String VALIDATION_GROUPS_STACK = "org.apache.myfaces.view.facelets.VALIDATION_GROUPS_STACK";
     
     public final static String EXCLUDED_VALIDATOR_IDS_STACK = "org.apache.myfaces.view.facelets.EXCLUDED_VALIDATOR_IDS_STACK";
+    
+    public final static String ENCLOSING_VALIDATOR_IDS_STACK = "org.apache.myfaces.view.facelets.ENCLOSING_VALIDATOR_IDS_STACK";
 
     private final FacesContext _faces;
 
@@ -736,4 +738,64 @@
 
         excludedValidatorIdsStack.addFirst(validatorId);
     }
+    
+    /**
+     * Gets all validationIds on the stack.
+     * @return
+     * @since 2.0
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    public Iterator<String> getEnclosingValidatorIds()
+    {
+        Map<Object, Object> attributes = getFacesContext().getAttributes();
+        
+        LinkedList<String> enclosingValidatorIdsStack 
+                = (LinkedList<String>) attributes.get(ENCLOSING_VALIDATOR_IDS_STACK);
+        if (enclosingValidatorIdsStack != null && !enclosingValidatorIdsStack.isEmpty())
+        {
+            return enclosingValidatorIdsStack.iterator(); 
+        }
+        return null;
+    }
+    
+    /**
+     * Removes top of stack.
+     * @since 2.0
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    public void popEnclosingValidatorIdToStack()
+    {
+        Map<Object, Object> contextAttributes = getFacesContext().getAttributes();
+        
+        LinkedList<String> enclosingValidatorIdsStack 
+                = (LinkedList<String>) contextAttributes.get(ENCLOSING_VALIDATOR_IDS_STACK);
+        if (enclosingValidatorIdsStack != null && !enclosingValidatorIdsStack.isEmpty())
+        {
+            enclosingValidatorIdsStack.removeFirst();
+        }
+    }
+    
+    /**
+     * Pushes validatorId to the stack of all enclosing validatorIds.
+     * @param validatorId
+     * @since 2.0
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    public void pushEnclosingValidatorIdToStack(String validatorId)
+    {
+        Map<Object, Object> attributes = getFacesContext().getAttributes();
+
+        LinkedList<String> enclosingValidatorIdsStack 
+                = (LinkedList<String>) attributes.get(ENCLOSING_VALIDATOR_IDS_STACK);
+        if (enclosingValidatorIdsStack == null)
+        {
+            enclosingValidatorIdsStack = new LinkedList<String>();
+            attributes.put(ENCLOSING_VALIDATOR_IDS_STACK, enclosingValidatorIdsStack);
+        }
+
+        enclosingValidatorIdsStack.addFirst(validatorId);
+    }
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java?rev=903632&r1=903631&r2=903632&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java Wed Jan 27 13:31:38 2010
@@ -19,6 +19,7 @@
 package org.apache.myfaces.view.facelets.tag.jsf;
 
 import java.io.IOException;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -32,7 +33,6 @@
 import javax.faces.component.ActionSource;
 import javax.faces.component.EditableValueHolder;
 import javax.faces.component.UIComponent;
-import javax.faces.component.UIPanel;
 import javax.faces.component.UniqueIdVendor;
 import javax.faces.component.ValueHolder;
 import javax.faces.component.behavior.ClientBehaviorHolder;
@@ -55,6 +55,8 @@
 import org.apache.myfaces.view.facelets.tag.jsf.core.AjaxHandler;
 import org.apache.myfaces.view.facelets.tag.jsf.core.FacetHandler;
 
+import com.sun.beans.ObjectHandler;
+
 /**
  *  
  * Implementation of the tag logic used in the JSF specification. 
@@ -379,6 +381,8 @@
     
     /**
      * Add the default Validators to the component.
+     * Also adds all validators specified by enclosing <f:validateBean> tags
+     * (e.g. the BeanValidator if it is not a default validator).
      *
      * @param context The FacesContext.
      * @param actx the AbstractFaceletContext
@@ -388,67 +392,108 @@
                                       EditableValueHolder component)
     {
         Application application = context.getApplication();
+        Map<String, String> validators = new HashMap<String, String>();
+        
+        // add all defaultValidators
         Map<String, String> defaultValidators = application.getDefaultValidatorInfo();
         if (defaultValidators != null && defaultValidators.size() != 0)
         {
-            Set<Map.Entry<String, String>> defaultValidatorInfoSet = defaultValidators.entrySet();
-            for (Map.Entry<String, String> entry : defaultValidatorInfoSet)
+            validators.putAll(defaultValidators);
+        }
+        // add all enclosing validators
+        Iterator<String> enclosingValidatorIds = actx.getEnclosingValidatorIds();
+        if (enclosingValidatorIds != null && enclosingValidatorIds.hasNext())
+        {
+            while (enclosingValidatorIds.hasNext())
+            {
+                String validatorId = enclosingValidatorIds.next();
+                if (!validators.containsKey(validatorId))
+                {
+                    validators.put(validatorId, null);
+                }
+            }
+        }
+        
+        if (!validators.isEmpty())
+        {
+            // we have validators to add
+            Set<Map.Entry<String, String>> validatorInfoSet = validators.entrySet();
+            for (Map.Entry<String, String> entry : validatorInfoSet)
             {
                 String validatorId = entry.getKey();
                 String validatorClassName = entry.getValue();
+                Validator enclosingValidator = null;
+                
+                if (validatorClassName == null)
+                {
+                    // we have no class name for validators of enclosing <f:validateBean> tags
+                    // --> we have to create it to get the class name
+                    // note that normally we can use this instance later anyway!
+                    enclosingValidator = application.createValidator(validatorId);
+                    validatorClassName = enclosingValidator.getClass().getName();
+                }
+                
+                // check if the validator is already registered for the given component
+                // this happens if <f:validateBean /> is nested inside the component on the view
+                Validator validator = null;
+                for (Validator v : component.getValidators())
+                {
+                    if (v.getClass().getName().equals(validatorClassName))
+                    {
+                        // found
+                        validator = v;
+                        break;
+                    }
+                }
                 
-                if (shouldAddDefaultValidator(validatorId, validatorClassName, context, actx, component))
+                if (validator == null)
                 {
-                    Validator validator = null;
-                    boolean created = false;
-                    // check if the validator is already registered for the given component
-                    for (Validator v : component.getValidators())
+                    if (shouldAddDefaultValidator(validatorId, context, actx, component))
                     {
-                        if (v.getClass().getName().equals(validatorClassName))
+                        if (enclosingValidator != null)
+                        {
+                            // we can use the instance from before
+                            validator = enclosingValidator;
+                        }
+                        else
                         {
-                            // found
-                            validator = v;
-                            break;
+                            // create it
+                            validator = application.createValidator(validatorId);
                         }
+                        // add the validator to the component
+                        component.addValidator(validator);
                     }
-                    if (validator == null)
+                    else
                     {
-                        // create it
-                        validator = application.createValidator(validatorId);
-                        created = true;
+                        // no validator instance
+                        continue;
                     }
+                }
+                
+                // special things to configure for a BeanValidator
+                if (validator instanceof BeanValidator)
+                {
+                    BeanValidator beanValidator = (BeanValidator) validator;
                     
-                    // special things to do for a BeanValidator
-                    if (validator instanceof BeanValidator)
+                    // check the validationGroups
+                    String validationGroups =  beanValidator.getValidationGroups();
+                    if (validationGroups == null 
+                            || validationGroups.matches(BeanValidator.EMPTY_VALIDATION_GROUPS_PATTERN))
                     {
-                        BeanValidator beanValidator = (BeanValidator) validator;
-                        
-                        // check the validationGroups
-                        String validationGroups =  beanValidator.getValidationGroups();
-                        if (validationGroups == null 
-                                || validationGroups.matches(BeanValidator.EMPTY_VALIDATION_GROUPS_PATTERN))
+                        // no validationGroups available
+                        // --> get the validationGroups from the stack
+                        String stackGroup = actx.getFirstValidationGroupFromStack();
+                        if (stackGroup != null)
                         {
-                            // no validationGroups available
-                            // --> get the validationGroups from the stack
-                            String stackGroup = actx.getFirstValidationGroupFromStack();
-                            if (stackGroup != null)
-                            {
-                                validationGroups = stackGroup;
-                            }
-                            else
-                            {
-                                // no validationGroups on the stack
-                                // --> set the default validationGroup
-                                validationGroups = javax.validation.groups.Default.class.getName();
-                            }
-                            beanValidator.setValidationGroups(validationGroups);
+                            validationGroups = stackGroup;
                         }
-                    }
-                    
-                    if (created)
-                    {
-                        // add the validator to the component
-                        component.addValidator(validator);
+                        else
+                        {
+                            // no validationGroups on the stack
+                            // --> set the default validationGroup
+                            validationGroups = javax.validation.groups.Default.class.getName();
+                        }
+                        beanValidator.setValidationGroups(validationGroups);
                     }
                 }
             }
@@ -459,15 +504,14 @@
      * Determine if the default Validator with the given validatorId should be added.
      *
      * @param validatorId The validatorId.
-     * @param validatorClassName The class name of the validator.
      * @param context The FacesContext.
      * @param actx the AbstractFaceletContext
      * @param component The EditableValueHolder to which the validator should be added.
      * @return true if the Validator should be added, false otherwise.
      */
     @SuppressWarnings("unchecked")
-    private boolean shouldAddDefaultValidator(String validatorId, String validatorClassName,
-                                              FacesContext context, AbstractFaceletContext actx,
+    private boolean shouldAddDefaultValidator(String validatorId, FacesContext context, 
+                                              AbstractFaceletContext actx,
                                               EditableValueHolder component)
     {
         // check if the validatorId is on the exclusion list on the component
@@ -510,6 +554,21 @@
             String disabled = externalContext.getInitParameter(BeanValidator.DISABLE_DEFAULT_BEAN_VALIDATOR_PARAM_NAME);
             if (disabled != null && disabled.toLowerCase().equals("true"))
             {
+                // check if there are any enclosing <f:validateBean> tags with the validatorId of the BeanValidator
+                Iterator<String> itEnclosingIds = actx.getEnclosingValidatorIds();
+                if (itEnclosingIds != null)
+                {
+                    while (itEnclosingIds.hasNext())
+                    {
+                        if (validatorId.equals(itEnclosingIds.next()))
+                        {
+                            // the component is enclosed by <f:validateBean>
+                            return true;
+                        }
+                    }
+                }
+                
+                // no enclosing <f:validateBean> found --> do not attach BeanValidator
                 return false;
             }
         }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ValidatorTagHandlerDelegate.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ValidatorTagHandlerDelegate.java?rev=903632&r1=903631&r2=903632&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ValidatorTagHandlerDelegate.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ValidatorTagHandlerDelegate.java Wed Jan 27 13:31:38 2010
@@ -112,11 +112,12 @@
             // we need methods from AbstractFaceletContext
             AbstractFaceletContext abstractCtx = (AbstractFaceletContext) ctx;
              
+            String validatorId = _delegate.getValidatorConfig().getValidatorId();
+            
             boolean disabled = _delegate.isDisabled(ctx);
             if (disabled)
             {
                 // the validator is disabled --> add its id to the exclusion stack
-                String validatorId = _delegate.getValidatorConfig().getValidatorId();
                 boolean validatorIdAvailable = validatorId != null && !"".equals(validatorId);
                 if (validatorIdAvailable)
                 {
@@ -130,7 +131,8 @@
             }
             else
             {
-                // the validator is enabled --> add the validation groups to the stack
+                // the validator is enabled 
+                // --> add the validation groups and the validatorId to the stack
                 String groups = getValidationGroups(ctx);
                 // spec: don't save the validation groups string if it is null or empty string
                 boolean groupsAvailable = groups != null 
@@ -139,7 +141,9 @@
                 {
                     abstractCtx.pushValidationGroupsToStack(groups);
                 }
+                abstractCtx.pushEnclosingValidatorIdToStack(validatorId);
                 _delegate.getValidatorConfig().getNextHandler().apply(ctx, parent);
+                abstractCtx.popEnclosingValidatorIdToStack();
                 if (groupsAvailable)
                 {
                     abstractCtx.popValidationGroupsToStack();