You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sl...@apache.org on 2009/02/05 00:55:29 UTC

svn commit: r740940 [6/9] - in /myfaces/core/branches/2_0_0: api/src/main/java/javax/faces/webapp/pdl/facelets/ api/src/main/resources/META-INF/ impl/src/main/java/com/ impl/src/main/java/com/sun/ impl/src/main/java/com/sun/facelets/ impl/src/main/java...

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagDecorator.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagDecorator.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagDecorator.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagDecorator.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,35 @@
+/**
+ * Licensed 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 com.sun.facelets.tag;
+
+/**
+ * Provides the ability to completely change the Tag before it's processed for compiling with the associated TagHandler.
+ * <p /> You could take &lt;input type="text" /> and convert it to &lth:inputText /> before compiling.
+ * 
+ * @author Jacob Hookom
+ * @version $Id: TagDecorator.java,v 1.3 2008/07/13 19:01:35 rlubke Exp $
+ */
+public interface TagDecorator
+{
+
+    /**
+     * If handled, return a new Tag instance, otherwise return null
+     * 
+     * @param tag
+     *            tag to be decorated
+     * @return a decorated tag, otherwise null
+     */
+    public Tag decorate(Tag tag);
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagException.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagException.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagException.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagException.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,66 @@
+/**
+ * Licensed 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 com.sun.facelets.tag;
+
+import javax.faces.webapp.pdl.facelets.FaceletException;
+
+/**
+ * An Exception caused by a Tag
+ * 
+ * @author Jacob Hookom
+ * @version $Id: TagException.java,v 1.4 2008/07/13 19:01:35 rlubke Exp $
+ */
+public final class TagException extends FaceletException
+{
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    public TagException(Tag tag)
+    {
+        super(tag.toString());
+    }
+
+    /**
+     * @param message
+     */
+    public TagException(Tag tag, String message)
+    {
+        super(tag + " " + message);
+    }
+
+    /**
+     * @param cause
+     */
+    public TagException(Tag tag, Throwable cause)
+    {
+        super(tag.toString(), cause);
+    }
+
+    /**
+     * @param message
+     * @param cause
+     */
+    public TagException(Tag tag, String message, Throwable cause)
+    {
+        super(tag + " " + message, cause);
+    }
+
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagHandler.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagHandler.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagHandler.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,109 @@
+/**
+ * Licensed 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 com.sun.facelets.tag;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.faces.webapp.pdl.facelets.FaceletHandler;
+
+/**
+ * Foundation class for FaceletHandlers associated with markup in a Facelet document.
+ * 
+ * @author Jacob Hookom
+ * @version $Id: TagHandler.java,v 1.6 2008/07/13 19:01:35 rlubke Exp $
+ */
+public abstract class TagHandler implements FaceletHandler
+{
+
+    protected final String tagId;
+
+    protected final Tag tag;
+
+    protected final FaceletHandler nextHandler;
+
+    public TagHandler(TagConfig config)
+    {
+        this.tagId = config.getTagId();
+        this.tag = config.getTag();
+        this.nextHandler = config.getNextHandler();
+    }
+
+    /**
+     * Utility method for fetching the appropriate TagAttribute
+     * 
+     * @param localName
+     *            name of attribute
+     * @return TagAttribute if found, otherwise null
+     */
+    protected final TagAttribute getAttribute(String localName)
+    {
+        return this.tag.getAttributes().get(localName);
+    }
+
+    /**
+     * Utility method for fetching a required TagAttribute
+     * 
+     * @param localName
+     *            name of the attribute
+     * @return TagAttribute if found, otherwise error
+     * @throws TagException
+     *             if the attribute was not found
+     */
+    protected final TagAttribute getRequiredAttribute(String localName) throws TagException
+    {
+        TagAttribute attr = this.getAttribute(localName);
+        if (attr == null)
+        {
+            throw new TagException(this.tag, "Attribute '" + localName + "' is required");
+        }
+        return attr;
+    }
+
+    /**
+     * Searches child handlers, starting at the 'nextHandler' for all instances of the passed type. This process will
+     * stop searching a branch if an instance is found.
+     * 
+     * @param type
+     *            Class type to search for
+     * @return iterator over instances of FaceletHandlers of the matching type
+     */
+    protected final Iterator findNextByType(Class type)
+    {
+        List found = new ArrayList();
+        if (type.isAssignableFrom(this.nextHandler.getClass()))
+        {
+            found.add(this.nextHandler);
+        }
+        else if (this.nextHandler instanceof CompositeFaceletHandler)
+        {
+            FaceletHandler[] h = ((CompositeFaceletHandler) this.nextHandler).getHandlers();
+            for (int i = 0; i < h.length; i++)
+            {
+                if (type.isAssignableFrom(h[i].getClass()))
+                {
+                    found.add(h[i]);
+                }
+            }
+        }
+        return found.iterator();
+    }
+
+    public String toString()
+    {
+        return this.tag.toString();
+    }
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagHandlerFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagHandlerFactory.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagHandlerFactory.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagHandlerFactory.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,39 @@
+/**
+ * Licensed 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 com.sun.facelets.tag;
+
+import javax.el.ELException;
+import javax.faces.FacesException;
+
+/**
+ * Delegate class for TagLibraries
+ * 
+ * @see TagLibrary
+ * @author Jacob Hookom
+ * @version $Id: TagHandlerFactory.java,v 1.4 2008/07/13 19:01:35 rlubke Exp $
+ */
+interface TagHandlerFactory
+{
+    /**
+     * A new TagHandler instantiated with the passed TagConfig
+     * 
+     * @param cfg
+     *            TagConfiguration information
+     * @return a new TagHandler
+     * @throws FacesException
+     * @throws ELException
+     */
+    public TagHandler createHandler(TagConfig cfg) throws FacesException, ELException;
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagLibrary.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagLibrary.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagLibrary.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TagLibrary.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,85 @@
+/**
+ * Licensed 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 com.sun.facelets.tag;
+
+import java.lang.reflect.Method;
+
+import javax.faces.FacesException;
+
+/**
+ * A library of Tags associated with one or more namespaces.
+ * 
+ * @author Jacob Hookom
+ * @version $Id: TagLibrary.java,v 1.3 2008/07/13 19:01:36 rlubke Exp $
+ */
+public interface TagLibrary
+{
+
+    /**
+     * If this library contains the passed namespace
+     * 
+     * @param ns
+     *            namespace
+     * @return true if the namespace is used in this library
+     */
+    public boolean containsNamespace(String ns);
+
+    /**
+     * If this library contains a TagHandler for the namespace and local name
+     * 
+     * @param ns
+     *            namespace
+     * @param localName
+     *            local name
+     * @return true if handled by this library
+     */
+    public boolean containsTagHandler(String ns, String localName);
+
+    /**
+     * Create a new instance of a TagHandler, using the passed TagConfig
+     * 
+     * @param ns
+     *            namespace
+     * @param localName
+     *            local name
+     * @param tag
+     *            configuration information
+     * @return a new TagHandler instance
+     * @throws FacesException
+     */
+    public TagHandler createTagHandler(String ns, String localName, TagConfig tag) throws FacesException;
+
+    /**
+     * If this library contains the specified function name
+     * 
+     * @param ns
+     *            namespace
+     * @param name
+     *            function name
+     * @return true if handled
+     */
+    public boolean containsFunction(String ns, String name);
+
+    /**
+     * Return a Method instance for the passed namespace and name
+     * 
+     * @param ns
+     *            namespace
+     * @param name
+     *            function name
+     * @return
+     */
+    public Method createFunction(String ns, String name);
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TextHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TextHandler.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TextHandler.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/TextHandler.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,42 @@
+/**
+ * Licensed 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 com.sun.facelets.tag;
+
+import javax.faces.webapp.pdl.facelets.FaceletContext;
+
+/**
+ * A mixin' interface that allows other code to identify FaceletHandlers that may provide text (String) content.
+ * 
+ * @author Jacob Hookom
+ * 
+ */
+public interface TextHandler
+{
+
+    /**
+     * Return the literal String value of the contained text
+     * 
+     * @return
+     */
+    public String getText();
+
+    /**
+     * Evaluate the literal String value against EL of the contained text
+     * 
+     * @param ctx
+     * @return
+     */
+    public String getText(FaceletContext ctx);
+
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/UserTagHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/UserTagHandler.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/UserTagHandler.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/UserTagHandler.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,147 @@
+/**
+ * Licensed 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 com.sun.facelets.tag;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import javax.el.ELException;
+import javax.el.VariableMapper;
+import javax.faces.FacesException;
+import javax.faces.component.UIComponent;
+
+import javax.faces.webapp.pdl.facelets.FaceletContext;
+import javax.faces.webapp.pdl.facelets.FaceletException;
+import com.sun.facelets.TemplateClient;
+import com.sun.facelets.el.VariableMapperWrapper;
+import com.sun.facelets.tag.ui.DefineHandler;
+
+/**
+ * A Tag that is specified in a FaceletFile. Takes all attributes specified and sets them on the FaceletContext before
+ * including the targeted Facelet file.
+ * 
+ * @author Jacob Hookom
+ * @version $Id: UserTagHandler.java,v 1.12 2008/07/13 19:01:35 rlubke Exp $
+ */
+final class UserTagHandler extends TagHandler implements TemplateClient
+{
+
+    protected final TagAttribute[] vars;
+
+    protected final URL location;
+
+    protected final Map handlers;
+
+    /**
+     * @param config
+     */
+    public UserTagHandler(TagConfig config, URL location)
+    {
+        super(config);
+        this.vars = this.tag.getAttributes().getAll();
+        this.location = location;
+        Iterator itr = this.findNextByType(DefineHandler.class);
+        if (itr.hasNext())
+        {
+            handlers = new HashMap();
+
+            DefineHandler d = null;
+            while (itr.hasNext())
+            {
+                d = (DefineHandler) itr.next();
+                this.handlers.put(d.getName(), d);
+            }
+        }
+        else
+        {
+            handlers = null;
+        }
+    }
+
+    /**
+     * Iterate over all TagAttributes and set them on the FaceletContext's VariableMapper, then include the target
+     * Facelet. Finally, replace the old VariableMapper.
+     * 
+     * @see TagAttribute#getValueExpression(FaceletContext, Class)
+     * @see VariableMapper
+     * @see javax.faces.webapp.pdl.facelets.FaceletHandler#apply(javax.faces.webapp.pdl.facelets.FaceletContext, javax.faces.component.UIComponent)
+     */
+    public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, FaceletException,
+            ELException
+    {
+        VariableMapper orig = ctx.getVariableMapper();
+
+        // setup a variable map
+        if (this.vars.length > 0)
+        {
+            VariableMapper varMapper = new VariableMapperWrapper(orig);
+            for (int i = 0; i < this.vars.length; i++)
+            {
+                varMapper.setVariable(this.vars[i].getLocalName(), this.vars[i].getValueExpression(ctx, Object.class));
+            }
+            ctx.setVariableMapper(varMapper);
+        }
+
+        // eval include
+        try
+        {
+            ctx.pushClient(this);
+            ctx.includeFacelet(parent, this.location);
+        }
+        catch (FileNotFoundException e)
+        {
+            throw new TagException(this.tag, e.getMessage());
+        }
+        finally
+        {
+
+            // make sure we undo our changes
+            ctx.popClient(this);
+            ctx.setVariableMapper(orig);
+        }
+    }
+
+    public boolean apply(FaceletContext ctx, UIComponent parent, String name) throws IOException, FacesException,
+            FaceletException, ELException
+    {
+        if (name != null)
+        {
+            if (this.handlers == null)
+            {
+                return false;
+            }
+            DefineHandler handler = (DefineHandler) this.handlers.get(name);
+            if (handler != null)
+            {
+                handler.applyDefinition(ctx, parent);
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+        else
+        {
+            this.nextHandler.apply(ctx, parent);
+            return true;
+        }
+    }
+
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ActionSourceRule.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ActionSourceRule.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ActionSourceRule.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ActionSourceRule.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,154 @@
+/**
+ * Licensed 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 com.sun.facelets.tag.jsf;
+
+import javax.faces.component.ActionSource;
+import javax.faces.component.ActionSource2;
+import javax.faces.event.ActionEvent;
+import javax.faces.event.MethodExpressionActionListener;
+
+import javax.faces.webapp.pdl.facelets.FaceletContext;
+import com.sun.facelets.el.LegacyMethodBinding;
+import com.sun.facelets.tag.TagAttribute;
+import com.sun.facelets.tag.Metadata;
+import com.sun.facelets.tag.MetaRule;
+import com.sun.facelets.tag.MetadataTarget;
+import com.sun.facelets.util.FacesAPI;
+
+/**
+ * 
+ * @author Jacob Hookom
+ * @version $Id: ActionSourceRule.java,v 1.5 2008/07/13 19:01:46 rlubke Exp $
+ */
+final class ActionSourceRule extends MetaRule
+{
+
+    public final static Class[] ACTION_SIG = new Class[0];
+
+    public final static Class[] ACTION_LISTENER_SIG = new Class[] { ActionEvent.class };
+
+    final static class ActionMapper extends Metadata
+    {
+
+        private final TagAttribute attr;
+
+        public ActionMapper(TagAttribute attr)
+        {
+            this.attr = attr;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((ActionSource) instance).setAction(new LegacyMethodBinding(this.attr
+                    .getMethodExpression(ctx, String.class, ActionSourceRule.ACTION_SIG)));
+        }
+    }
+
+    final static class ActionMapper2 extends Metadata
+    {
+
+        private final TagAttribute attr;
+
+        public ActionMapper2(TagAttribute attr)
+        {
+            this.attr = attr;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((ActionSource2) instance).setActionExpression(this.attr.getMethodExpression(ctx, String.class,
+                                                                                         ActionSourceRule.ACTION_SIG));
+        }
+
+    }
+
+    final static class ActionListenerMapper extends Metadata
+    {
+
+        private final TagAttribute attr;
+
+        public ActionListenerMapper(TagAttribute attr)
+        {
+            this.attr = attr;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((ActionSource) instance).setActionListener(new LegacyMethodBinding(this.attr
+                    .getMethodExpression(ctx, null, ActionSourceRule.ACTION_LISTENER_SIG)));
+        }
+
+    }
+
+    final static class ActionListenerMapper2 extends Metadata
+    {
+
+        private final TagAttribute attr;
+
+        public ActionListenerMapper2(TagAttribute attr)
+        {
+            this.attr = attr;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((ActionSource2) instance).addActionListener(new MethodExpressionActionListener(this.attr
+                    .getMethodExpression(ctx, null, ActionSourceRule.ACTION_LISTENER_SIG)));
+
+        }
+
+    }
+
+    public final static ActionSourceRule Instance = new ActionSourceRule();
+
+    public ActionSourceRule()
+    {
+        super();
+    }
+
+    public Metadata applyRule(String name, TagAttribute attribute, MetadataTarget meta)
+    {
+        if (meta.isTargetInstanceOf(ActionSource.class))
+        {
+
+            boolean elSupport = FacesAPI.getComponentVersion(meta.getTargetClass()) >= 12;
+
+            if ("action".equals(name))
+            {
+                if (elSupport && meta.isTargetInstanceOf(ActionSource2.class))
+                {
+                    return new ActionMapper2(attribute);
+                }
+                else
+                {
+                    return new ActionMapper(attribute);
+                }
+            }
+
+            if ("actionListener".equals(name))
+            {
+                if (elSupport && meta.isTargetInstanceOf(ActionSource2.class))
+                {
+                    return new ActionListenerMapper2(attribute);
+                }
+                else
+                {
+                    return new ActionListenerMapper(attribute);
+                }
+            }
+        }
+        return null;
+    }
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ComponentConfig.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ComponentConfig.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ComponentConfig.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ComponentConfig.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,42 @@
+/**
+ * Licensed 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 com.sun.facelets.tag.jsf;
+
+import com.sun.facelets.tag.TagConfig;
+
+/**
+ * Used in creating AbstractComponentHandler's and all implementations.
+ * 
+ * @see com.sun.facelets.tag.AbstractComponentHandler
+ * @see com.sun.facelets.tag.jsf.ComponentHandler
+ * @author Jacob Hookom
+ * @version $Id: ComponentConfig.java,v 1.3 2008/07/13 19:01:46 rlubke Exp $
+ */
+public interface ComponentConfig extends TagConfig
+{
+    /**
+     * ComponentType to pass to the Application. Cannot be null.
+     * 
+     * @return ComponentType to pass to the Application. Cannot be null.
+     */
+    public String getComponentType();
+
+    /**
+     * RendererType to set on created UIComponent instances.
+     * 
+     * @return RendererType to set on created UIComponent instances
+     */
+    public String getRendererType();
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ComponentHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ComponentHandler.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ComponentHandler.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ComponentHandler.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,338 @@
+/**
+ * Licensed 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 com.sun.facelets.tag.jsf;
+
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.el.ELException;
+import javax.el.MethodExpression;
+import javax.el.ValueExpression;
+import javax.faces.FacesException;
+import javax.faces.application.Application;
+import javax.faces.component.ActionSource;
+import javax.faces.component.ActionSource2;
+import javax.faces.component.EditableValueHolder;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIViewRoot;
+import javax.faces.component.ValueHolder;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+import javax.faces.el.ValueBinding;
+import javax.faces.event.ActionEvent;
+import javax.faces.event.MethodExpressionActionListener;
+import javax.faces.event.MethodExpressionValueChangeListener;
+import javax.faces.event.ValueChangeEvent;
+import javax.faces.validator.MethodExpressionValidator;
+
+import javax.faces.webapp.pdl.facelets.FaceletContext;
+import com.sun.facelets.el.ELAdaptor;
+import com.sun.facelets.el.LegacyMethodBinding;
+import com.sun.facelets.el.LegacyValueBinding;
+import com.sun.facelets.tag.MetaTagHandler;
+import com.sun.facelets.tag.TagAttribute;
+import com.sun.facelets.tag.Metadata;
+import com.sun.facelets.tag.TagException;
+import com.sun.facelets.tag.TagHandler;
+import com.sun.facelets.tag.MetaRuleset;
+import com.sun.facelets.tag.jsf.core.FacetHandler;
+import com.sun.facelets.util.FacesAPI;
+
+/**
+ * Implementation of the tag logic used in the JSF specification. This is your golden hammer for wiring UIComponents to
+ * Facelets.
+ * 
+ * @author Jacob Hookom
+ * @version $Id: ComponentHandler.java,v 1.19 2008/07/13 19:01:47 rlubke Exp $
+ */
+public class ComponentHandler extends MetaTagHandler
+{
+
+    private final static Logger log = Logger.getLogger("facelets.tag.component");
+
+    private final TagAttribute binding;
+
+    private final String componentType;
+
+    private final TagAttribute id;
+
+    private final String rendererType;
+
+    public ComponentHandler(ComponentConfig config)
+    {
+        super(config);
+        this.componentType = config.getComponentType();
+        this.rendererType = config.getRendererType();
+        this.id = this.getAttribute("id");
+        this.binding = this.getAttribute("binding");
+    }
+
+    /**
+     * Method handles UIComponent tree creation in accordance with the JSF 1.2 spec.
+     * <ol>
+     * <li>First determines this UIComponent's id by calling {@link #getId(FaceletContext) getId(FaceletContext)}.</li>
+     * <li>Search the parent for an existing UIComponent of the id we just grabbed</li>
+     * <li>If found, {@link #markForDeletion(UIComponent) mark} its children for deletion.</li>
+     * <li>If <i>not</i> found, call {@link #createComponent(FaceletContext) createComponent}.
+     * <ol>
+     * <li>Only here do we apply {@link ObjectHandler#setAttributes(FaceletContext, Object) attributes}</li>
+     * <li>Set the UIComponent's id</li>
+     * <li>Set the RendererType of this instance</li>
+     * </ol>
+     * </li>
+     * <li>Now apply the nextHandler, passing the UIComponent we've created/found.</li>
+     * <li>Now add the UIComponent to the passed parent</li>
+     * <li>Lastly, if the UIComponent already existed (found), then {@link #finalizeForDeletion(UIComponent) finalize}
+     * for deletion.</li>
+     * </ol>
+     * 
+     * @see javax.faces.webapp.pdl.facelets.FaceletHandler#apply(javax.faces.webapp.pdl.facelets.FaceletContext, javax.faces.component.UIComponent)
+     * 
+     * @throws TagException
+     *             if the UIComponent parent is null
+     */
+    public final void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, ELException
+    {
+        // make sure our parent is not null
+        if (parent == null)
+        {
+            throw new TagException(this.tag, "Parent UIComponent was null");
+        }
+
+        // possible facet scoped
+        String facetName = this.getFacetName(ctx, parent);
+
+        // our id
+        String id = ctx.generateUniqueId(this.tagId);
+
+        // grab our component
+        UIComponent c = ComponentSupport.findChildByTagId(parent, id);
+        boolean componentFound = false;
+        if (c != null)
+        {
+            componentFound = true;
+            // mark all children for cleaning
+            if (log.isLoggable(Level.FINE))
+            {
+                log.fine(this.tag + " Component[" + id + "] Found, marking children for cleanup");
+            }
+            ComponentSupport.markForDeletion(c);
+        }
+        else
+        {
+            c = this.createComponent(ctx);
+            if (log.isLoggable(Level.FINE))
+            {
+                log.fine(this.tag + " Component[" + id + "] Created: " + c.getClass().getName());
+            }
+            this.setAttributes(ctx, c);
+
+            // mark it owned by a facelet instance
+            c.getAttributes().put(ComponentSupport.MARK_CREATED, id);
+
+            // assign our unique id
+            if (this.id != null)
+            {
+                c.setId(this.id.getValue(ctx));
+            }
+            else
+            {
+                UIViewRoot root = ComponentSupport.getViewRoot(ctx, parent);
+                if (root != null)
+                {
+                    String uid = root.createUniqueId();
+                    c.setId(uid);
+                }
+            }
+
+            if (this.rendererType != null)
+            {
+                c.setRendererType(this.rendererType);
+            }
+
+            // hook method
+            this.onComponentCreated(ctx, c, parent);
+        }
+
+        // first allow c to get populated
+        this.applyNextHandler(ctx, c);
+
+        // finish cleaning up orphaned children
+        if (componentFound)
+        {
+            ComponentSupport.finalizeForDeletion(c);
+
+            if (facetName == null)
+            {
+                parent.getChildren().remove(c);
+            }
+        }
+
+        this.onComponentPopulated(ctx, c, parent);
+
+        // add to the tree afterwards
+        // this allows children to determine if it's
+        // been part of the tree or not yet
+        if (facetName == null)
+        {
+            parent.getChildren().add(c);
+        }
+        else
+        {
+            parent.getFacets().put(facetName, c);
+        }
+    }
+
+    /**
+     * Return the Facet name we are scoped in, otherwise null
+     * 
+     * @param ctx
+     * @return
+     */
+    protected final String getFacetName(FaceletContext ctx, UIComponent parent)
+    {
+        return (String) parent.getAttributes().get(FacetHandler.KEY);
+    }
+
+    /**
+     * If the binding attribute was specified, use that in conjuction with our componentType String variable to call
+     * createComponent on the Application, otherwise just pass the componentType String. <p /> If the binding was used,
+     * then set the ValueExpression "binding" on the created UIComponent.
+     * 
+     * @see Application#createComponent(javax.faces.el.ValueBinding, javax.faces.context.FacesContext, java.lang.String)
+     * @see Application#createComponent(java.lang.String)
+     * @param ctx
+     *            FaceletContext to use in creating a component
+     * @return
+     */
+    protected UIComponent createComponent(FaceletContext ctx)
+    {
+        UIComponent c = null;
+        FacesContext faces = ctx.getFacesContext();
+        Application app = faces.getApplication();
+        if (this.binding != null)
+        {
+            ValueExpression ve = this.binding.getValueExpression(ctx, Object.class);
+            if (FacesAPI.getVersion() >= 12)
+            {
+                c = app.createComponent(ve, faces, this.componentType);
+                if (c != null)
+                {
+                    // Make sure the component supports 1.2
+                    if (FacesAPI.getComponentVersion(c) >= 12)
+                    {
+                        c.setValueExpression("binding", ve);
+                    }
+                    else
+                    {
+                        ValueBinding vb = new LegacyValueBinding(ve);
+                        c.setValueBinding("binding", vb);
+                    }
+
+                }
+            }
+            else
+            {
+                ValueBinding vb = new LegacyValueBinding(ve);
+                c = app.createComponent(vb, faces, this.componentType);
+                if (c != null)
+                {
+                    c.setValueBinding("binding", vb);
+                }
+            }
+        }
+        else
+        {
+            c = app.createComponent(this.componentType);
+        }
+        return c;
+    }
+
+    /**
+     * If the id TagAttribute was specified, get it's value, otherwise generate a unique id from our tagId.
+     * 
+     * @see TagAttribute#getValue(FaceletContext)
+     * @param ctx
+     *            FaceletContext to use
+     * @return what should be a unique Id
+     */
+    protected String getId(FaceletContext ctx)
+    {
+        if (this.id != null)
+        {
+            return this.id.getValue(ctx);
+        }
+        return ctx.generateUniqueId(this.tagId);
+    }
+
+    protected MetaRuleset createMetaRuleset(Class type)
+    {
+        MetaRuleset m = super.createMetaRuleset(type);
+
+        // ignore standard component attributes
+        m.ignore("binding").ignore("id");
+
+        // add auto wiring for attributes
+        m.addRule(ComponentRule.Instance);
+
+        // if it's an ActionSource
+        if (ActionSource.class.isAssignableFrom(type))
+        {
+            m.addRule(ActionSourceRule.Instance);
+        }
+
+        // if it's a ValueHolder
+        if (ValueHolder.class.isAssignableFrom(type))
+        {
+            m.addRule(ValueHolderRule.Instance);
+
+            // if it's an EditableValueHolder
+            if (EditableValueHolder.class.isAssignableFrom(type))
+            {
+                m.ignore("submittedValue");
+                m.ignore("valid");
+                m.addRule(EditableValueHolderRule.Instance);
+            }
+        }
+
+        return m;
+    }
+
+    /**
+     * A hook method for allowing developers to do additional processing once Facelets creates the component. The
+     * 'setAttributes' method is still perferred, but this method will provide the parent UIComponent before it's been
+     * added to the tree and before any children have been added to the newly created UIComponent.
+     * 
+     * @param ctx
+     * @param c
+     * @param parent
+     */
+    protected void onComponentCreated(FaceletContext ctx, UIComponent c, UIComponent parent)
+    {
+        // do nothing
+    }
+
+    protected void onComponentPopulated(FaceletContext ctx, UIComponent c, UIComponent parent)
+    {
+        // do nothing
+    }
+
+    protected void applyNextHandler(FaceletContext ctx, UIComponent c) throws IOException, FacesException, ELException
+    {
+        // first allow c to get populated
+        this.nextHandler.apply(ctx, c);
+    }
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ComponentRule.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ComponentRule.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ComponentRule.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ComponentRule.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,155 @@
+/**
+ * Licensed 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 com.sun.facelets.tag.jsf;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIComponentBase;
+
+import javax.faces.webapp.pdl.facelets.FaceletContext;
+import com.sun.facelets.el.LegacyValueBinding;
+import com.sun.facelets.tag.TagAttribute;
+import com.sun.facelets.tag.Metadata;
+import com.sun.facelets.tag.MetaRule;
+import com.sun.facelets.tag.MetadataTarget;
+import com.sun.facelets.util.FacesAPI;
+
+/**
+ * 
+ * @author Jacob Hookom
+ * @version $Id: ComponentRule.java,v 1.4 2008/07/13 19:01:47 rlubke Exp $
+ */
+final class ComponentRule extends MetaRule
+{
+
+    final class LiteralAttributeMetadata extends Metadata
+    {
+
+        private final String name;
+        private final String value;
+
+        public LiteralAttributeMetadata(String name, String value)
+        {
+            this.value = value;
+            this.name = name;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((UIComponent) instance).getAttributes().put(this.name, this.value);
+        }
+    }
+
+    final static class ValueExpressionMetadata extends Metadata
+    {
+
+        private final String name;
+
+        private final TagAttribute attr;
+
+        private final Class type;
+
+        public ValueExpressionMetadata(String name, Class type, TagAttribute attr)
+        {
+            this.name = name;
+            this.attr = attr;
+            this.type = type;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((UIComponent) instance).setValueExpression(this.name, this.attr.getValueExpression(ctx, this.type));
+        }
+
+    }
+
+    final static class ValueBindingMetadata extends Metadata
+    {
+
+        private final String name;
+
+        private final TagAttribute attr;
+
+        private final Class type;
+
+        public ValueBindingMetadata(String name, Class type, TagAttribute attr)
+        {
+            this.name = name;
+            this.attr = attr;
+            this.type = type;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((UIComponent) instance).setValueBinding(this.name, new LegacyValueBinding(this.attr
+                    .getValueExpression(ctx, this.type)));
+        }
+
+    }
+
+    private final static Logger log = Logger.getLogger("facelets.tag.component");
+
+    public final static ComponentRule Instance = new ComponentRule();
+
+    public ComponentRule()
+    {
+        super();
+    }
+
+    public Metadata applyRule(String name, TagAttribute attribute, MetadataTarget meta)
+    {
+        if (meta.isTargetInstanceOf(UIComponent.class))
+        {
+
+            // if component and dynamic, then must set expression
+            if (!attribute.isLiteral())
+            {
+                Class type = meta.getPropertyType(name);
+                if (type == null)
+                {
+                    type = Object.class;
+                }
+                if (FacesAPI.getComponentVersion(meta.getTargetClass()) >= 12)
+                {
+                    return new ValueExpressionMetadata(name, type, attribute);
+                }
+                else
+                {
+                    return new ValueBindingMetadata(name, type, attribute);
+                }
+            }
+            else if (meta.getWriteMethod(name) == null)
+            {
+
+                // this was an attribute literal, but not property
+                warnAttr(attribute, meta.getTargetClass(), name);
+
+                return new LiteralAttributeMetadata(name, attribute.getValue());
+            }
+        }
+        return null;
+    }
+
+    private static void warnAttr(TagAttribute attr, Class type, String n)
+    {
+        if (log.isLoggable(Level.FINER))
+        {
+            log.finer(attr + " Property '" + n + "' is not on type: " + type.getName());
+        }
+    }
+
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ComponentSupport.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ComponentSupport.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ComponentSupport.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ComponentSupport.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,352 @@
+/**
+ * Licensed 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 com.sun.facelets.tag.jsf;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+
+import javax.faces.FacesException;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+
+import javax.faces.webapp.pdl.facelets.FaceletContext;
+import javax.faces.webapp.pdl.facelets.FaceletHandler;
+import com.sun.facelets.tag.TagAttribute;
+import com.sun.facelets.tag.TagAttributeException;
+
+/**
+ * 
+ * @author Jacob Hookom
+ * @version $Id: ComponentSupport.java,v 1.8 2008/07/13 19:01:46 rlubke Exp $
+ */
+public final class ComponentSupport
+{
+
+    private final static String MARK_DELETED = "com.sun.facelets.MARK_DELETED";
+    public final static String MARK_CREATED = "com.sun.facelets.MARK_ID";
+
+    /**
+     * Used in conjunction with markForDeletion where any UIComponent marked will be removed.
+     * 
+     * @param c
+     *            UIComponent to finalize
+     */
+    public static final void finalizeForDeletion(UIComponent c)
+    {
+        // remove any existing marks of deletion
+        c.getAttributes().remove(MARK_DELETED);
+
+        // finally remove any children marked as deleted
+        int sz = c.getChildCount();
+        if (sz > 0)
+        {
+            UIComponent cc = null;
+            List cl = c.getChildren();
+            while (--sz >= 0)
+            {
+                cc = (UIComponent) cl.get(sz);
+                if (cc.getAttributes().containsKey(MARK_DELETED))
+                {
+                    cl.remove(sz);
+                }
+            }
+        }
+
+        // remove any facets marked as deleted
+        if (c.getFacets().size() > 0)
+        {
+            Collection col = c.getFacets().values();
+            UIComponent fc;
+            for (Iterator itr = col.iterator(); itr.hasNext();)
+            {
+                fc = (UIComponent) itr.next();
+                if (fc.getAttributes().containsKey(MARK_DELETED))
+                {
+                    itr.remove();
+                }
+            }
+        }
+    }
+
+    /**
+     * A lighter-weight version of UIComponent's findChild.
+     * 
+     * @param parent
+     *            parent to start searching from
+     * @param id
+     *            to match to
+     * @return UIComponent found or null
+     */
+    public static final UIComponent findChild(UIComponent parent, String id)
+    {
+        int sz = parent.getChildCount();
+        if (sz > 0)
+        {
+            UIComponent c = null;
+            List cl = parent.getChildren();
+            while (--sz >= 0)
+            {
+                c = (UIComponent) cl.get(sz);
+                if (id.equals(c.getId()))
+                {
+                    return c;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * By TagId, find Child
+     * 
+     * @param parent
+     * @param id
+     * @return
+     */
+    public static final UIComponent findChildByTagId(UIComponent parent, String id)
+    {
+        Iterator itr = parent.getFacetsAndChildren();
+        UIComponent c = null;
+        String cid = null;
+        while (itr.hasNext())
+        {
+            c = (UIComponent) itr.next();
+            cid = (String) c.getAttributes().get(MARK_CREATED);
+            if (id.equals(cid))
+            {
+                return c;
+            }
+        }
+        // int sz = parent.getChildCount();
+        // if (sz > 0) {
+        // UIComponent c = null;
+        // List cl = parent.getChildren();
+        // String cid = null;
+        // while (--sz >= 0) {
+        // c = (UIComponent) cl.get(sz);
+        // cid = (String) c.getAttributes().get(MARK_CREATED);
+        // if (id.equals(cid)) {
+        // return c;
+        // }
+        // }
+        // }
+        return null;
+    }
+
+    /**
+     * According to JSF 1.2 tag specs, this helper method will use the TagAttribute passed in determining the Locale
+     * intended.
+     * 
+     * @param ctx
+     *            FaceletContext to evaluate from
+     * @param attr
+     *            TagAttribute representing a Locale
+     * @return Locale found
+     * @throws TagAttributeException
+     *             if the Locale cannot be determined
+     */
+    public static final Locale getLocale(FaceletContext ctx, TagAttribute attr) throws TagAttributeException
+    {
+        Object obj = attr.getObject(ctx);
+        if (obj instanceof Locale)
+        {
+            return (Locale) obj;
+        }
+        if (obj instanceof String)
+        {
+            String s = (String) obj;
+            if (s.length() == 2)
+            {
+                return new Locale(s);
+            }
+            if (s.length() == 5)
+            {
+                return new Locale(s.substring(0, 2), s.substring(3, 5).toUpperCase());
+            }
+            if (s.length() >= 7)
+            {
+                return new Locale(s.substring(0, 2), s.substring(3, 5).toUpperCase(), s.substring(6, s.length()));
+            }
+            throw new TagAttributeException(attr, "Invalid Locale Specified: " + s);
+        }
+        else
+        {
+            throw new TagAttributeException(attr, "Attribute did not evaluate to a String or Locale: " + obj);
+        }
+    }
+
+    /**
+     * Tries to walk up the parent to find the UIViewRoot, if not found, then go to FaceletContext's FacesContext for
+     * the view root.
+     * 
+     * @param ctx
+     *            FaceletContext
+     * @param parent
+     *            UIComponent to search from
+     * @return UIViewRoot instance for this evaluation
+     */
+    public static final UIViewRoot getViewRoot(FaceletContext ctx, UIComponent parent)
+    {
+        UIComponent c = parent;
+        do
+        {
+            if (c instanceof UIViewRoot)
+            {
+                return (UIViewRoot) c;
+            }
+            else
+            {
+                c = c.getParent();
+            }
+        } while (c != null);
+        return ctx.getFacesContext().getViewRoot();
+    }
+
+    /**
+     * Marks all direct children and Facets with an attribute for deletion.
+     * 
+     * @see #finalizeForDeletion(UIComponent)
+     * @param c
+     *            UIComponent to mark
+     */
+    public static final void markForDeletion(UIComponent c)
+    {
+        // flag this component as deleted
+        c.getAttributes().put(MARK_DELETED, Boolean.TRUE);
+
+        // mark all children to be deleted
+        int sz = c.getChildCount();
+        if (sz > 0)
+        {
+            UIComponent cc = null;
+            List cl = c.getChildren();
+            while (--sz >= 0)
+            {
+                cc = (UIComponent) cl.get(sz);
+                if (cc.getAttributes().containsKey(MARK_CREATED))
+                {
+                    cc.getAttributes().put(MARK_DELETED, Boolean.TRUE);
+                }
+            }
+        }
+
+        // mark all facets to be deleted
+        if (c.getFacets().size() > 0)
+        {
+            Collection col = c.getFacets().values();
+            UIComponent fc;
+            for (Iterator itr = col.iterator(); itr.hasNext();)
+            {
+                fc = (UIComponent) itr.next();
+                if (fc.getAttributes().containsKey(MARK_CREATED))
+                {
+                    fc.getAttributes().put(MARK_DELETED, Boolean.TRUE);
+                }
+            }
+        }
+    }
+
+    public final static void encodeRecursive(FacesContext context, UIComponent viewToRender) throws IOException,
+            FacesException
+    {
+        if (viewToRender.isRendered())
+        {
+            viewToRender.encodeBegin(context);
+            if (viewToRender.getRendersChildren())
+            {
+                viewToRender.encodeChildren(context);
+            }
+            else if (viewToRender.getChildCount() > 0)
+            {
+                Iterator kids = viewToRender.getChildren().iterator();
+                while (kids.hasNext())
+                {
+                    UIComponent kid = (UIComponent) kids.next();
+                    encodeRecursive(context, kid);
+                }
+            }
+            viewToRender.encodeEnd(context);
+        }
+    }
+
+    public static void removeTransient(UIComponent c)
+    {
+        UIComponent d, e;
+        if (c.getChildCount() > 0)
+        {
+            for (Iterator itr = c.getChildren().iterator(); itr.hasNext();)
+            {
+                d = (UIComponent) itr.next();
+                if (d.getFacets().size() > 0)
+                {
+                    for (Iterator jtr = d.getFacets().values().iterator(); jtr.hasNext();)
+                    {
+                        e = (UIComponent) jtr.next();
+                        if (e.isTransient())
+                        {
+                            jtr.remove();
+                        }
+                        else
+                        {
+                            removeTransient(e);
+                        }
+                    }
+                }
+                if (d.isTransient())
+                {
+                    itr.remove();
+                }
+                else
+                {
+                    removeTransient(d);
+                }
+            }
+        }
+        if (c.getFacets().size() > 0)
+        {
+            for (Iterator itr = c.getFacets().values().iterator(); itr.hasNext();)
+            {
+                d = (UIComponent) itr.next();
+                if (d.isTransient())
+                {
+                    itr.remove();
+                }
+                else
+                {
+                    removeTransient(d);
+                }
+            }
+        }
+    }
+
+    /**
+     * Determine if the passed component is not null and if it's new to the tree. This operation can be used for
+     * determining if attributes should be wired to the component.
+     * 
+     * @param component
+     *            the component you wish to modify
+     * @return true if it's new
+     */
+    public final static boolean isNew(UIComponent component)
+    {
+        return component != null && component.getParent() == null;
+    }
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ConvertHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ConvertHandler.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ConvertHandler.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ConvertHandler.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,152 @@
+/**
+ * Licensed 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 com.sun.facelets.tag.jsf;
+
+import java.io.IOException;
+
+import javax.el.ELException;
+import javax.el.ValueExpression;
+import javax.faces.FacesException;
+import javax.faces.component.UIComponent;
+import javax.faces.component.ValueHolder;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+
+import javax.faces.webapp.pdl.facelets.FaceletContext;
+import javax.faces.webapp.pdl.facelets.FaceletException;
+import com.sun.facelets.tag.MetaTagHandler;
+import com.sun.facelets.tag.TagAttribute;
+import com.sun.facelets.tag.TagConfig;
+import com.sun.facelets.tag.TagException;
+import com.sun.facelets.tag.MetaRuleset;
+
+/**
+ * Handles setting a Converter instance on a ValueHolder. Will wire all attributes set to the Converter instance
+ * created/fetched. Uses the "binding" attribute for grabbing instances to apply attributes to. <p/> Will only
+ * set/create Converter is the passed UIComponent's parent is null, signifying that it wasn't restored from an existing
+ * tree.
+ * 
+ * @see javax.faces.webapp.ConverterELTag
+ * @see javax.faces.convert.Converter
+ * @see javax.faces.component.ValueHolder
+ * @author Jacob Hookom
+ * @version $Id: ConvertHandler.java,v 1.4 2008/07/13 19:01:46 rlubke Exp $
+ */
+public class ConvertHandler extends MetaTagHandler
+{
+
+    private final TagAttribute binding;
+
+    private String converterId;
+
+    /**
+     * @param config
+     * @deprecated
+     */
+    public ConvertHandler(TagConfig config)
+    {
+        super(config);
+        this.binding = this.getAttribute("binding");
+        this.converterId = null;
+    }
+
+    public ConvertHandler(ConverterConfig config)
+    {
+        this((TagConfig) config);
+        this.converterId = config.getConverterId();
+    }
+
+    /**
+     * Set Converter instance on parent ValueHolder if it's not being restored.
+     * <ol>
+     * <li>Cast to ValueHolder</li>
+     * <li>If "binding" attribute was specified, fetch/create and re-bind to expression.</li>
+     * <li>Otherwise, call {@link #createConverter(FaceletContext) createConverter}.</li>
+     * <li>Call {@link ObjectHandler#setAttributes(FaceletContext, Object) setAttributes} on Converter instance.</li>
+     * <li>Set the Converter on the ValueHolder</li>
+     * <li>If the ValueHolder has a localValue, convert it and set the value</li>
+     * </ol>
+     * 
+     * @see ValueHolder
+     * @see Converter
+     * @see #createConverter(FaceletContext)
+     * @see javax.faces.webapp.pdl.facelets.FaceletHandler#apply(javax.faces.webapp.pdl.facelets.FaceletContext, javax.faces.component.UIComponent)
+     */
+    public final void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException,
+            FaceletException, ELException
+    {
+        if (parent == null || !(parent instanceof ValueHolder))
+        {
+            throw new TagException(this.tag, "Parent not an instance of ValueHolder: " + parent);
+        }
+
+        // only process if it's been created
+        if (parent.getParent() == null)
+        {
+            // cast to a ValueHolder
+            ValueHolder vh = (ValueHolder) parent;
+            ValueExpression ve = null;
+            Converter c = null;
+            if (this.binding != null)
+            {
+                ve = this.binding.getValueExpression(ctx, Converter.class);
+                c = (Converter) ve.getValue(ctx);
+            }
+            if (c == null)
+            {
+                c = this.createConverter(ctx);
+                if (ve != null)
+                {
+                    ve.setValue(ctx, c);
+                }
+            }
+            if (c == null)
+            {
+                throw new TagException(this.tag, "No Converter was created");
+            }
+            this.setAttributes(ctx, c);
+            vh.setConverter(c);
+            Object lv = vh.getLocalValue();
+            FacesContext faces = ctx.getFacesContext();
+            if (lv instanceof String)
+            {
+                vh.setValue(c.getAsObject(faces, parent, (String) lv));
+            }
+        }
+    }
+
+    /**
+     * Create a Converter instance
+     * 
+     * @param ctx
+     *            FaceletContext to use
+     * @return Converter instance, cannot be null
+     */
+    protected Converter createConverter(FaceletContext ctx)
+    {
+        if (this.converterId == null)
+        {
+            throw new TagException(
+                                   this.tag,
+                                   "Default behavior invoked of requiring a converter-id passed in the constructor, must override ConvertHandler(ConverterConfig)");
+        }
+        return ctx.getFacesContext().getApplication().createConverter(this.converterId);
+    }
+
+    protected MetaRuleset createMetaRuleset(Class type)
+    {
+        return super.createMetaRuleset(type).ignore("binding");
+    }
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ConverterConfig.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ConverterConfig.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ConverterConfig.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ConverterConfig.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,36 @@
+/**
+ * Licensed 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 com.sun.facelets.tag.jsf;
+
+import com.sun.facelets.tag.TagConfig;
+
+/**
+ * Used in creating ConvertHandler's and all implementations.
+ * 
+ * @see com.sun.facelets.tag.jsf.ConvertHandler
+ * @author Jacob Hookom
+ * @version $Id: ConverterConfig.java,v 1.3 2008/07/13 19:01:47 rlubke Exp $
+ */
+public interface ConverterConfig extends TagConfig
+{
+
+    /**
+     * The converter id to be used in instantiating this converter
+     * 
+     * @return the converter id that can be passed to Application.createConverter
+     */
+    public String getConverterId();
+
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/EditableValueHolderRule.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/EditableValueHolderRule.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/EditableValueHolderRule.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/EditableValueHolderRule.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,167 @@
+/**
+ * Licensed 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 com.sun.facelets.tag.jsf;
+
+import javax.faces.component.EditableValueHolder;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.event.MethodExpressionValueChangeListener;
+import javax.faces.event.ValueChangeEvent;
+import javax.faces.validator.MethodExpressionValidator;
+
+import javax.faces.webapp.pdl.facelets.FaceletContext;
+import com.sun.facelets.el.LegacyMethodBinding;
+import com.sun.facelets.tag.TagAttribute;
+import com.sun.facelets.tag.Metadata;
+import com.sun.facelets.tag.MetaRule;
+import com.sun.facelets.tag.MetadataTarget;
+import com.sun.facelets.util.FacesAPI;
+
+/**
+ * 
+ * @author Jacob Hookom
+ * @version $Id: EditableValueHolderRule.java,v 1.3 2008/07/13 19:01:46 rlubke Exp $
+ */
+public final class EditableValueHolderRule extends MetaRule
+{
+
+    final static class LiteralValidatorMetadata extends Metadata
+    {
+
+        private final String validatorId;
+
+        public LiteralValidatorMetadata(String validatorId)
+        {
+            this.validatorId = validatorId;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((EditableValueHolder) instance).addValidator(ctx.getFacesContext().getApplication()
+                    .createValidator(this.validatorId));
+        }
+    }
+
+    final static class ValueChangedExpressionMetadata extends Metadata
+    {
+        private final TagAttribute attr;
+
+        public ValueChangedExpressionMetadata(TagAttribute attr)
+        {
+            this.attr = attr;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((EditableValueHolder) instance).addValueChangeListener(new MethodExpressionValueChangeListener(this.attr
+                    .getMethodExpression(ctx, null, VALUECHANGE_SIG)));
+        }
+    }
+
+    final static class ValueChangedBindingMetadata extends Metadata
+    {
+        private final TagAttribute attr;
+
+        public ValueChangedBindingMetadata(TagAttribute attr)
+        {
+            this.attr = attr;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((EditableValueHolder) instance).setValueChangeListener(new LegacyMethodBinding(this.attr
+                    .getMethodExpression(ctx, null, VALUECHANGE_SIG)));
+        }
+    }
+
+    final static class ValidatorExpressionMetadata extends Metadata
+    {
+        private final TagAttribute attr;
+
+        public ValidatorExpressionMetadata(TagAttribute attr)
+        {
+            this.attr = attr;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((EditableValueHolder) instance).addValidator(new MethodExpressionValidator(this.attr
+                    .getMethodExpression(ctx, null, VALIDATOR_SIG)));
+        }
+    }
+
+    final static class ValidatorBindingMetadata extends Metadata
+    {
+        private final TagAttribute attr;
+
+        public ValidatorBindingMetadata(TagAttribute attr)
+        {
+            this.attr = attr;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((EditableValueHolder) instance).setValidator(new LegacyMethodBinding(this.attr
+                    .getMethodExpression(ctx, null, VALIDATOR_SIG)));
+        }
+    }
+
+    private final static Class[] VALIDATOR_SIG = new Class[] { FacesContext.class, UIComponent.class, Object.class };
+
+    private final static Class[] VALUECHANGE_SIG = new Class[] { ValueChangeEvent.class };
+
+    public final static EditableValueHolderRule Instance = new EditableValueHolderRule();
+
+    public Metadata applyRule(String name, TagAttribute attribute, MetadataTarget meta)
+    {
+
+        if (meta.isTargetInstanceOf(EditableValueHolder.class))
+        {
+
+            boolean elSupport = FacesAPI.getComponentVersion(meta.getTargetClass()) >= 12;
+
+            if ("validator".equals(name))
+            {
+                if (attribute.isLiteral())
+                {
+                    return new LiteralValidatorMetadata(attribute.getValue());
+                }
+                else if (elSupport)
+                {
+                    return new ValidatorExpressionMetadata(attribute);
+                }
+                else
+                {
+                    return new ValidatorBindingMetadata(attribute);
+                }
+            }
+
+            if ("valueChangeListener".equals(name))
+            {
+                if (elSupport)
+                {
+                    return new ValueChangedExpressionMetadata(attribute);
+                }
+                else
+                {
+                    return new ValueChangedBindingMetadata(attribute);
+                }
+            }
+
+        }
+        return null;
+    }
+
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ValidateHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ValidateHandler.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ValidateHandler.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ValidateHandler.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,133 @@
+/**
+ * Licensed 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 com.sun.facelets.tag.jsf;
+
+import java.io.IOException;
+
+import javax.el.ELException;
+import javax.el.ValueExpression;
+import javax.faces.FacesException;
+import javax.faces.component.EditableValueHolder;
+import javax.faces.component.UIComponent;
+import javax.faces.validator.Validator;
+
+import javax.faces.webapp.pdl.facelets.FaceletContext;
+import javax.faces.webapp.pdl.facelets.FaceletException;
+import com.sun.facelets.tag.MetaTagHandler;
+import com.sun.facelets.tag.TagAttribute;
+import com.sun.facelets.tag.TagConfig;
+import com.sun.facelets.tag.TagException;
+import com.sun.facelets.tag.MetaRuleset;
+
+/**
+ * Handles setting a Validator instance on a EditableValueHolder. Will wire all attributes set to the Validator instance
+ * created/fetched. Uses the "binding" attribute for grabbing instances to apply attributes to. <p/> Will only
+ * set/create Validator is the passed UIComponent's parent is null, signifying that it wasn't restored from an existing
+ * tree.
+ * 
+ * @author Jacob Hookom
+ * @version $Id: ValidateHandler.java,v 1.4 2008/07/13 19:01:46 rlubke Exp $
+ */
+public class ValidateHandler extends MetaTagHandler
+{
+
+    private final TagAttribute binding;
+
+    private String validatorId;
+
+    /**
+     * 
+     * @param config
+     * @deprecated
+     */
+    public ValidateHandler(TagConfig config)
+    {
+        super(config);
+        this.binding = this.getAttribute("binding");
+    }
+
+    public ValidateHandler(ValidatorConfig config)
+    {
+        this((TagConfig) config);
+        this.validatorId = config.getValidatorId();
+    }
+
+    /**
+     * TODO
+     * 
+     * @see javax.faces.webapp.pdl.facelets.FaceletHandler#apply(javax.faces.webapp.pdl.facelets.FaceletContext, javax.faces.component.UIComponent)
+     */
+    public final void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException,
+            FaceletException, ELException
+    {
+
+        if (parent == null || !(parent instanceof EditableValueHolder))
+        {
+            throw new TagException(this.tag, "Parent not an instance of EditableValueHolder: " + parent);
+        }
+
+        // only process if it's been created
+        if (parent.getParent() == null)
+        {
+            // cast to a ValueHolder
+            EditableValueHolder evh = (EditableValueHolder) parent;
+            ValueExpression ve = null;
+            Validator v = null;
+            if (this.binding != null)
+            {
+                ve = this.binding.getValueExpression(ctx, Validator.class);
+                v = (Validator) ve.getValue(ctx);
+            }
+            if (v == null)
+            {
+                v = this.createValidator(ctx);
+                if (ve != null)
+                {
+                    ve.setValue(ctx, v);
+                }
+            }
+            if (v == null)
+            {
+                throw new TagException(this.tag, "No Validator was created");
+            }
+            this.setAttributes(ctx, v);
+            evh.addValidator(v);
+        }
+    }
+
+    /**
+     * Template method for creating a Validator instance
+     * 
+     * @param ctx
+     *            FaceletContext to use
+     * @return a new Validator instance
+     */
+    protected Validator createValidator(FaceletContext ctx)
+    {
+        if (this.validatorId == null)
+        {
+            throw new TagException(
+                                   this.tag,
+                                   "Default behavior invoked of requiring a validator-id passed in the constructor, must override ValidateHandler(ValidatorConfig)");
+        }
+        return ctx.getFacesContext().getApplication().createValidator(this.validatorId);
+    }
+
+    protected MetaRuleset createMetaRuleset(Class type)
+    {
+        return super.createMetaRuleset(type).ignore("binding");
+    }
+
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ValidatorConfig.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ValidatorConfig.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ValidatorConfig.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ValidatorConfig.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,36 @@
+/**
+ * Licensed 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 com.sun.facelets.tag.jsf;
+
+import com.sun.facelets.tag.TagConfig;
+
+/**
+ * Used in creating ValidateHandler's and all implementations.
+ * 
+ * @see com.sun.facelets.tag.jsf.ValidateHandler
+ * @author Jacob Hookom
+ * @version $Id: ValidatorConfig.java,v 1.3 2008/07/13 19:01:46 rlubke Exp $
+ */
+public interface ValidatorConfig extends TagConfig
+{
+
+    /**
+     * The validator-id associated with a particular validator in your faces-config
+     * 
+     * @return passable to Application.createValidator(String)
+     */
+    public String getValidatorId();
+
+}

Added: myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ValueHolderRule.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ValueHolderRule.java?rev=740940&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ValueHolderRule.java (added)
+++ myfaces/core/branches/2_0_0/impl/src/main/java/com/sun/facelets/tag/jsf/ValueHolderRule.java Wed Feb  4 23:55:25 2009
@@ -0,0 +1,184 @@
+/**
+ * Licensed 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 com.sun.facelets.tag.jsf;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.ValueHolder;
+import javax.faces.convert.Converter;
+
+import javax.faces.webapp.pdl.facelets.FaceletContext;
+import com.sun.facelets.el.LegacyValueBinding;
+import com.sun.facelets.tag.TagAttribute;
+import com.sun.facelets.tag.Metadata;
+import com.sun.facelets.tag.MetaRule;
+import com.sun.facelets.tag.MetadataTarget;
+import com.sun.facelets.util.FacesAPI;
+
+/**
+ * 
+ * @author Jacob Hookom
+ * @version $Id: ValueHolderRule.java,v 1.4 2008/07/13 19:01:46 rlubke Exp $
+ */
+final class ValueHolderRule extends MetaRule
+{
+
+    final static class LiteralConverterMetadata extends Metadata
+    {
+
+        private final String converterId;
+
+        public LiteralConverterMetadata(String converterId)
+        {
+            this.converterId = converterId;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((ValueHolder) instance).setConverter(ctx.getFacesContext().getApplication()
+                    .createConverter(this.converterId));
+        }
+    }
+
+    final static class DynamicConverterMetadata extends Metadata
+    {
+
+        private final TagAttribute attr;
+
+        public DynamicConverterMetadata(TagAttribute attr)
+        {
+            this.attr = attr;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((UIComponent) instance).setValueBinding("converter", new LegacyValueBinding(attr
+                    .getValueExpression(ctx, Converter.class)));
+        }
+    }
+
+    final static class DynamicConverterMetadata2 extends Metadata
+    {
+
+        private final TagAttribute attr;
+
+        public DynamicConverterMetadata2(TagAttribute attr)
+        {
+            this.attr = attr;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((UIComponent) instance).setValueExpression("converter", attr.getValueExpression(ctx, Converter.class));
+        }
+    }
+
+    final static class LiteralValueMetadata extends Metadata
+    {
+
+        private final String value;
+
+        public LiteralValueMetadata(String value)
+        {
+            this.value = value;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((ValueHolder) instance).setValue(this.value);
+        }
+    }
+
+    final static class DynamicValueExpressionMetadata extends Metadata
+    {
+
+        private final TagAttribute attr;
+
+        public DynamicValueExpressionMetadata(TagAttribute attr)
+        {
+            this.attr = attr;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((UIComponent) instance).setValueExpression("value", attr.getValueExpression(ctx, Object.class));
+        }
+    }
+
+    final static class DynamicValueBindingMetadata extends Metadata
+    {
+
+        private final TagAttribute attr;
+
+        public DynamicValueBindingMetadata(TagAttribute attr)
+        {
+            this.attr = attr;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((UIComponent) instance).setValueBinding("value", new LegacyValueBinding(attr
+                    .getValueExpression(ctx, Object.class)));
+        }
+    }
+
+    public final static ValueHolderRule Instance = new ValueHolderRule();
+
+    public Metadata applyRule(String name, TagAttribute attribute, MetadataTarget meta)
+    {
+        if (meta.isTargetInstanceOf(ValueHolder.class))
+        {
+
+            if ("converter".equals(name))
+            {
+                if (attribute.isLiteral())
+                {
+                    return new LiteralConverterMetadata(attribute.getValue());
+                }
+                else
+                {
+                    if (FacesAPI.getComponentVersion(meta.getTargetClass()) >= 12)
+                    {
+                        return new DynamicConverterMetadata2(attribute);
+                    }
+                    else
+                    {
+                        return new DynamicConverterMetadata(attribute);
+                    }
+                }
+            }
+
+            if ("value".equals(name))
+            {
+                if (attribute.isLiteral())
+                {
+                    return new LiteralValueMetadata(attribute.getValue());
+                }
+                else
+                {
+                    if (FacesAPI.getComponentVersion(meta.getTargetClass()) >= 12)
+                    {
+                        return new DynamicValueExpressionMetadata(attribute);
+                    }
+                    else
+                    {
+                        return new DynamicValueBindingMetadata(attribute);
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+}