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();