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/08/28 02:50:12 UTC
svn commit: r808697 - in
/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets: ./
tag/composite/ tag/jsf/
Author: lu4242
Date: Fri Aug 28 00:50:12 2009
New Revision: 808697
URL: http://svn.apache.org/viewvc?rev=808697&view=rev
Log:
MYFACES-2324 Add ViewDeclarationLanguage.retargetAttachedObjects and ViewDeclarationLanguage.retargetMethodExpressions
Added:
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetHandler.java (with props)
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetImpl.java (with props)
Modified:
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentResourceTagHandler.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ConverterTagHandlerDelegate.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/view/facelets/FaceletViewDeclarationLanguage.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java?rev=808697&r1=808696&r2=808697&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java Fri Aug 28 00:50:12 2009
@@ -91,6 +91,7 @@
import org.apache.myfaces.view.facelets.impl.DefaultResourceResolver;
import org.apache.myfaces.view.facelets.impl.ResourceResolver;
import org.apache.myfaces.view.facelets.tag.TagDecorator;
+import org.apache.myfaces.view.facelets.tag.composite.CompositeComponentResourceTagHandler;
import org.apache.myfaces.view.facelets.tag.composite.CompositeLibrary;
import org.apache.myfaces.view.facelets.tag.composite.CompositeResourceLibrary;
import org.apache.myfaces.view.facelets.tag.ui.UIDebug;
@@ -395,7 +396,7 @@
// its tag handler is applied.
if (UIComponent.isCompositeComponent(component))
{
- // TODO: How we obtain the list of AttachedObjectHandler for
+ // How we obtain the list of AttachedObjectHandler for
// the current composite component? It should be a component
// attribute or retrieved by a key inside component.getAttributes
// map. Since api does not specify any attribute, we suppose
@@ -403,6 +404,16 @@
// from component attribute map.
// But this is only the point of the iceberg, because we should
// define how we register attached object handlers in this list.
+ // ANS: see CompositeComponentResourceTagHandler.
+ // The current handler should be added to the list, to be chained.
+ // Note that the inner component should have a target with the same name
+ // as "for" attribute
+ CompositeComponentResourceTagHandler.addAttachedObjectHandler(component, currentHandler);
+
+ List<AttachedObjectHandler> handlers = (List<AttachedObjectHandler>)
+ component.getAttributes().get(CompositeComponentResourceTagHandler.ATTACHED_OBJECT_HANDLERS_KEY);
+
+ retargetAttachedObjects(context, component, handlers);
}
else
{
@@ -426,14 +437,12 @@
// its tag handler is applied.
if (UIComponent.isCompositeComponent(component))
{
- // TODO: How we obtain the list of AttachedObjectHandler for
- // the current composite component? It should be a component
- // attribute or retrieved by a key inside component.getAttributes
- // map. Since api does not specify any attribute, we suppose
- // this is an implementation detail and it should be retrieved
- // from component attribute map.
- // But this is only the point of the iceberg, because we should
- // define how we register attached object handlers in this list.
+ CompositeComponentResourceTagHandler.addAttachedObjectHandler(component, currentHandler);
+
+ List<AttachedObjectHandler> handlers = (List<AttachedObjectHandler>)
+ component.getAttributes().get(CompositeComponentResourceTagHandler.ATTACHED_OBJECT_HANDLERS_KEY);
+
+ retargetAttachedObjects(context, component, handlers);
}
else
{
Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetHandler.java?rev=808697&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetHandler.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetHandler.java Fri Aug 28 00:50:12 2009
@@ -0,0 +1,169 @@
+/*
+ * 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.view.facelets.tag.composite;
+
+import java.beans.BeanDescriptor;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.faces.component.UIComponent;
+import javax.faces.view.AttachedObjectTarget;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.FaceletHandler;
+import javax.faces.view.facelets.TagAttribute;
+import javax.faces.view.facelets.TagConfig;
+import javax.faces.view.facelets.TagHandler;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletAttribute;
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
+
+/**
+ * composite:actionSource, composite:valueHolder and composite:editableValueHolder
+ * do the same: register an AttachedObjectTarget on the "targetList" mentioned on
+ * ViewDeclarationLanguage.retargetAttachedObjects. AttachedObjectTargetHandler group the
+ * common behavior
+ *
+ * @author Leonardo Uribe (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+@JSFFaceletTag
+public abstract class AttachedObjectTargetHandler<T extends AttachedObjectTarget>
+ extends TagHandler implements InterfaceDescriptorCreator
+{
+
+ private static final Log log = LogFactory.getLog(AttachedObjectTargetHandler.class);
+
+ /**
+ *
+ */
+ @JSFFaceletAttribute(name="name",
+ className="javax.el.ValueExpression",
+ deferredValueType="java.lang.String")
+ protected final TagAttribute _name;
+
+ /**
+ *
+ */
+ @JSFFaceletAttribute(name="targets",
+ className="javax.el.ValueExpression",
+ deferredValueType="java.lang.String")
+ protected final TagAttribute _targets;
+
+ /**
+ * Check if the PropertyDescriptor instance created by this handler
+ * can be cacheable or not.
+ */
+ private boolean _cacheable;
+
+ private AttachedObjectTarget _target;
+
+ public AttachedObjectTargetHandler(TagConfig config)
+ {
+ super(config);
+ _name = getRequiredAttribute("name");
+ _targets = getAttribute("targets");
+ if (_name.isLiteral())
+ {
+ _cacheable = true;
+ }
+ else
+ {
+ _cacheable = false;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void apply(FaceletContext ctx, UIComponent parent)
+ throws IOException
+ {
+ CompositeComponentBeanInfo beanInfo =
+ (CompositeComponentBeanInfo) parent.getAttributes()
+ .get(UIComponent.BEANINFO_KEY);
+
+ if (beanInfo == null)
+ {
+ if (log.isErrorEnabled())
+ {
+ log.error("Cannot found composite bean descriptor UIComponent.BEANINFO_KEY ");
+ }
+ return;
+ }
+
+ BeanDescriptor beanDescriptor = beanInfo.getBeanDescriptor();
+
+ //1. Obtain the list mentioned as "targetList" on ViewDeclarationLanguage.retargetAttachedObjects
+ List<AttachedObjectTarget> targetList = (List<AttachedObjectTarget>)
+ beanDescriptor.getValue(
+ AttachedObjectTarget.ATTACHED_OBJECT_TARGETS_KEY);
+
+ if (targetList == null)
+ {
+ //2. If not found create it and set
+ targetList = new ArrayList<AttachedObjectTarget>();
+ beanDescriptor.setValue(
+ AttachedObjectTarget.ATTACHED_OBJECT_TARGETS_KEY,
+ targetList);
+ }
+
+ //3. Create the instance of AttachedObjectTarget
+ if (isCacheable())
+ {
+ if (_target == null)
+ {
+ _target = createAttachedObjectTarget(ctx);
+ }
+ targetList.add(_target);
+ }
+ else
+ {
+ AttachedObjectTarget target = createAttachedObjectTarget(ctx);
+ targetList.add(target);
+ }
+
+ this.nextHandler.apply(ctx, parent);
+ }
+
+ public boolean isCacheable()
+ {
+ return _cacheable;
+ }
+
+ public void setCacheable(boolean cacheable)
+ {
+ _cacheable = cacheable;
+ }
+
+ @Override
+ public FaceletHandler getNextHandler()
+ {
+ return nextHandler;
+ }
+
+ /**
+ * Create a new AttachedObjectTarget instance to be added on the
+ * target list.
+ *
+ * @return
+ */
+ protected abstract T createAttachedObjectTarget(FaceletContext ctx);
+}
Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetHandler.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetImpl.java?rev=808697&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetImpl.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetImpl.java Fri Aug 28 00:50:12 2009
@@ -0,0 +1,122 @@
+/*
+ * 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.view.facelets.tag.composite;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.el.ValueExpression;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.view.AttachedObjectTarget;
+
+import org.apache.myfaces.shared_impl.util.StringUtils;
+
+/**
+ *
+ * @author Leonardo Uribe (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+public class AttachedObjectTargetImpl implements AttachedObjectTarget, Serializable
+{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7214478234269252354L;
+
+ protected ValueExpression _name;
+
+ protected ValueExpression _targets;
+
+ public AttachedObjectTargetImpl()
+ {
+ }
+
+ @Override
+ public String getName()
+ {
+ if (_name != null)
+ {
+ return (String) _name.getValue(FacesContext.getCurrentInstance().getELContext());
+ }
+ return null;
+ }
+
+ @Override
+ public List<UIComponent> getTargets(UIComponent topLevelComponent)
+ {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ String [] targetsArray = getTargets(facesContext);
+
+ if (targetsArray.length > 0)
+ {
+ List<UIComponent> targetsList = new ArrayList<UIComponent>(targetsArray.length);
+ for (String target : targetsArray)
+ {
+ UIComponent innerComponent = topLevelComponent.findComponent(target);
+
+ if (innerComponent != null)
+ {
+ targetsList.add(innerComponent);
+ }
+ }
+ return targetsList;
+ }
+ else
+ {
+ // composite:actionSource/valueHolder/editableValueHolder
+ // "name" description says if targets is not set, name is
+ // the component id of the target component where
+ // it should be mapped to
+ String name = getName();
+ if (name != null)
+ {
+ UIComponent innerComponent = topLevelComponent.findComponent(getName());
+ if (innerComponent != null)
+ {
+ List<UIComponent> targetsList = new ArrayList<UIComponent>(1);
+ targetsList.add(innerComponent);
+ return targetsList;
+ }
+ }
+ return Collections.emptyList();
+ }
+ }
+
+ public String [] getTargets(FacesContext context)
+ {
+ if (_targets != null)
+ {
+ return StringUtils.splitShortString((String) _targets.getValue(context.getELContext()), ' ');
+ }
+ return org.apache.myfaces.shared_impl.util.ArrayUtils.EMPTY_STRING_ARRAY;
+ }
+
+ public void setName(ValueExpression ve)
+ {
+ _name = ve;
+ }
+
+ public void setTargets(ValueExpression ve)
+ {
+ _targets = ve;
+ }
+}
Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttachedObjectTargetImpl.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentResourceTagHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentResourceTagHandler.java?rev=808697&r1=808696&r2=808697&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentResourceTagHandler.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentResourceTagHandler.java Fri Aug 28 00:50:12 2009
@@ -21,6 +21,8 @@
import java.beans.BeanInfo;
import java.beans.PropertyDescriptor;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import javax.el.ValueExpression;
import javax.el.VariableMapper;
@@ -32,6 +34,7 @@
import javax.faces.component.UIPanel;
import javax.faces.component.ValueHolder;
import javax.faces.context.FacesContext;
+import javax.faces.view.AttachedObjectHandler;
import javax.faces.view.ViewDeclarationLanguage;
import javax.faces.view.facelets.ComponentConfig;
import javax.faces.view.facelets.ComponentHandler;
@@ -59,6 +62,17 @@
public class CompositeComponentResourceTagHandler extends ComponentHandler
implements ComponentBuilderHandler
{
+ /**
+ * This key is used to keep the list of AttachedObjectHandlers
+ * created when a composite component is created. Tag handlers
+ * exposing attached objects should call
+ * addAttachedObjectHandler(UIComponent, AttachedObjectHandler)
+ * that uses this key to save this list on component attribute
+ * map.
+ */
+ public final static String ATTACHED_OBJECT_HANDLERS_KEY =
+ "org.apache.myfaces.ATTACHED_OBJECT_HANDLERS_KEY";
+
private final Resource _resource;
private Metadata _mapper;
@@ -120,6 +134,7 @@
return component;
}
+ @SuppressWarnings("unchecked")
@Override
public void applyNextHandler(FaceletContext ctx, UIComponent c)
throws IOException
@@ -133,9 +148,18 @@
ViewDeclarationLanguage vdl = facesContext.getApplication().getViewHandler().
getViewDeclarationLanguage(facesContext, facesContext.getViewRoot().getViewId());
- // TODO: This method should be called from here, but we have to retrieve
- // its handlers from somewhere.
- //vdl.retargetAttachedObjects(facesContext, c, handlers)
+ List<AttachedObjectHandler> handlers = (List<AttachedObjectHandler>)
+ c.getAttributes().get(ATTACHED_OBJECT_HANDLERS_KEY);
+
+ if (handlers != null)
+ {
+ vdl.retargetAttachedObjects(facesContext, c, handlers);
+
+ // Since handlers list is not serializable and it is not necessary to
+ // keep them anymore on attribute map, it is better to remove it from
+ // component attribute map
+ c.getAttributes().remove(ATTACHED_OBJECT_HANDLERS_KEY);
+ }
vdl.retargetMethodExpressions(facesContext, c);
@@ -169,6 +193,32 @@
faceletContext.setVariableMapper(orig);
}
}
+
+ /**
+ * Add to the composite component parent this handler, so it will be processed later when
+ * ViewDeclarationLanguage.retargetAttachedObjects is called (see applyNextHandler method).
+ *
+ * Tag Handlers exposing attached objects should call this method to expose them when the
+ * parent to be applied is a composite components.
+ *
+ * @param compositeComponentParent
+ * @param handler
+ */
+ @SuppressWarnings("unchecked")
+ public static void addAttachedObjectHandler(UIComponent compositeComponentParent, AttachedObjectHandler handler)
+ {
+ List<AttachedObjectHandler> list = (List<AttachedObjectHandler>)
+ compositeComponentParent.getAttributes().get(
+ ATTACHED_OBJECT_HANDLERS_KEY);
+
+ if (list == null)
+ {
+ list = new ArrayList<AttachedObjectHandler>();
+ compositeComponentParent.getAttributes().put(ATTACHED_OBJECT_HANDLERS_KEY, list);
+ }
+
+ list.add(handler);
+ }
@Override
public void setAttributes(FaceletContext ctx, Object instance)
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ConverterTagHandlerDelegate.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ConverterTagHandlerDelegate.java?rev=808697&r1=808696&r2=808697&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ConverterTagHandlerDelegate.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ConverterTagHandlerDelegate.java Fri Aug 28 00:50:12 2009
@@ -25,7 +25,8 @@
import javax.faces.component.ValueHolder;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
-import javax.faces.view.AttachedObjectHandler;
+import javax.faces.view.ValueHolderAttachedObjectHandler;
+import javax.faces.view.facelets.ComponentHandler;
import javax.faces.view.facelets.ConverterHandler;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.MetaRuleset;
@@ -34,6 +35,9 @@
import javax.faces.view.facelets.TagHandlerDelegate;
import org.apache.myfaces.view.facelets.tag.MetaRulesetImpl;
+import org.apache.myfaces.view.facelets.tag.composite.CompositeComponentResourceTagHandler;
+
+import com.sun.beans.ObjectHandler;
/**
* Handles setting a Converter instance on a ValueHolder. Will wire all attributes set to the Converter instance
@@ -46,7 +50,7 @@
*
* @since 2.0
*/
-public class ConverterTagHandlerDelegate extends TagHandlerDelegate implements AttachedObjectHandler
+public class ConverterTagHandlerDelegate extends TagHandlerDelegate implements ValueHolderAttachedObjectHandler
{
private ConverterHandler _delegate;
@@ -74,16 +78,23 @@
@Override
public void apply(FaceletContext ctx, UIComponent parent) throws IOException
{
- if (parent == null || !(parent instanceof ValueHolder))
+ // only process if it's been created
+ if (!ComponentHandler.isNew(parent))
{
- throw new TagException(_delegate.getTag(), "Parent not an instance of ValueHolder: " + parent);
+ return;
}
-
- // only process if it's been created
- if (parent.getParent() == null)
+ if (parent instanceof ValueHolder)
{
applyAttachedObject(ctx.getFacesContext(), parent);
- }
+ }
+ else if (UIComponent.isCompositeComponent(parent))
+ {
+ CompositeComponentResourceTagHandler.addAttachedObjectHandler(parent, _delegate);
+ }
+ else
+ {
+ throw new TagException(_delegate.getTag(), "Parent not composite component or an instance of ValueHolder: " + parent);
+ }
}
/**
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=808697&r1=808696&r2=808697&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 Fri Aug 28 00:50:12 2009
@@ -25,7 +25,8 @@
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
-import javax.faces.view.AttachedObjectHandler;
+import javax.faces.view.EditableValueHolderAttachedObjectHandler;
+import javax.faces.view.facelets.ComponentHandler;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.MetaRuleset;
import javax.faces.view.facelets.TagAttribute;
@@ -34,6 +35,7 @@
import javax.faces.view.facelets.ValidatorHandler;
import org.apache.myfaces.view.facelets.tag.MetaRulesetImpl;
+import org.apache.myfaces.view.facelets.tag.composite.CompositeComponentResourceTagHandler;
/**
* Handles setting a Validator instance on a EditableValueHolder. Will wire all attributes set to the Validator instance
@@ -46,7 +48,7 @@
*
* @since 2.0
*/
-public class ValidatorTagHandlerDelegate extends TagHandlerDelegate implements AttachedObjectHandler
+public class ValidatorTagHandlerDelegate extends TagHandlerDelegate implements EditableValueHolderAttachedObjectHandler
{
private ValidatorHandler _delegate;
@@ -58,17 +60,22 @@
@Override
public void apply(FaceletContext ctx, UIComponent parent) throws IOException
{
-
- if (parent == null || !(parent instanceof EditableValueHolder))
+ if (!ComponentHandler.isNew(parent))
{
- throw new TagException(_delegate.getTag(), "Parent not an instance of EditableValueHolder: " + parent);
+ return;
}
-
- // only process if it's been created
- if (parent.getParent() == null)
+ if (parent instanceof EditableValueHolder)
{
applyAttachedObject(ctx.getFacesContext(), parent);
}
+ else if (UIComponent.isCompositeComponent(parent))
+ {
+ CompositeComponentResourceTagHandler.addAttachedObjectHandler(parent, _delegate);
+ }
+ else
+ {
+ throw new TagException(_delegate.getTag(), "Parent not composite component or an instance of EditableValueHolder: " + parent);
+ }
}
/**