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 2013/01/26 00:44:45 UTC

svn commit: r1438771 - in /myfaces/core/branches/2.2.x: api/src/main/java/javax/faces/component/ api/src/main/java/javax/faces/context/ api/src/main/java/javax/faces/render/ impl/src/main/java/org/apache/myfaces/view/facelets/compiler/ impl/src/main/ja...

Author: lu4242
Date: Fri Jan 25 23:44:45 2013
New Revision: 1438771

URL: http://svn.apache.org/viewvc?rev=1438771&view=rev
Log:
MYFACES-3686 Implement f:passThroughAttribute and f:passThroughAttributes 

Added:
    myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/component/_PassThroughAttributesMap.java   (with props)
    myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/PassThroughAttributeHandler.java
      - copied, changed from r1433611, myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/AttributeHandler.java
    myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/PassThroughAttributesHandler.java   (with props)
Modified:
    myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/component/UIComponent.java
    myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/component/UIComponentBase.java
    myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/context/ResponseWriter.java
    myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/render/Renderer.java
    myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/UILeaf.java

Modified: myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/component/UIComponent.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/component/UIComponent.java?rev=1438771&r1=1438770&r2=1438771&view=diff
==============================================================================
--- myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/component/UIComponent.java (original)
+++ myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/component/UIComponent.java Fri Jan 25 23:44:45 2013
@@ -182,6 +182,19 @@ public abstract class UIComponent
     }
 
     public abstract Map<String, Object> getAttributes();
+    
+    /**
+     * @since 2.2
+     * @return 
+     */
+    public abstract Map<String,Object> getPassThroughAttributes();
+    
+    /**
+     * @since 2.2
+     * @param create
+     * @return 
+     */
+    public abstract Map<String,Object> getPassThroughAttributes(boolean create);
 
     /**
      *
@@ -1027,7 +1040,8 @@ public abstract class UIComponent
         rendererType,
         attributesMap,
         bindings,
-        facesListeners
+        facesListeners,
+        passThroughAttributesMap
     }
 
     protected StateHelper getStateHelper()

Modified: myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/component/UIComponentBase.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/component/UIComponentBase.java?rev=1438771&r1=1438770&r2=1438771&view=diff
==============================================================================
--- myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/component/UIComponentBase.java (original)
+++ myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/component/UIComponentBase.java Fri Jan 25 23:44:45 2013
@@ -91,6 +91,7 @@ public abstract class UIComponentBase ex
             = "javax.faces.component.UIComponentBase.SHARED_STRING_BUILDER";
 
     private _ComponentAttributesMap _attributesMap = null;
+    private _PassThroughAttributesMap _passthroughAttributesMap = null;
     private List<UIComponent> _childrenList = null;
     private Map<String, UIComponent> _facetMap = null;
     private _DeltaList<FacesListener> _facesListeners = null;
@@ -99,12 +100,19 @@ public abstract class UIComponentBase ex
     private UIComponent _parent = null;
     private boolean _transient = false;
     
-    private boolean _isRendererTypeSet = false;
+    //private boolean _isRendererTypeSet = false;
     private String _rendererType;
     private String _markCreated;
     private String _facetName;
-    private boolean _addedByHandler = false;
-    private boolean _facetCreatedUIPanel = false;
+    //private boolean _addedByHandler = false;
+    //private boolean _facetCreatedUIPanel = false;
+    //private boolean _passthroughAttributesMapSet = false;
+    
+    private int _capabilities = 0;
+    private final static int FLAG_IS_RENDERER_TYPE_SET = 1;
+    private final static int FLAG_ADDED_BY_HANDLER = 2;
+    private final static int FLAG_FACET_CREATED_UIPANEL = 4;
+    private final static int FLAG_PASSTHROUGH_ATTRIBUTE_MAP_SET = 8;
 
     /**
      * This map holds ClientBehavior instances.
@@ -444,7 +452,8 @@ public abstract class UIComponentBase ex
                 ((PartialStateHolder) entry.getValue()).clearInitialState();
             }
         }
-        _isRendererTypeSet = false;
+        //_isRendererTypeSet = false;
+        _capabilities &= ~(FLAG_IS_RENDERER_TYPE_SET);
     }
 
     /**
@@ -801,6 +810,36 @@ public abstract class UIComponentBase ex
         return _attributesMap;
     }
 
+    @Override
+    public Map<String, Object> getPassThroughAttributes()
+    {
+        return getPassThroughAttributes(true);
+    }
+
+    @Override
+    public Map<String, Object> getPassThroughAttributes(boolean create)
+    {
+        // Take into account the param "create" in MyFaces case does not have
+        // sense at all
+        if (_passthroughAttributesMap == null)
+        {
+            if (!create)
+            {
+                if ((_capabilities & FLAG_PASSTHROUGH_ATTRIBUTE_MAP_SET) != 0)
+                {
+                    // Was already created, return wrapper
+                    _passthroughAttributesMap = new _PassThroughAttributesMap(this);
+                }
+            }
+            else
+            {
+                _passthroughAttributesMap = new _PassThroughAttributesMap(this);
+                _capabilities |= FLAG_PASSTHROUGH_ATTRIBUTE_MAP_SET;
+            }
+        }
+        return _passthroughAttributesMap;
+    }
+
     /**
      * Return the number of direct child components this component has.
      * <p>
@@ -1922,12 +1961,12 @@ public abstract class UIComponentBase ex
             
             if (facesListenersSaved == null && stateHelperSaved == null && 
                 behaviorsMapSaved == null && systemEventListenerClassMapSaved == null &&
-               !_isRendererTypeSet)
+               !((_capabilities & FLAG_IS_RENDERER_TYPE_SET) != 0))
             {
                 return null;
             }
             
-            if (_isRendererTypeSet)
+            if ((_capabilities & FLAG_IS_RENDERER_TYPE_SET) != 0)
             {
                 return new Object[] {facesListenersSaved, stateHelperSaved, behaviorsMapSaved,
                                     systemEventListenerClassMapSaved, 
@@ -1942,7 +1981,7 @@ public abstract class UIComponentBase ex
         else
         {
             //Full
-            Object values[] = new Object[11];
+            Object values[] = new Object[9];
             values[0] = saveFacesListenersList(context);
             StateHelper stateHelper = getStateHelper(false);
             if (stateHelper != null)
@@ -1955,9 +1994,10 @@ public abstract class UIComponentBase ex
             values[5] = _clientId;
             values[6] = _markCreated;
             values[7] = _rendererType;
-            values[8] = _isRendererTypeSet;
-            values[9] = _addedByHandler;
-            values[10] = _facetCreatedUIPanel;
+            values[8] = _capabilities;
+            //values[8] = _isRendererTypeSet;
+            //values[9] = _addedByHandler;
+            //values[10] = _facetCreatedUIPanel;
 
             return values;
         }
@@ -1993,7 +2033,7 @@ public abstract class UIComponentBase ex
         
         Object values[] = (Object[]) state;
         
-        if ( values.length == 11 && initialStateMarked())
+        if ( values.length == 9 && initialStateMarked())
         {
             //Delta mode is active, but we are restoring a full state.
             //we need to clear the initial state, to restore state without
@@ -2011,7 +2051,7 @@ public abstract class UIComponentBase ex
                         ((_AttachedDeltaWrapper) values[0]).getWrappedStateObject());
             //}
         }
-        else if (values[0] != null || (values.length == 11))
+        else if (values[0] != null || (values.length == 9))
         {
             //Full
             _facesListeners = (_DeltaList<FacesListener>)
@@ -2024,26 +2064,28 @@ public abstract class UIComponentBase ex
         
         getStateHelper().restoreState(context, values[1]);
         
-        if (values.length == 11)
+        if (values.length == 9)
         {
             _id = (String) values[4];
             _clientId = (String) values[5];
             _markCreated = (String) values[6];
             _rendererType = (String) values[7];
-            _isRendererTypeSet = (Boolean) values[8];
-            _addedByHandler = (Boolean) values[9];
-            _facetCreatedUIPanel = (Boolean) values[10];
+            _capabilities = (Integer) values[8];
+            //_isRendererTypeSet = (Boolean) values[8];
+            //_addedByHandler = (Boolean) values[9];
+            //_facetCreatedUIPanel = (Boolean) values[10];
         }
         else if (values.length == 5)
         {
             _rendererType = (String) values[4];
-            _isRendererTypeSet = true;
+            //_isRendererTypeSet = true;
+            _capabilities |= FLAG_IS_RENDERER_TYPE_SET;
         }
 
         // rendererType needs to be restored before SystemEventListener,
         // otherwise UIComponent.getCurrentComponent(context).getRenderer(context)
         // will not work correctly
-        if (values.length == 11)
+        if (values.length == 9)
         {
             //Full restore
             restoreFullBehaviorsMap(context, values[2]);
@@ -2440,22 +2482,38 @@ public abstract class UIComponentBase ex
     
     boolean isOamVfAddedByHandler()
     {
-        return _addedByHandler;
+        return (_capabilities & FLAG_ADDED_BY_HANDLER) != 0;
     }
     
     void setOamVfAddedByHandler(boolean addedByHandler)
     {
-        _addedByHandler = addedByHandler;
+        if (addedByHandler)
+        {
+            _capabilities |= FLAG_ADDED_BY_HANDLER;
+        }
+        else
+        {
+            _capabilities &= ~(FLAG_ADDED_BY_HANDLER);
+        }
+        //_addedByHandler = addedByHandler;
     }
     
     boolean isOamVfFacetCreatedUIPanel()
     {
-        return _facetCreatedUIPanel;
+        return (_capabilities & FLAG_FACET_CREATED_UIPANEL) != 0;
     }
     
     void setOamVfFacetCreatedUIPanel(boolean facetCreatedUIPanel)
     {
-        _facetCreatedUIPanel = facetCreatedUIPanel;
+        //_facetCreatedUIPanel = facetCreatedUIPanel;
+        if (facetCreatedUIPanel)
+        {
+            _capabilities |= FLAG_FACET_CREATED_UIPANEL;
+        }
+        else
+        {
+            _capabilities &= ~(FLAG_FACET_CREATED_UIPANEL);
+        }
     }
 
 /**
@@ -2537,7 +2595,8 @@ public abstract class UIComponentBase ex
         {
             //This flag just indicates the rendererType 
             //should be included on the delta
-            this._isRendererTypeSet = true;
+            //this._isRendererTypeSet = true;
+            _capabilities |= FLAG_IS_RENDERER_TYPE_SET;
         }
         setCachedRenderer(null);
     }

Added: myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/component/_PassThroughAttributesMap.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/component/_PassThroughAttributesMap.java?rev=1438771&view=auto
==============================================================================
--- myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/component/_PassThroughAttributesMap.java (added)
+++ myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/component/_PassThroughAttributesMap.java Fri Jan 25 23:44:45 2013
@@ -0,0 +1,145 @@
+/*
+ * 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 javax.faces.component;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+class _PassThroughAttributesMap implements Map<String, Object>, Serializable
+{
+    private static final long serialVersionUID = -9106932179394257866L;
+    
+    private UIComponentBase _component;
+    
+    _PassThroughAttributesMap(UIComponentBase component)
+    {
+        _component = component;
+    }
+
+    
+    /**
+     * Return the map containing the attributes.
+     * <p/>
+     * This method is package-scope so that the UIComponentBase class can access it
+     * directly when serializing the component.
+     */
+    Map<String, Object> getUnderlyingMap()
+    {
+        StateHelper stateHelper = _component.getStateHelper(false);
+        Map<String, Object> attributes = null;
+        if (stateHelper != null)
+        {
+            attributes = (Map<String, Object>) stateHelper.get(UIComponentBase.PropertyKeys.passThroughAttributesMap);
+        }
+        return attributes == null ? Collections.EMPTY_MAP : attributes;
+    }
+    
+    /**
+     * TODO: Document why this method is necessary, and why it doesn't try to
+     * compare the _component field.
+     */
+    @Override
+    public boolean equals(Object obj)
+    {
+        return getUnderlyingMap().equals(obj);
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return getUnderlyingMap().hashCode();
+    }
+
+    public int size()
+    {
+        return getUnderlyingMap().size();
+    }
+
+    public boolean isEmpty()
+    {
+        return getUnderlyingMap().isEmpty();
+    }
+
+    public boolean containsKey(Object key)
+    {
+        return getUnderlyingMap().containsKey(key);
+    }
+
+    public boolean containsValue(Object value)
+    {
+        return getUnderlyingMap().containsValue(value);
+    }
+
+    public Object get(Object key)
+    {
+        return getUnderlyingMap().get(key);
+    }
+
+    public Object put(String key, Object value)
+    {
+        return getUnderlyingMap().put(key, value);
+    }
+
+    public Object remove(Object key)
+    {
+        return getUnderlyingMap().remove(key);
+    }
+
+    /**
+     * Call put(key, value) for each entry in the provided map.
+     */
+    public void putAll(Map<? extends String, ?> t)
+    {
+        for (Map.Entry<? extends String, ?> entry : t.entrySet())
+        {
+            put(entry.getKey(), entry.getValue());
+        }
+    }
+
+    /**
+     * Return a set of all <i>attributes</i>. Properties of the underlying
+     * UIComponent are not included, nor value-bindings.
+     */
+    public Set<Map.Entry<String, Object>> entrySet()
+    {
+        return getUnderlyingMap().entrySet();
+    }
+
+    public Set<String> keySet()
+    {
+        return getUnderlyingMap().keySet();
+    }
+
+    public void clear()
+    {
+        getUnderlyingMap().clear();
+    }
+
+    public Collection<Object> values()
+    {
+        return getUnderlyingMap().values();
+    }
+}

Propchange: myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/component/_PassThroughAttributesMap.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/context/ResponseWriter.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/context/ResponseWriter.java?rev=1438771&r1=1438770&r2=1438771&view=diff
==============================================================================
--- myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/context/ResponseWriter.java (original)
+++ myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/context/ResponseWriter.java Fri Jan 25 23:44:45 2013
@@ -74,4 +74,24 @@ public abstract class ResponseWriter ext
     {
         writeText(object, string);
     }
+
+    /**
+     * @since 2.2
+     * @param preamble
+     * @throws IOException 
+     */
+    public void writePreamble(String preamble) throws IOException 
+    {
+        write(preamble);
+    }
+
+    /**
+     * @since 2.2
+     * @param doctype
+     * @throws IOException 
+     */
+    public void writeDoctype(String doctype) throws IOException
+    {
+        write(doctype);
+    }
 }

Modified: myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/render/Renderer.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/render/Renderer.java?rev=1438771&r1=1438770&r2=1438771&view=diff
==============================================================================
--- myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/render/Renderer.java (original)
+++ myfaces/core/branches/2.2.x/api/src/main/java/javax/faces/render/Renderer.java Fri Jan 25 23:44:45 2013
@@ -32,6 +32,11 @@ import javax.faces.convert.ConverterExce
  */
 public abstract class Renderer
 {
+    /**
+     * @since 2.2
+     */
+    public static final String PASSTHROUGH_RENDERER_LOCALNAME_KEY = "elementName";
+    
     public void decode(FacesContext context, UIComponent component)
     {
         if (context == null)

Modified: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/UILeaf.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/UILeaf.java?rev=1438771&r1=1438770&r2=1438771&view=diff
==============================================================================
--- myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/UILeaf.java (original)
+++ myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/UILeaf.java Fri Jan 25 23:44:45 2013
@@ -753,4 +753,25 @@ class UILeaf extends UIComponent impleme
         return _attributes;
     }
 
+    @Override
+    public Map<String, Object> getPassThroughAttributes()
+    {
+        return getPassThroughAttributes(true);
+    }
+
+    @Override
+    public Map<String, Object> getPassThroughAttributes(boolean create)
+    {
+        if (create)
+        {
+            // Just return an empty map, because UILeaf cannot contain
+            // passthrough attributes.
+            return Collections.emptyMap();
+        }
+        else
+        {
+            return null;
+        }
+    }
+
 }

Copied: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/PassThroughAttributeHandler.java (from r1433611, myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/AttributeHandler.java)
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/PassThroughAttributeHandler.java?p2=myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/PassThroughAttributeHandler.java&p1=myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/AttributeHandler.java&r1=1433611&r2=1438771&rev=1438771&view=diff
==============================================================================
--- myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/AttributeHandler.java (original)
+++ myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/PassThroughAttributeHandler.java Fri Jan 25 23:44:45 2013
@@ -33,20 +33,13 @@ import javax.faces.view.facelets.TagHand
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
 
 /**
- * Sets the specified name and attribute on the parent UIComponent. If the "value" specified is not a literal, it will
- * instead set the ValueExpression on the UIComponent. <p /> See <a target="_new"
- * href="http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/tlddocs/f/attribute.html">tag documentation</a>.
  * 
- * @see javax.faces.component.UIComponent#getAttributes()
- * @see javax.faces.component.UIComponent#setValueExpression(java.lang.String, javax.el.ValueExpression)
- * @author Jacob Hookom
- * @version $Id$
+ * @author Leonardo Uribe
  */
 @JSFFaceletTag(
-        name = "f:attribute",
-        bodyContent = "empty", 
-        tagClass="org.apache.myfaces.taglib.core.AttributeTag")
-public final class AttributeHandler extends TagHandler
+        name = "f:passThroughAttribute",
+        bodyContent = "empty")
+public final class PassThroughAttributeHandler extends TagHandler
     implements javax.faces.view.facelets.AttributeHandler
 {
     private final TagAttribute _name;
@@ -56,7 +49,7 @@ public final class AttributeHandler exte
     /**
      * @param config
      */
-    public AttributeHandler(TagConfig config)
+    public PassThroughAttributeHandler(TagConfig config)
     {
         super(config);
         _name = getRequiredAttribute("name");
@@ -80,16 +73,13 @@ public final class AttributeHandler exte
         if (parent.getParent() == null)
         {
             String n = _name.getValue(ctx);
-            if (!parent.getAttributes().containsKey(n))
+            if (_value.isLiteral())
             {
-                if (_value.isLiteral())
-                {
-                    parent.getAttributes().put(n, _value.getValue());
-                }
-                else
-                {
-                    parent.setValueExpression(n, _value.getValueExpression(ctx, Object.class));
-                }
+                parent.getPassThroughAttributes().put(n, _value.getValue());
+            }
+            else
+            {
+                parent.getPassThroughAttributes().put(n, _value.getValueExpression(ctx, Object.class));
             }
         }
     }

Added: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/PassThroughAttributesHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/PassThroughAttributesHandler.java?rev=1438771&view=auto
==============================================================================
--- myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/PassThroughAttributesHandler.java (added)
+++ myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/PassThroughAttributesHandler.java Fri Jan 25 23:44:45 2013
@@ -0,0 +1,67 @@
+/*
+ * 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.jsf.core;
+
+import java.io.IOException;
+import java.util.Map;
+import javax.faces.component.UIComponent;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.TagAttribute;
+import javax.faces.view.facelets.TagConfig;
+import javax.faces.view.facelets.TagException;
+import javax.faces.view.facelets.TagHandler;
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
+
+/**
+ *
+ * @since 2.2
+ * @author Leonardo Uribe
+ */
+@JSFFaceletTag(
+        name = "f:passThroughAttributes",
+        bodyContent = "empty")
+public final class PassThroughAttributesHandler extends TagHandler 
+{
+    private final TagAttribute _value;
+    
+    public PassThroughAttributesHandler(TagConfig config)
+    {
+        super(config);
+        _value = getRequiredAttribute("value");
+    }
+
+    public void apply(FaceletContext ctx, UIComponent parent) throws IOException
+    {
+        if (parent == null)
+        {
+            throw new TagException(this.tag, "Parent UIComponent was null");
+        }
+
+        // only process if the parent is new to the tree
+        if (parent.getParent() == null)
+        {
+            Map<String, Object> map = (Map<String, Object>) _value.getObject(ctx, Map.class);
+
+            for (Map.Entry<String, Object> entry : map.entrySet())
+            {
+                parent.getPassThroughAttributes().put(entry.getKey(), entry.getValue());
+            }
+        }
+    }
+}

Propchange: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/PassThroughAttributesHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native