You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2009/11/18 19:28:56 UTC

svn commit: r881865 - in /myfaces/core/trunk: api/src/main/java/javax/faces/component/ impl/src/main/java/org/apache/myfaces/util/ impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/

Author: lu4242
Date: Wed Nov 18 18:28:55 2009
New Revision: 881865

URL: http://svn.apache.org/viewvc?rev=881865&view=rev
Log:
MYFACES-2362 Move default validator registration from UIInput.validateValue to ComponentTagHandlerDelegate (Thanks to Jakob Korherr for this patch)

Added:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/util/ExternalSpecifications.java
Modified:
    myfaces/core/trunk/api/src/main/java/javax/faces/component/UIInput.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UIInput.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UIInput.java?rev=881865&r1=881864&r2=881865&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UIInput.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UIInput.java Wed Nov 18 18:28:55 2009
@@ -349,72 +349,10 @@
             return;
         }
 
-        if (!empty)
+        if (!empty || shouldValidateEmptyFields(context))
         {
-            //TODO: Jan-Kees: This is not the most elegant solution, but for now it works
-            addDefaultValidators(context);
             _ComponentUtils.callValidators(context, this, convertedValue);
         }
-        else
-        {
-            if (shouldValidateEmptyFields(context))
-            {
-                //TODO: Jan-Kees: This is not the most elegant solution, but for now it works
-                addDefaultValidators(context);
-                _ComponentUtils.callValidators(context, this, convertedValue);
-            }
-        }
-    }
-
-    /**
-     * Add the default Validators to this component.
-     *
-     * @param context The FacesContext.
-     */
-    private void addDefaultValidators(FacesContext context)
-    {
-        Application application = context.getApplication();
-        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)
-            {
-                String validatorId = entry.getKey();
-                if (shouldAddDefaultValidator(validatorId, context))
-                {
-                    this.addValidator(application.createValidator(validatorId));
-                }
-            }
-        }
-    }
-
-    /**
-     * Determine if the default Validator with the given validatorId should be added to this component.
-     *
-     * @param validatorId The validatorId.
-     * @param context The FacesContext.
-     * @return true if the Validator should be added, false otherwise.
-     */
-    private boolean shouldAddDefaultValidator(String validatorId, FacesContext context)
-    {
-        // Some extra rules are required for Bean Validation.
-        if (validatorId.equals(BeanValidator.VALIDATOR_ID))
-        {
-            if (!_ExternalSpecifications.isBeanValidationAvailable)
-            {
-                return false;
-            }
-            ExternalContext externalContext = context.getExternalContext();
-            String disabled = externalContext.getInitParameter(BeanValidator.DISABLE_DEFAULT_BEAN_VALIDATOR_PARAM_NAME);
-            if (disabled != null && disabled.toLowerCase().equals("true"))
-            {
-                return false;
-            }
-        }
-
-        // By default, all default validators should be added
-        return true;
     }
 
     private boolean shouldValidateEmptyFields(FacesContext context)

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/util/ExternalSpecifications.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/util/ExternalSpecifications.java?rev=881865&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/util/ExternalSpecifications.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/util/ExternalSpecifications.java Wed Nov 18 18:28:55 2009
@@ -0,0 +1,103 @@
+/*
+ * 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.util;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.myfaces.shared_impl.util.ClassUtils;
+
+/**
+ * <p>
+ * Utility class for determining which specifications are available
+ * in the current process. See JIRA issue: http://issues.apache.org/jira/browse/MYFACES-2386
+ * </p>
+ *
+ * @author Jan-Kees van Andel
+ * @author Jakob Korherr
+ * @since 2.0
+ */
+public class ExternalSpecifications
+{
+
+    //private static final Log log = LogFactory.getLog(BeanValidator.class);
+    private static final Logger log = Logger.getLogger(ExternalSpecifications.class.getName());
+
+    /**
+     * This boolean indicates if Bean Validation is present.
+     *
+     * Eager initialization is used for performance. This means Bean Validation binaries
+     * should not be added at runtime after this variable has been set.
+     */
+    public static final boolean isBeanValidationAvailable;
+    static
+    {
+        boolean tmp = false;
+        try
+        {
+            tmp = (ClassUtils.classForName("javax.validation.Validation") != null);
+
+            // cannot perform this check, because validation-api.jar is not
+            // in the classpath of myfaces-impl
+            /*if (tmp)
+            {
+                try
+                {
+                    // Trial-error approach to check for Bean Validation impl existence.
+                    Validation.buildDefaultValidatorFactory().getValidator();
+                }
+                catch (Throwable t)
+                {
+                    log.log(Level.FINE, "Error initializing Bean Validation (could be normal)", t);
+                    tmp = false;
+                }
+            }*/
+        }
+        catch (Throwable t)
+        {
+            log.log(Level.FINE, "Error loading class (could be normal)", t);
+            tmp = false;
+        }
+        isBeanValidationAvailable = tmp;
+    }
+
+    /**
+     * This boolean indicates if Unified EL is present.
+     *
+     * Eager initialization is used for performance. This means Unified EL binaries
+     * should not be added at runtime after this variable has been set.
+     */
+    public static final boolean isUnifiedELAvailable;
+    static
+    {
+        boolean tmp = false;
+        try
+        {
+            //TODO: Check this class name when Unified EL for Java EE6 is final.
+            tmp = (ClassUtils.classForName("javax.el.ValueReference") != null);
+        }
+        catch (Throwable t)
+        {
+            log.log(Level.FINE, "Error loading class (could be normal)", t);
+            tmp = false;
+        }
+        isUnifiedELAvailable = tmp;
+    }
+
+}

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=881865&r1=881864&r2=881865&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 Nov 18 18:28:55 2009
@@ -20,6 +20,8 @@
 
 import java.io.IOException;
 import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -32,7 +34,10 @@
 import javax.faces.component.UniqueIdVendor;
 import javax.faces.component.ValueHolder;
 import javax.faces.component.behavior.ClientBehaviorHolder;
+import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
+import javax.faces.validator.BeanValidator;
+import javax.faces.validator.Validator;
 import javax.faces.view.facelets.ComponentConfig;
 import javax.faces.view.facelets.ComponentHandler;
 import javax.faces.view.facelets.FaceletContext;
@@ -41,10 +46,10 @@
 import javax.faces.view.facelets.TagException;
 import javax.faces.view.facelets.TagHandlerDelegate;
 
+import org.apache.myfaces.util.ExternalSpecifications;
 import org.apache.myfaces.view.facelets.AbstractFaceletContext;
 import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage;
 import org.apache.myfaces.view.facelets.tag.MetaRulesetImpl;
-import org.apache.myfaces.view.facelets.tag.composite.CompositeComponentResourceTagHandler;
 import org.apache.myfaces.view.facelets.tag.jsf.core.AjaxHandler;
 import org.apache.myfaces.view.facelets.tag.jsf.core.FacetHandler;
 
@@ -216,6 +221,14 @@
                 }
             }
         }
+        
+        if (c instanceof EditableValueHolder)
+        {
+            // add default validators here, because this feature 
+            // is only available in facelets (see MYFACES-2362 for details)
+            addDefaultValidators(facesContext, (EditableValueHolder) c);
+        }
+        
         _delegate.onComponentPopulated(ctx, c, parent);
 
         // add to the tree afterwards
@@ -229,7 +242,7 @@
         {
             parent.getFacets().put(facetName, c);
         }
-
+        
         if (c instanceof UniqueIdVendor)
         {
             actx.popUniqueIdVendorToStack();
@@ -357,5 +370,70 @@
         
         return m;
     }
+    
+    /**
+     * Add the default Validators to the component.
+     *
+     * @param context The FacesContext.
+     * @param component The EditableValueHolder to which the validators should be added
+     */
+    private void addDefaultValidators(FacesContext context, EditableValueHolder component)
+    {
+        Application application = context.getApplication();
+        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)
+            {
+                String validatorId = entry.getKey();
+                String validatorClassName = entry.getValue();
+                if (shouldAddDefaultValidator(validatorId, validatorClassName, context, component))
+                {
+                    component.addValidator(application.createValidator(validatorId));
+                }
+            }
+        }
+    }
+
+    /**
+     * 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 component The EditableValueHolder to which the validator should be added.
+     * @return true if the Validator should be added, false otherwise.
+     */
+    private boolean shouldAddDefaultValidator(String validatorId, String validatorClassName,
+                                              FacesContext context, EditableValueHolder component)
+    {
+        // check if the validator is already registered for the given component
+        for (Validator v : component.getValidators())
+        {
+            if (v.getClass().getName().equals(validatorClassName))
+            {
+                return false;
+            }
+        }
+        
+        // Some extra rules are required for Bean Validation.
+        if (validatorId.equals(BeanValidator.VALIDATOR_ID))
+        {
+            if (!ExternalSpecifications.isBeanValidationAvailable)
+            {
+                return false;
+            }
+            ExternalContext externalContext = context.getExternalContext();
+            String disabled = externalContext.getInitParameter(BeanValidator.DISABLE_DEFAULT_BEAN_VALIDATOR_PARAM_NAME);
+            if (disabled != null && disabled.toLowerCase().equals("true"))
+            {
+                return false;
+            }
+        }
+
+        // By default, all default validators should be added
+        return true;
+    }
 
 }