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 2010/06/02 05:45:22 UTC

svn commit: r950357 - in /myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets: ./ compiler/ impl/ tag/ tag/composite/

Author: lu4242
Date: Wed Jun  2 03:45:21 2010
New Revision: 950357

URL: http://svn.apache.org/viewvc?rev=950357&view=rev
Log:
MYFACES-2638 Fix PostAddToViewEvent and PreRemoveFromViewEvent publishing conditions (fix facets problem)

Added:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompositeComponentUnit.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentDefinitionTagHandler.java
Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/AbstractFacelet.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletFactory.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompilationManager.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/Compiler.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/SAXCompiler.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFacelet.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletFactory.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/TagHandlerUtils.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentResourceTagHandler.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/ImplementationHandler.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/InsertChildrenHandler.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/InsertFacetHandler.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/InterfaceHandler.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/RenderFacetHandler.java

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/AbstractFacelet.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/AbstractFacelet.java?rev=950357&r1=950356&r2=950357&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/AbstractFacelet.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/AbstractFacelet.java Wed Jun  2 03:45:21 2010
@@ -93,4 +93,6 @@ public abstract class AbstractFacelet ex
     
     public abstract void applyCompositeComponent(AbstractFaceletContext ctx, UIComponent parent, Resource resource) throws IOException, FacesException,
             FaceletException, ELException;
+    
+    public abstract boolean isBuildingCompositeComponentMetadata();
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletFactory.java?rev=950357&r1=950356&r2=950357&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletFactory.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletFactory.java Wed Jun  2 03:45:21 2010
@@ -92,6 +92,34 @@ public abstract class FaceletFactory
      * @throws ELException
      */
     public abstract Facelet getViewMetadataFacelet(URL url) throws IOException, FaceletException, FacesException, ELException;
+
+    /**
+     * Return a Facelet instance as specified by the file at the passed URI. The returned facelet is used
+     * to create composite component metadata.
+     * <p>
+     * This method should be called from vdl.getComponentMetadata(FacesContext context)  
+     * </p>
+     * 
+     * @since 2.0.1
+     * @param uri
+     * @return
+     * @throws IOException
+     */
+    public abstract Facelet getCompositeComponentMetadataFacelet(String uri) throws IOException;
+    
+    /**
+     * Create a Facelet used to create composite component metadata from the passed URL. This method checks if the 
+     * cached Facelet needs to be refreshed before returning. If so, uses the passed URL to build a new instance.
+     * 
+     * @since 2.0.1
+     * @param url source url
+     * @return Facelet instance
+     * @throws IOException
+     * @throws FaceletException
+     * @throws FacesException
+     * @throws ELException
+     */
+    public abstract Facelet getCompositeComponentMetadataFacelet(URL url) throws IOException, FaceletException, FacesException, ELException;
     
     /**
      * Set the static instance

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java?rev=950357&r1=950356&r2=950357&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java Wed Jun  2 03:45:21 2010
@@ -57,13 +57,11 @@ import javax.faces.context.ExternalConte
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 import javax.faces.event.ActionEvent;
-import javax.faces.event.ActionListener;
 import javax.faces.event.MethodExpressionActionListener;
 import javax.faces.event.MethodExpressionValueChangeListener;
 import javax.faces.event.PhaseId;
 import javax.faces.event.PreRemoveFromViewEvent;
 import javax.faces.event.ValueChangeEvent;
-import javax.faces.event.ValueChangeListener;
 import javax.faces.render.RenderKit;
 import javax.faces.validator.MethodExpressionValidator;
 import javax.faces.view.ActionSource2AttachedObjectHandler;
@@ -100,8 +98,6 @@ import org.apache.myfaces.view.facelets.
 import org.apache.myfaces.view.facelets.compiler.TagLibraryConfig;
 import org.apache.myfaces.view.facelets.el.LocationMethodExpression;
 import org.apache.myfaces.view.facelets.el.LocationValueExpression;
-import org.apache.myfaces.view.facelets.el.TagMethodExpression;
-import org.apache.myfaces.view.facelets.el.TagValueExpression;
 import org.apache.myfaces.view.facelets.el.VariableMapperWrapper;
 import org.apache.myfaces.view.facelets.impl.DefaultFaceletFactory;
 import org.apache.myfaces.view.facelets.impl.DefaultResourceResolver;
@@ -198,7 +194,7 @@ public class FaceletViewDeclarationLangu
     public final static String FILLED_VIEW = "org.apache.myfaces.FILLED_VIEW";
     
     //BEGIN CONSTANTS SET ON BUILD VIEW
-    public final static String BUILDING_COMPOSITE_COMPONENT_METADATA = "org.apache.myfaces.BUILDING_COMPOSITE_COMPONENT_METADATA";
+    //public final static String BUILDING_COMPOSITE_COMPONENT_METADATA = "org.apache.myfaces.BUILDING_COMPOSITE_COMPONENT_METADATA";
     
     public final static String BUILDING_VIEW_METADATA = "org.apache.myfaces.BUILDING_VIEW_METADATA";
     
@@ -494,13 +490,13 @@ public class FaceletViewDeclarationLangu
             FaceletFactory.setInstance(_faceletFactory);
             try
             {
-                compositeComponentFacelet = _faceletFactory.getFacelet(componentResource.getURL());
+                compositeComponentFacelet = _faceletFactory.getCompositeComponentMetadataFacelet(componentResource.getURL());
             }
             finally
             {
                 FaceletFactory.setInstance(null);
             }
-            context.getAttributes().put(BUILDING_COMPOSITE_COMPONENT_METADATA, Boolean.TRUE);
+            //context.getAttributes().put(BUILDING_COMPOSITE_COMPONENT_METADATA, Boolean.TRUE);
             
             // Create a temporal tree where all components will be put, but we are only
             // interested in metadata.
@@ -535,10 +531,10 @@ public class FaceletViewDeclarationLangu
         {
             throw new FacesException(e);
         }
-        finally
-        {
-            context.getAttributes().remove(BUILDING_COMPOSITE_COMPONENT_METADATA);
-        }
+        //finally
+        //{
+            //context.getAttributes().remove(BUILDING_COMPOSITE_COMPONENT_METADATA);
+        //}
         
         return beanInfo;
     }
@@ -549,10 +545,10 @@ public class FaceletViewDeclarationLangu
      * @param context
      * @return
      */
-    public static boolean isBuildingCompositeComponentMetadata(FacesContext context)
-    {
-        return context.getAttributes().containsKey(BUILDING_COMPOSITE_COMPONENT_METADATA);
-    }
+    //public static boolean isBuildingCompositeComponentMetadata(FacesContext context)
+    //{
+    //    return context.getAttributes().containsKey(BUILDING_COMPOSITE_COMPONENT_METADATA);
+    //}
     
     /**
      * Check if the current facelet applied is used to build view metadata.

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompilationManager.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompilationManager.java?rev=950357&r1=950356&r2=950357&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompilationManager.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompilationManager.java Wed Jun  2 03:45:21 2010
@@ -243,7 +243,11 @@ final class CompilationManager
             //   there is some code that found the right component in the temporal tree to add the
             //   generated BeanInfo, which it is retrieved later.
             //
+            // After use Template Client API for composite components, it was found the need to
+            // gather metadata information from 
             log.fine("Composite Component Interface Found, saving unit");
+            CompositeComponentUnit compositeRootCompilationUnit = new CompositeComponentUnit();
+            this.startUnit(compositeRootCompilationUnit);
             interfaceCompilationUnit = new TagUnit(this.tagLibrary, qname[0], qname[1], t, this.nextTagId());
             this.startUnit(interfaceCompilationUnit);
         }        
@@ -253,6 +257,8 @@ final class CompilationManager
             this.units.clear();
             NamespaceUnit nsUnit = this.namespaceManager.toNamespaceUnit(this.tagLibrary);
             this.units.push(nsUnit);
+            CompositeComponentUnit compositeRootCompilationUnit = new CompositeComponentUnit();
+            this.startUnit(compositeRootCompilationUnit);
             if (interfaceCompilationUnit != null)
             {
                 this.currentUnit().addChild(interfaceCompilationUnit);
@@ -320,6 +326,11 @@ final class CompilationManager
                 return;
             }
         }
+        else if (unit instanceof CompositeComponentUnit)
+        {
+            this.finished = true;
+            return;
+        }
 
         this.finishUnit();
     }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/Compiler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/Compiler.java?rev=950357&r1=950356&r2=950357&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/Compiler.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/Compiler.java Wed Jun  2 03:45:21 2010
@@ -125,6 +125,14 @@ public abstract class Compiler
             this.initialize();
         return this.doCompileViewMetadata(src, alias);
     }
+    
+    public final FaceletHandler compileCompositeComponentMetadata(URL src, String alias) throws IOException, FaceletException, ELException,
+            FacesException
+    {
+        if (!this.initialized)
+            this.initialize();
+        return this.doCompileCompositeComponentMetadata(src, alias);
+    }
 
     protected abstract FaceletHandler doCompile(URL src, String alias) throws IOException, FaceletException,
             ELException, FacesException;
@@ -132,6 +140,9 @@ public abstract class Compiler
     protected abstract FaceletHandler doCompileViewMetadata(URL src, String alias) throws IOException, FaceletException,
             ELException, FacesException;
     
+    protected abstract FaceletHandler doCompileCompositeComponentMetadata(URL src, String alias) throws IOException, FaceletException,
+            ELException, FacesException;
+    
     public final TagDecorator createTagDecorator()
     {
         if (this.decorators.size() > 0)

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompositeComponentUnit.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompositeComponentUnit.java?rev=950357&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompositeComponentUnit.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/CompositeComponentUnit.java Wed Jun  2 03:45:21 2010
@@ -0,0 +1,44 @@
+/*
+ * 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.compiler;
+
+import javax.faces.view.facelets.FaceletHandler;
+
+import org.apache.myfaces.view.facelets.tag.composite.CompositeComponentDefinitionTagHandler;
+
+/**
+ * This compilation unit is used to wrap cc:interface and cc:implementation in
+ * a base handler, to allow proper handling of composite component metadata.
+ * 
+ * @author Leonardo Uribe (latest modification by $Author: lu4242 $)
+ * @version $Revision: 945454 $ $Date: 2010-05-17 20:40:21 -0500 (Lun, 17 May 2010) $
+ */
+class CompositeComponentUnit extends CompilationUnit
+{
+
+    public CompositeComponentUnit()
+    {
+    }
+
+    public FaceletHandler createFaceletHandler()
+    {
+        return new CompositeComponentDefinitionTagHandler(this.getNextFaceletHandler());
+    }
+
+}

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/SAXCompiler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/SAXCompiler.java?rev=950357&r1=950356&r2=950357&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/SAXCompiler.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/SAXCompiler.java Wed Jun  2 03:45:21 2010
@@ -40,6 +40,9 @@ import javax.xml.parsers.SAXParserFactor
 import org.apache.myfaces.shared_impl.util.ClassUtils;
 import org.apache.myfaces.view.facelets.tag.TagAttributeImpl;
 import org.apache.myfaces.view.facelets.tag.TagAttributesImpl;
+import org.apache.myfaces.view.facelets.tag.composite.CompositeLibrary;
+import org.apache.myfaces.view.facelets.tag.composite.ImplementationHandler;
+import org.apache.myfaces.view.facelets.tag.composite.InterfaceHandler;
 import org.apache.myfaces.view.facelets.tag.jsf.core.CoreLibrary;
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
@@ -427,6 +430,229 @@ public final class SAXCompiler extends C
         }        
     }
     
+    /**
+     * Like CompilationHandler but does not take into account everything outside cc:interface or cc:implementation tag.
+     *  
+     * Note inside cc:implementation it only takes into account cc:insertChildren, cc:insertFacet and cc:renderFacet,
+     * all other tags, comments or text are just skipped.
+     * 
+     * @since 2.0.1
+     */
+    private static class CompositeComponentMetadataHandler extends DefaultHandler implements LexicalHandler
+    {
+
+        private final String alias;
+
+        private boolean inDocument = false;
+
+        private Locator locator;
+
+        private final CompilationManager unit;
+        
+        private boolean inCompositeInterface = false;
+        
+        private boolean inCompositeImplementation = false;
+
+        public CompositeComponentMetadataHandler(CompilationManager unit, String alias)
+        {
+            this.unit = unit;
+            this.alias = alias;
+        }
+
+        public void characters(char[] ch, int start, int length) throws SAXException
+        {
+            if (this.inDocument && inCompositeInterface)
+            {
+                this.unit.writeText(new String(ch, start, length));
+            }
+        }
+
+        public void comment(char[] ch, int start, int length) throws SAXException
+        {
+            if (this.inDocument && inCompositeInterface)
+            {
+                this.unit.writeComment(new String(ch, start, length));
+            }
+        }
+
+        protected TagAttributes createAttributes(Attributes attrs)
+        {
+            int len = attrs.getLength();
+            TagAttribute[] ta = new TagAttribute[len];
+            for (int i = 0; i < len; i++)
+            {
+                ta[i] = new TagAttributeImpl(this.createLocation(), attrs.getURI(i), attrs.getLocalName(i), attrs
+                        .getQName(i), attrs.getValue(i));
+            }
+            return new TagAttributesImpl(ta);
+        }
+
+        protected Location createLocation()
+        {
+            return new Location(this.alias, this.locator.getLineNumber(), this.locator.getColumnNumber());
+        }
+
+        public void endCDATA() throws SAXException
+        {
+            if (this.inDocument && inCompositeInterface)
+            {
+                this.unit.writeInstruction("]]>");
+            }
+        }
+
+        public void endDocument() throws SAXException
+        {
+            super.endDocument();
+        }
+
+        public void endDTD() throws SAXException
+        {
+            this.inDocument = true;
+        }
+
+        public void endElement(String uri, String localName, String qName) throws SAXException
+        {
+            if (inCompositeInterface)
+            {
+                this.unit.popTag();
+            }
+            else if (inCompositeImplementation && CompositeLibrary.NAMESPACE.equals(uri))
+            {
+                if ( "insertFacet".equals(localName) ||
+                     "renderFacet".equals(localName) ||
+                     "insertChildren".equals(localName) || 
+                     ImplementationHandler.NAME.equals(localName))
+                {
+                    this.unit.popTag();
+                }
+            }
+            
+            if (CompositeLibrary.NAMESPACE.equals(uri))
+            {
+                if (InterfaceHandler.NAME.equals(localName))
+                {
+                    this.inCompositeInterface=false;
+                }
+                else if (ImplementationHandler.NAME.equals(localName))
+                {
+                    this.inCompositeImplementation=false;
+                }
+            }
+        }
+
+        public void endEntity(String name) throws SAXException
+        {
+        }
+
+        public void endPrefixMapping(String prefix) throws SAXException
+        {
+            this.unit.popNamespace(prefix);
+        }
+
+        public void fatalError(SAXParseException e) throws SAXException
+        {
+            if (this.locator != null)
+            {
+                throw new SAXException("Error Traced[line: " + this.locator.getLineNumber() + "] " + e.getMessage());
+            }
+            else
+            {
+                throw e;
+            }
+        }
+
+        public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
+        {
+            if (this.inDocument && inCompositeInterface)
+            {
+                this.unit.writeWhitespace(new String(ch, start, length));
+            }
+        }
+
+        public InputSource resolveEntity(String publicId, String systemId) throws SAXException
+        {
+            String dtd = "org/apache/myfaces/resource/default.dtd";
+            /*
+             * if ("-//W3C//DTD XHTML 1.0 Transitional//EN".equals(publicId)) { dtd = "xhtml1-transitional.dtd"; } else
+             * if (systemId != null && systemId.startsWith("file:/")) { return new InputSource(systemId); }
+             */
+            URL url = ClassUtils.getContextClassLoader().getResource(dtd);
+            return new InputSource(url.toString());
+        }
+
+        public void setDocumentLocator(Locator locator)
+        {
+            this.locator = locator;
+        }
+
+        public void startCDATA() throws SAXException
+        {
+            if (this.inDocument && inCompositeInterface)
+            {
+                this.unit.writeInstruction("<![CDATA[");
+            }
+        }
+
+        public void startDocument() throws SAXException
+        {
+            this.inDocument = true;
+        }
+
+        public void startDTD(String name, String publicId, String systemId) throws SAXException
+        {
+            // metadata does not require output doctype
+            this.inDocument = false;
+        }
+
+        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
+        {
+            if (CompositeLibrary.NAMESPACE.equals(uri))
+            {
+                if (InterfaceHandler.NAME.equals(localName))
+                {
+                    this.inCompositeInterface=true;
+                }
+                else if (ImplementationHandler.NAME.equals(localName))
+                {
+                    this.inCompositeImplementation=true;
+                }
+            }
+            
+            if (inCompositeInterface)
+            {
+                this.unit.pushTag(new Tag(this.createLocation(), uri, localName, qName, this.createAttributes(attributes)));
+            }
+            else if (inCompositeImplementation && CompositeLibrary.NAMESPACE.equals(uri))
+            {
+                if ("insertFacet".equals(localName)    ||
+                    "renderFacet".equals(localName)    ||
+                    "insertChildren".equals(localName) ||
+                    ImplementationHandler.NAME.equals(localName)   )
+                {
+                    this.unit.pushTag(new Tag(this.createLocation(), uri, localName, qName, this.createAttributes(attributes)));
+                }
+            }
+        }
+
+        public void startEntity(String name) throws SAXException
+        {
+        }
+
+        public void startPrefixMapping(String prefix, String uri) throws SAXException
+        {
+            this.unit.pushNamespace(prefix, uri);
+        }
+
+        public void processingInstruction(String target, String data) throws SAXException
+        {
+            if (this.inDocument && inCompositeInterface)
+            {
+                StringBuffer sb = new StringBuffer(64);
+                sb.append("<?").append(target).append(' ').append(data).append("?>\n");
+                this.unit.writeInstruction(sb.toString());
+            }
+        }        
+    }
 
     public SAXCompiler()
     {
@@ -501,7 +727,44 @@ public final class SAXCompiler extends C
             }
         }
         return new EncodingHandler(mngr.createFaceletHandler(), encoding);
-    }    
+    }
+
+    /**
+     * @since 2.0.1
+     */
+    @Override
+    protected FaceletHandler doCompileCompositeComponentMetadata(URL src, String alias)
+            throws IOException, FaceletException, ELException, FacesException
+    {
+        CompilationManager mngr = null;
+        InputStream is = null;
+        String encoding = null;
+        try
+        {
+            is = new BufferedInputStream(src.openStream(), 1024);
+            mngr = new CompilationManager(alias, this);
+            encoding = getXmlDecl(is, mngr);
+            CompositeComponentMetadataHandler handler = new CompositeComponentMetadataHandler(mngr, alias);
+            SAXParser parser = this.createSAXParser(handler);
+            parser.parse(is, handler);
+        }
+        catch (SAXException e)
+        {
+            throw new FaceletException("Error Parsing " + alias + ": " + e.getMessage(), e.getCause());
+        }
+        catch (ParserConfigurationException e)
+        {
+            throw new FaceletException("Error Configuring Parser " + alias + ": " + e.getMessage(), e.getCause());
+        }
+        finally
+        {
+            if (is != null)
+            {
+                is.close();
+            }
+        }
+        return new EncodingHandler(mngr.createFaceletHandler(), encoding);
+    }
 
     protected static final String writeXmlDecl(InputStream is, CompilationManager mngr) throws IOException
     {

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFacelet.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFacelet.java?rev=950357&r1=950356&r2=950357&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFacelet.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFacelet.java Wed Jun  2 03:45:21 2010
@@ -81,6 +81,8 @@ final class DefaultFacelet extends Abstr
 
     private final URL _src;
 
+    private final boolean _isBuildingCompositeComponentMetadata; 
+
     public DefaultFacelet(DefaultFaceletFactory factory, ExpressionFactory el, URL src, String alias,
                           FaceletHandler root)
     {
@@ -92,7 +94,22 @@ final class DefaultFacelet extends Abstr
         _createTime = System.currentTimeMillis();
         _refreshPeriod = _factory.getRefreshPeriod();
         _relativePaths = new WeakHashMap<String, URL>();
+        _isBuildingCompositeComponentMetadata = false;
     }
+    
+    public DefaultFacelet(DefaultFaceletFactory factory, ExpressionFactory el, URL src, String alias,
+            FaceletHandler root, boolean isBuildingCompositeComponentMetadata)
+    {
+        _factory = factory;
+        _elFactory = el;
+        _src = src;
+        _root = root;
+        _alias = alias;
+        _createTime = System.currentTimeMillis();
+        _refreshPeriod = _factory.getRefreshPeriod();
+        _relativePaths = new WeakHashMap<String, URL>();
+        _isBuildingCompositeComponentMetadata = isBuildingCompositeComponentMetadata;
+    }    
 
     /**
      * @see org.apache.myfaces.view.facelets.Facelet#apply(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
@@ -418,4 +435,10 @@ final class DefaultFacelet extends Abstr
     {
         return _alias;
     }
+
+    @Override
+    public boolean isBuildingCompositeComponentMetadata()
+    {
+        return _isBuildingCompositeComponentMetadata;
+    }
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java?rev=950357&r1=950356&r2=950357&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java Wed Jun  2 03:45:21 2010
@@ -46,7 +46,6 @@ import javax.faces.view.facelets.Facelet
 import org.apache.myfaces.view.facelets.AbstractFacelet;
 import org.apache.myfaces.view.facelets.AbstractFaceletContext;
 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
-import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage;
 import org.apache.myfaces.view.facelets.TemplateClient;
 import org.apache.myfaces.view.facelets.TemplateContext;
 import org.apache.myfaces.view.facelets.TemplateManager;
@@ -83,8 +82,6 @@ final class DefaultFaceletContext extend
     private final StringBuilder _uniqueIdBuilder = new StringBuilder(30);
 
     //private final LinkedList<TemplateManager> _clients;
-
-    private final boolean _isBuildingCompositeComponentMetadata;
     
     private final FaceletCompositionContext _mctx;
     
@@ -109,7 +106,6 @@ final class DefaultFaceletContext extend
         _faceletHierarchy.addAll(ctx._faceletHierarchy);
         _faceletHierarchy.add(facelet);
         _facelet = facelet;
-        _isBuildingCompositeComponentMetadata = ctx._isBuildingCompositeComponentMetadata;
         _mctx = ctx._mctx;
         
         if (ccWrap)
@@ -155,8 +151,6 @@ final class DefaultFaceletContext extend
         _faceletHierarchy = new ArrayList<AbstractFacelet>(1);
         _faceletHierarchy.add(facelet);
         _facelet = facelet;
-        _isBuildingCompositeComponentMetadata = FaceletViewDeclarationLanguage.
-            isBuildingCompositeComponentMetadata(faces);
         _mctx = mctx;
         
         _isolatedTemplateContext = new ArrayList<TemplateContext>(1);
@@ -719,7 +713,7 @@ final class DefaultFaceletContext extend
     @Override
     public boolean isBuildingCompositeComponentMetadata()
     {
-        return _isBuildingCompositeComponentMetadata;
+        return _facelet.isBuildingCompositeComponentMetadata();
     }
     
     public FaceletCompositionContext getFaceletCompositionContext()

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletFactory.java?rev=950357&r1=950356&r2=950357&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletFactory.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletFactory.java Wed Jun  2 03:45:21 2010
@@ -60,6 +60,8 @@ public final class DefaultFaceletFactory
     private Map<String, DefaultFacelet> _facelets;
     
     private Map<String, DefaultFacelet> _viewMetadataFacelets;
+    
+    private Map<String, DefaultFacelet> _compositeComponentMetadataFacelets;
 
     private long _refreshPeriod;
 
@@ -82,6 +84,8 @@ public final class DefaultFaceletFactory
         _facelets = new HashMap<String, DefaultFacelet>();
         
         _viewMetadataFacelets = new HashMap<String, DefaultFacelet>();
+        
+        _compositeComponentMetadataFacelets = new HashMap<String, DefaultFacelet>();
 
         _relativeLocations = new HashMap<String, URL>();
 
@@ -314,6 +318,37 @@ public final class DefaultFaceletFactory
         }
 
     }
+    
+    /**
+     * @since 2.0.1
+     * @param url
+     * @return
+     * @throws IOException
+     * @throws FaceletException
+     * @throws FacesException
+     * @throws ELException
+     */
+    private DefaultFacelet _createCompositeComponentMetadataFacelet(URL url) throws IOException, FaceletException, FacesException, ELException
+    {
+        if (log.isLoggable(Level.FINE))
+        {
+            log.fine("Creating Facelet used to create Composite Component Metadata for: " + url);
+        }
+
+        // The alias is used later for informative purposes, so we append 
+        // some prefix to identify later where the errors comes from.
+        String alias = "/compositeComponentMetadata/" + url.getFile().replaceFirst(_baseUrl.getFile(), "");
+        try
+        {
+            FaceletHandler h = _compiler.compileCompositeComponentMetadata(url, alias);
+            DefaultFacelet f = new DefaultFacelet(this, _compiler.createExpressionFactory(), url, alias, h, true);
+            return f;
+        }
+        catch (FileNotFoundException fnfe)
+        {
+            throw new FileNotFoundException("Facelet " + alias + " not found at: " + url.toExternalForm());
+        }
+    }
 
     /**
      * Works in the same way as getFacelet(String uri), but redirect
@@ -367,4 +402,58 @@ public final class DefaultFaceletFactory
         
         return f;
     }
+    
+    /**
+     * Works in the same way as getFacelet(String uri), but redirect
+     * to getViewMetadataFacelet(URL url)
+     * @since 2.0.1
+     */
+    @Override
+    public Facelet getCompositeComponentMetadataFacelet(String uri) throws IOException
+    {
+        URL url = (URL) _relativeLocations.get(uri);
+        if (url == null)
+        {
+            url = resolveURL(_baseUrl, uri);
+            if (url != null)
+            {
+                Map<String, URL> newLoc = new HashMap<String, URL>(_relativeLocations);
+                newLoc.put(uri, url);
+                _relativeLocations = newLoc;
+            }
+            else
+            {
+                throw new IOException("'" + uri + "' not found.");
+            }
+        }
+        return this.getCompositeComponentMetadataFacelet(url);
+    }
+
+    /**
+     * @since 2.0.1
+     */
+    @Override
+    public Facelet getCompositeComponentMetadataFacelet(URL url) throws IOException,
+            FaceletException, FacesException, ELException
+    {
+        ParameterCheck.notNull("url", url);
+        
+        String key = url.toString();
+        
+        DefaultFacelet f = _compositeComponentMetadataFacelets.get(key);
+        
+        if (f == null || this.needsToBeRefreshed(f))
+        {
+            f = this._createCompositeComponentMetadataFacelet(url);
+            if (_refreshPeriod != NO_CACHE_DELAY)
+            {
+                Map<String, DefaultFacelet> newLoc = new HashMap<String, DefaultFacelet>(_compositeComponentMetadataFacelets);
+                newLoc.put(key, f);
+                _compositeComponentMetadataFacelets = newLoc;
+            }
+        }
+        
+        return f;
+    }
+
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/TagHandlerUtils.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/TagHandlerUtils.java?rev=950357&r1=950356&r2=950357&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/TagHandlerUtils.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/TagHandlerUtils.java Wed Jun  2 03:45:21 2010
@@ -36,6 +36,34 @@ import javax.faces.view.facelets.Facelet
  */
 public final class TagHandlerUtils
 {
+ 
+    /**
+     * Find the first occurence of a tag handler that is instanceof T
+     * 
+     * @since 2.0.1
+     * @param <T>
+     * @param nextHandler
+     * @param type
+     * @return
+     */
+    public static <T> T findFirstNextByType(FaceletHandler nextHandler, Class<T> type)
+    {
+        if (type.isAssignableFrom(nextHandler.getClass()))
+        {
+            return (T)nextHandler;
+        }
+        else if (nextHandler instanceof javax.faces.view.facelets.CompositeFaceletHandler)
+        {
+            for (FaceletHandler handler : ((javax.faces.view.facelets.CompositeFaceletHandler)nextHandler).getHandlers())
+            {
+                if (type.isAssignableFrom(handler.getClass()))
+                {
+                    return (T)handler;
+                }
+            }
+        }
+        return null;
+    }    
 
     /**
      * From TagHandler: 

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentDefinitionTagHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentDefinitionTagHandler.java?rev=950357&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentDefinitionTagHandler.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentDefinitionTagHandler.java Wed Jun  2 03:45:21 2010
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.tag.composite;
+
+import java.beans.BeanDescriptor;
+import java.beans.BeanInfo;
+import java.io.IOException;
+import java.util.Collection;
+
+import javax.faces.application.Resource;
+import javax.faces.component.UIComponent;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.FaceletHandler;
+
+import org.apache.myfaces.view.facelets.AbstractFaceletContext;
+import org.apache.myfaces.view.facelets.el.CompositeComponentELUtils;
+import org.apache.myfaces.view.facelets.tag.TagHandlerUtils;
+
+/**
+ * This handler wraps a composite component definition. 
+ * <p>
+ * This handler is set by facelets compiler through 
+ * CompositeComponentUnit class by the presence of cc:interface 
+ * or cc:implementation tag.
+ * </p> 
+ * <p>
+ * The presence of this class has the following objectives:
+ * </p>
+ * <ul>
+ * <li>Cache the BeanInfo instance for a composite component</li>
+ * <li>Set a Location object to resolve #{cc} correctly</li>
+ * <ul>
+ * @author Leonardo Uribe (latest modification by $Author: lu4242 $)
+ * @version $Revision: 945454 $ $Date: 2010-05-17 20:40:21 -0500 (Lun, 17 May 2010) $
+ */
+public final class CompositeComponentDefinitionTagHandler implements FaceletHandler
+{
+    private final FaceletHandler _nextHandler;
+    
+    private boolean _cacheable;
+    
+    /**
+     * Cached instance used by this component. Note here we have a 
+     * "racy single-check".If this field is used, it is supposed 
+     * the object cached by this handler is immutable, and this is
+     * granted if all properties not saved as ValueExpression are
+     * "literal". 
+     **/
+    private BeanInfo _cachedBeanInfo;
+    
+    private InterfaceHandler _interfaceHandler;
+    
+    private ImplementationHandler _implementationHandler;
+    
+    public CompositeComponentDefinitionTagHandler(FaceletHandler next)
+    {
+        this._nextHandler = next;
+        
+        _cacheable = true;
+        
+        _interfaceHandler = TagHandlerUtils.findFirstNextByType(_nextHandler, InterfaceHandler.class);
+        
+        _implementationHandler = TagHandlerUtils.findFirstNextByType(_nextHandler, ImplementationHandler.class);
+        
+        Collection<InterfaceDescriptorCreator> metadataInterfaceHandlerList = 
+            TagHandlerUtils.findNextByType( _nextHandler, InterfaceDescriptorCreator.class);
+        
+        for (InterfaceDescriptorCreator handler : metadataInterfaceHandlerList)
+        {
+            if (!handler.isCacheable())
+            {
+                _cacheable = false;
+                break;
+            }
+        }
+        if (!_cacheable)
+        {
+            for (InterfaceDescriptorCreator handler : metadataInterfaceHandlerList)
+            {
+                handler.setCacheable(false);
+            }
+        }
+    }
+
+    public void apply(FaceletContext ctx, UIComponent parent)
+            throws IOException
+    {
+        // Store the current Location on the parent (the location is needed
+        // to resolve the related composite component via #{cc} properly).
+        if (_interfaceHandler != null)
+        {
+            UIComponent compositeBaseParent = _getCompositeBaseParent(parent);
+            
+            compositeBaseParent.getAttributes()
+                .put(CompositeComponentELUtils.LOCATION_KEY, this._interfaceHandler.getLocation());
+        }
+        else if (_implementationHandler != null)
+        {
+            UIComponent compositeBaseParent = _getCompositeBaseParent(parent);
+            
+            compositeBaseParent.getAttributes()
+                .put(CompositeComponentELUtils.LOCATION_KEY, this._implementationHandler.getLocation());
+        }
+        
+        // Only apply if we are building composite component metadata,
+        // in other words we are calling ViewDeclarationLanguage.getComponentMetadata
+        if ( ((AbstractFaceletContext)ctx).isBuildingCompositeComponentMetadata() )
+        {
+            CompositeComponentBeanInfo tempBeanInfo = 
+                (CompositeComponentBeanInfo) parent.getAttributes()
+                .get(UIComponent.BEANINFO_KEY);
+            
+            if (tempBeanInfo == null)
+            {
+                UIComponent compositeBaseParent = _getCompositeBaseParent(parent);
+
+                if (_cacheable)
+                {
+                    if (_cachedBeanInfo == null)
+                    {
+                        _cachedBeanInfo = _createCompositeComponentMetadata(ctx, compositeBaseParent);
+                        parent.getAttributes().put(
+                                UIComponent.BEANINFO_KEY, _cachedBeanInfo);
+                        _nextHandler.apply(ctx, compositeBaseParent);
+                    }
+                    else
+                    {
+                        // Put the cached instance, but in that case it is not necessary to call
+                        // nextHandler
+                        parent.getAttributes().put(
+                                UIComponent.BEANINFO_KEY, _cachedBeanInfo);
+                    }
+                }
+                else
+                {
+                    tempBeanInfo = _createCompositeComponentMetadata(ctx, compositeBaseParent);
+                    parent.getAttributes().put(
+                            UIComponent.BEANINFO_KEY, tempBeanInfo);
+                    _nextHandler.apply(ctx, compositeBaseParent);
+                }
+            }
+        }
+        else
+        {
+            _nextHandler.apply(ctx, parent);
+        }
+    }
+    
+    /**
+     * Get the base component used temporally to hold metadata
+     * information generated by this handler. 
+     * 
+     * @param component
+     * @return
+     */
+    private UIComponent _getCompositeBaseParent(UIComponent component)
+    {
+        if (!component.getAttributes().containsKey(Resource.COMPONENT_RESOURCE_KEY))
+        {
+            UIComponent parent = component.getParent();
+            if (parent != null)
+            {
+                return _getCompositeBaseParent(parent);
+            }
+        }
+        return component;
+    }
+    
+    private CompositeComponentBeanInfo _createCompositeComponentMetadata(
+            FaceletContext ctx, UIComponent parent)
+    {
+        BeanDescriptor descriptor = new BeanDescriptor(parent.getClass());
+        CompositeComponentBeanInfo beanInfo = new CompositeComponentBeanInfo(descriptor);
+        return beanInfo;
+    }
+}

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentResourceTagHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentResourceTagHandler.java?rev=950357&r1=950356&r2=950357&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentResourceTagHandler.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentResourceTagHandler.java Wed Jun  2 03:45:21 2010
@@ -18,6 +18,7 @@
  */
 package org.apache.myfaces.view.facelets.tag.composite;
 
+import java.beans.BeanDescriptor;
 import java.beans.BeanInfo;
 import java.beans.PropertyDescriptor;
 import java.io.IOException;
@@ -162,10 +163,10 @@ public class CompositeComponentResourceT
     {
         //super.applyNextHandler(ctx, c);
         
+        applyNextHandlerIfNotApplied(ctx, c);
+        
         applyCompositeComponentFacelet(ctx,c);
         
-        applyNextHandlerIfNotApplied(ctx, c);
-
         if (ComponentHandler.isNew(c))
         {
             FacesContext facesContext = ctx.getFacesContext();
@@ -198,31 +199,47 @@ public class CompositeComponentResourceT
         }
     }
     
+    @SuppressWarnings("unchecked")
     protected void applyNextHandlerIfNotApplied(FaceletContext ctx, UIComponent c)
         throws IOException
     {
         //Apply all facelets not applied yet.
+        
+        CompositeComponentBeanInfo beanInfo = 
+            (CompositeComponentBeanInfo) c.getAttributes().get(UIComponent.BEANINFO_KEY);
+        
+        BeanDescriptor beanDescriptor = beanInfo.getBeanDescriptor();
+
+        boolean insertChildrenUsed = (beanDescriptor.getValue(InsertChildrenHandler.INSERT_CHILDREN_USED) != null);
+        
+        List<String> insertFacetList = (List<String>) beanDescriptor.getValue(InsertFacetHandler.INSERT_FACET_USED);
+        
         if (nextHandler instanceof javax.faces.view.facelets.CompositeFaceletHandler)
         {
             for (FaceletHandler handler : ((javax.faces.view.facelets.CompositeFaceletHandler)nextHandler).getHandlers())
             {
                 if (handler instanceof javax.faces.view.facelets.FacetHandler)
                 {
-                    if (!c.getAttributes().containsKey(InsertFacetHandler.INSERT_FACET_USED+((javax.faces.view.facelets.FacetHandler)handler).getFacetName(ctx)))
+                    if (insertFacetList == null || !insertFacetList.contains( ((javax.faces.view.facelets.FacetHandler)handler).getFacetName(ctx)))
                     {
                         handler.apply(ctx, c);
                     }
                 }
-                else if (handler instanceof javax.faces.view.facelets.ComponentHandler)
+                else if (handler instanceof InsertFacetHandler)
                 {
-                    if (!c.getAttributes().containsKey(InsertChildrenHandler.INSERT_CHILDREN_USED))
+                    if (insertFacetList == null || !insertFacetList.contains( ((InsertFacetHandler)handler).getFacetName(ctx)))
                     {
                         handler.apply(ctx, c);
                     }
                 }
-                else if (handler instanceof InsertFacetHandler)
+                else if (insertChildrenUsed)
                 {
-                    if (!c.getAttributes().containsKey(InsertFacetHandler.INSERT_FACET_USED+((InsertFacetHandler)handler).getFacetName(ctx)))
+                    if (!(handler instanceof javax.faces.view.facelets.ComponentHandler ||
+                            handler instanceof InsertChildrenHandler ||
+                            handler instanceof InsertHandler ||
+                            handler instanceof DecorateHandler ||
+                            handler instanceof IncludeHandler ||
+                            handler instanceof TextHandler))
                     {
                         handler.apply(ctx, c);
                     }
@@ -237,21 +254,26 @@ public class CompositeComponentResourceT
         {
             if (nextHandler instanceof javax.faces.view.facelets.FacetHandler)
             {
-                if (!c.getAttributes().containsKey(InsertFacetHandler.INSERT_FACET_USED+((javax.faces.view.facelets.FacetHandler)nextHandler).getFacetName(ctx)))
+                if (insertFacetList == null || !insertFacetList.contains( ((javax.faces.view.facelets.FacetHandler)nextHandler).getFacetName(ctx)) )
                 {
                     nextHandler.apply(ctx, c);
                 }
             }
-            else if (nextHandler instanceof javax.faces.view.facelets.ComponentHandler)
+            else if (nextHandler instanceof InsertFacetHandler)
             {
-                if (!c.getAttributes().containsKey(InsertChildrenHandler.INSERT_CHILDREN_USED))
+                if (insertFacetList == null || !insertFacetList.contains( ((InsertFacetHandler)nextHandler).getFacetName(ctx)) )
                 {
                     nextHandler.apply(ctx, c);
                 }
             }
-            else if (nextHandler instanceof InsertFacetHandler)
+            else if (insertChildrenUsed)
             {
-                if (!c.getAttributes().containsKey(InsertFacetHandler.INSERT_FACET_USED+((InsertFacetHandler)nextHandler).getFacetName(ctx)))
+                if (!(nextHandler instanceof javax.faces.view.facelets.ComponentHandler ||
+                        nextHandler instanceof InsertChildrenHandler ||
+                        nextHandler instanceof InsertHandler ||
+                        nextHandler instanceof DecorateHandler ||
+                        nextHandler instanceof IncludeHandler ||
+                        nextHandler instanceof TextHandler))
                 {
                     nextHandler.apply(ctx, c);
                 }
@@ -260,7 +282,7 @@ public class CompositeComponentResourceT
             {
                 nextHandler.apply(ctx, c);
             }
-        }        
+        }
     }
     
     protected void applyCompositeComponentFacelet(FaceletContext faceletContext, UIComponent compositeComponentBase) 

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/ImplementationHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/ImplementationHandler.java?rev=950357&r1=950356&r2=950357&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/ImplementationHandler.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/ImplementationHandler.java Wed Jun  2 03:45:21 2010
@@ -28,6 +28,7 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import javax.faces.component.UIComponent;
+import javax.faces.view.Location;
 import javax.faces.view.facelets.FaceletContext;
 import javax.faces.view.facelets.TagConfig;
 import javax.faces.view.facelets.TagException;
@@ -35,7 +36,6 @@ import javax.faces.view.facelets.TagHand
 
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
 import org.apache.myfaces.view.facelets.AbstractFaceletContext;
-import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage;
 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
 
 /**
@@ -59,8 +59,7 @@ public class ImplementationHandler exten
             throws IOException
     {
         FaceletCompositionContext mctx = FaceletCompositionContext.getCurrentInstance(ctx); 
-        if (!FaceletViewDeclarationLanguage.
-                isBuildingCompositeComponentMetadata(ctx.getFacesContext()))
+        if (!((AbstractFaceletContext)ctx).isBuildingCompositeComponentMetadata())
         {
             // If this tag is found in a facelet, the compiler has trimmed all
             // tags outside this one excluding composite:interface, so "parent"
@@ -116,6 +115,15 @@ public class ImplementationHandler exten
                     throw new TagException(tag,e);
                 }
             }
+            
+            // Pass to nextHandler, to give the chance to cc:insertChildren, cc:insertFacet and cc:renderFacet
+            // to save metadata information.
+            nextHandler.apply(ctx, parent);
         }
     }
+    
+    public Location getLocation()
+    {
+        return this.tag.getLocation();
+    }
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/InsertChildrenHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/InsertChildrenHandler.java?rev=950357&r1=950356&r2=950357&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/InsertChildrenHandler.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/InsertChildrenHandler.java Wed Jun  2 03:45:21 2010
@@ -19,15 +19,10 @@
 package org.apache.myfaces.view.facelets.tag.composite;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
-import javax.faces.component.StateHolder;
 import javax.faces.component.UIComponent;
-import javax.faces.context.FacesContext;
-import javax.faces.event.ComponentSystemEvent;
-import javax.faces.event.ComponentSystemEventListener;
 import javax.faces.view.facelets.FaceletContext;
 import javax.faces.view.facelets.TagConfig;
 import javax.faces.view.facelets.TagHandler;
@@ -35,7 +30,6 @@ import javax.faces.view.facelets.TagHand
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
 import org.apache.myfaces.view.facelets.AbstractFaceletContext;
 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
-import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;
 
 /**
  * @author Leonardo Uribe (latest modification by $Author$)
@@ -49,6 +43,8 @@ public class InsertChildrenHandler exten
     //public static String INSERT_CHILDREN_ORDERING = "org.apache.myfaces.INSERT_CHILDREN_ORDERING";
     
     public static String INSERT_CHILDREN_USED = "org.apache.myfaces.INSERT_CHILDREN_USED";
+    
+    private static final Logger log = Logger.getLogger(InsertChildrenHandler.class.getName());
 
     public InsertChildrenHandler(TagConfig config)
     {
@@ -58,13 +54,33 @@ public class InsertChildrenHandler exten
     public void apply(FaceletContext ctx, UIComponent parent)
             throws IOException
     {
-        UIComponent parentCompositeComponent = FaceletCompositionContext.getCurrentInstance(ctx).getCompositeComponentFromStack();
-        
-        AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
-        
-        actx.includeCompositeComponentDefinition(parent, null);
-        
-        parentCompositeComponent.getAttributes().put(INSERT_CHILDREN_USED, Boolean.TRUE);
+        if (((AbstractFaceletContext)ctx).isBuildingCompositeComponentMetadata())
+        {
+            CompositeComponentBeanInfo beanInfo = 
+                (CompositeComponentBeanInfo) parent.getAttributes()
+                .get(UIComponent.BEANINFO_KEY);
+            
+            if (beanInfo == null)
+            {
+                if (log.isLoggable(Level.SEVERE))
+                {
+                    log.severe("Cannot found composite bean descriptor UIComponent.BEANINFO_KEY ");
+                }
+                return;
+            }
+            
+            beanInfo.getBeanDescriptor().setValue(INSERT_CHILDREN_USED, Boolean.TRUE);
+        }
+        else
+        {
+            UIComponent parentCompositeComponent = FaceletCompositionContext.getCurrentInstance(ctx).getCompositeComponentFromStack();
+            
+            AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
+            
+            actx.includeCompositeComponentDefinition(parent, null);
+            
+            parentCompositeComponent.getAttributes().put(INSERT_CHILDREN_USED, Boolean.TRUE);
+        }
     }
 
     /*

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/InsertFacetHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/InsertFacetHandler.java?rev=950357&r1=950356&r2=950357&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/InsertFacetHandler.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/InsertFacetHandler.java Wed Jun  2 03:45:21 2010
@@ -18,30 +18,23 @@
  */
 package org.apache.myfaces.view.facelets.tag.composite;
 
+import java.beans.BeanDescriptor;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
-import javax.faces.component.StateHolder;
 import javax.faces.component.UIComponent;
-import javax.faces.context.FacesContext;
-import javax.faces.event.ComponentSystemEvent;
-import javax.faces.event.ComponentSystemEventListener;
-import javax.faces.event.PostAddToViewEvent;
-import javax.faces.view.facelets.ComponentHandler;
 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.JSFFaceletAttribute;
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
 import org.apache.myfaces.view.facelets.AbstractFaceletContext;
 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
-import org.apache.myfaces.view.facelets.PostBuildComponentTreeOnRestoreViewEvent;
-import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;
 
 /**
  * Insert or move the facet from the composite component body to the expected location.
@@ -56,7 +49,9 @@ public class InsertFacetHandler extends 
     //public static String INSERT_FACET_TARGET_ID = "org.apache.myfaces.INSERT_FACET_TARGET_ID.";
     //public static String INSERT_FACET_ORDERING = "org.apache.myfaces.INSERT_FACET_ORDERING.";
     
-    public static String INSERT_FACET_USED = "org.apache.myfaces.INSERT_FACET_USED.";
+    public static String INSERT_FACET_USED = "org.apache.myfaces.INSERT_FACET_USED";
+    
+    private static final Logger log = Logger.getLogger(InsertFacetHandler.class.getName());
     
     /**
      * The name that identify the current facet.
@@ -88,18 +83,53 @@ public class InsertFacetHandler extends 
         return _name.getValue(ctx);
     }
 
+    @SuppressWarnings("unchecked")
     public void apply(FaceletContext ctx, UIComponent parent)
             throws IOException
     {
-        String facetName = _name.getValue(ctx);
-        
-        AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
-        
-        UIComponent parentCompositeComponent = FaceletCompositionContext.getCurrentInstance(ctx).getCompositeComponentFromStack();
-        
-        actx.includeCompositeComponentDefinition(parent, facetName);
-        
-        parentCompositeComponent.getAttributes().put(INSERT_FACET_USED+facetName, Boolean.TRUE);
+        if (((AbstractFaceletContext)ctx).isBuildingCompositeComponentMetadata())
+        {
+            String facetName = _name.getValue(ctx);
+            CompositeComponentBeanInfo beanInfo = 
+                (CompositeComponentBeanInfo) parent.getAttributes()
+                .get(UIComponent.BEANINFO_KEY);
+            
+            if (beanInfo == null)
+            {
+                if (log.isLoggable(Level.SEVERE))
+                {
+                    log.severe("Cannot found composite bean descriptor UIComponent.BEANINFO_KEY ");
+                }
+                return;
+            }
+            
+            BeanDescriptor beanDescriptor = beanInfo.getBeanDescriptor(); 
+
+            List<String> facetList = (List<String>) beanDescriptor.getValue(INSERT_FACET_USED);
+            
+            if (facetList == null)
+            {
+                //2. If not found create it and set
+                facetList = new ArrayList<String>();
+                beanDescriptor.setValue(
+                        INSERT_FACET_USED,
+                        facetList);
+            }
+            
+            facetList.add(facetName);
+        }
+        else
+        {
+            String facetName = _name.getValue(ctx);
+            
+            AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
+            
+            UIComponent parentCompositeComponent = FaceletCompositionContext.getCurrentInstance(ctx).getCompositeComponentFromStack();
+            
+            actx.includeCompositeComponentDefinition(parent, facetName);
+            
+            parentCompositeComponent.getAttributes().put(INSERT_FACET_USED+facetName, Boolean.TRUE);
+        }
         
     }
     

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/InterfaceHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/InterfaceHandler.java?rev=950357&r1=950356&r2=950357&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/InterfaceHandler.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/InterfaceHandler.java Wed Jun  2 03:45:21 2010
@@ -19,12 +19,14 @@
 package org.apache.myfaces.view.facelets.tag.composite;
 
 import java.beans.BeanDescriptor;
-import java.beans.BeanInfo;
 import java.io.IOException;
 import java.util.Collection;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import javax.faces.application.Resource;
 import javax.faces.component.UIComponent;
+import javax.faces.view.Location;
 import javax.faces.view.facelets.FaceletContext;
 import javax.faces.view.facelets.TagAttribute;
 import javax.faces.view.facelets.TagConfig;
@@ -33,8 +35,6 @@ import javax.faces.view.facelets.TagHand
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletAttribute;
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
 import org.apache.myfaces.view.facelets.AbstractFaceletContext;
-import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage;
-import org.apache.myfaces.view.facelets.el.CompositeComponentELUtils;
 import org.apache.myfaces.view.facelets.tag.TagHandlerUtils;
 
 /**
@@ -42,8 +42,10 @@ import org.apache.myfaces.view.facelets.
  * @version $Revision$ $Date$
  */
 @JSFFaceletTag(name="composite:interface")
-public class InterfaceHandler extends TagHandler
+public class InterfaceHandler extends TagHandler implements InterfaceDescriptorCreator
 {
+    private static final Logger log = Logger.getLogger(InterfaceHandler.class.getName());
+    
     public final static String NAME = "interface";
     
     /**
@@ -100,14 +102,8 @@ public class InterfaceHandler extends Ta
      */
     private boolean _cacheable;
     
-    /**
-     * Cached instance used by this component. Note here we have a 
-     * "racy single-check".If this field is used, it is supposed 
-     * the object cached by this handler is immutable, and this is
-     * granted if all properties not saved as ValueExpression are
-     * "literal". 
-     **/
-    private BeanInfo _cachedBeanInfo;
+
+    private Collection<InterfaceDescriptorCreator> attrHandlerList;
     
     public InterfaceHandler(TagConfig config)
     {
@@ -129,7 +125,7 @@ public class InterfaceHandler extends Ta
             _cacheable = true;
             // Check if all attributes are cacheable. If that so, we can cache this
             // instance, otherwise not.
-            Collection<InterfaceDescriptorCreator> attrHandlerList = 
+            attrHandlerList = 
                 TagHandlerUtils.findNextByType( nextHandler, InterfaceDescriptorCreator.class);
             for (InterfaceDescriptorCreator handler : attrHandlerList)
             {
@@ -139,7 +135,7 @@ public class InterfaceHandler extends Ta
                     break;
                 }
             }
-            if (_cacheable)
+            if (!_cacheable)
             {
                 // Disable cache on attributes because this tag is the responsible for reuse
                 for (InterfaceDescriptorCreator handler : attrHandlerList)
@@ -157,49 +153,57 @@ public class InterfaceHandler extends Ta
     public void apply(FaceletContext ctx, UIComponent parent)
             throws IOException
     {
-        // Store the current Location on the parent (the location is needed
-        // to resolve the related composite component via #{cc} properly).
-        _getCompositeBaseParent(parent).getAttributes()
-                .put(CompositeComponentELUtils.LOCATION_KEY, this.tag.getLocation());
-        
         // Only apply if we are building composite component metadata,
         // in other words we are calling ViewDeclarationLanguage.getComponentMetadata
-        if ( FaceletViewDeclarationLanguage.
-                isBuildingCompositeComponentMetadata(ctx.getFacesContext()) )
+        if ( ((AbstractFaceletContext)ctx).isBuildingCompositeComponentMetadata() )
         {
             UIComponent compositeBaseParent = _getCompositeBaseParent(parent);
             
-            CompositeComponentBeanInfo tempBeanInfo = 
+            CompositeComponentBeanInfo beanInfo = 
                 (CompositeComponentBeanInfo) parent.getAttributes()
                 .get(UIComponent.BEANINFO_KEY);
             
-            if (tempBeanInfo == null)
+            if (beanInfo == null)
             {
-                if (_cacheable)
-                {
-                    if (_cachedBeanInfo == null)
-                    {
-                        _cachedBeanInfo = _createCompositeComponentMetadata(ctx, compositeBaseParent);
-                        parent.getAttributes().put(
-                                UIComponent.BEANINFO_KEY, _cachedBeanInfo);
-                        nextHandler.apply(ctx, compositeBaseParent);
-                    }
-                    else
-                    {
-                        // Put the cached instance, but in that case it is not necessary to call
-                        // nextHandler
-                        parent.getAttributes().put(
-                                UIComponent.BEANINFO_KEY, _cachedBeanInfo);
-                    }
-                }
-                else
+                if (log.isLoggable(Level.SEVERE))
                 {
-                    tempBeanInfo = _createCompositeComponentMetadata(ctx, compositeBaseParent);
-                    parent.getAttributes().put(
-                            UIComponent.BEANINFO_KEY, tempBeanInfo);
-                    nextHandler.apply(ctx, compositeBaseParent);
+                    log.severe("Cannot found composite bean descriptor UIComponent.BEANINFO_KEY ");
                 }
+                return;
+            }            
+            
+            BeanDescriptor descriptor = beanInfo.getBeanDescriptor();
+            // Add values to descriptor according to pld javadoc
+            if (_name != null)
+            {
+                descriptor.setName(_name.getValue(ctx));
+            }
+            if (_componentType != null)
+            {
+                // componentType is required by Application.createComponent(FacesContext, Resource)
+                // to instantiate the base component for this composite component. It should be
+                // as family javax.faces.NamingContainer .
+                descriptor.setValue(UIComponent.COMPOSITE_COMPONENT_TYPE_KEY, 
+                        _componentType.getValueExpression(ctx, String.class));
+            }
+            if (_displayName != null)
+            {
+                descriptor.setDisplayName(_displayName.getValue(ctx));
             }
+            if (_preferred != null)
+            {
+                descriptor.setPreferred(_preferred.getBoolean(ctx));
+            }
+            if (_expert != null)
+            {
+                descriptor.setExpert(_expert.getBoolean(ctx));
+            }
+            if (_shortDescription != null)
+            {
+                descriptor.setShortDescription(_shortDescription.getValue(ctx));
+            }
+            
+            nextHandler.apply(ctx, compositeBaseParent);
         }
     }
     
@@ -222,71 +226,23 @@ public class InterfaceHandler extends Ta
         }
         return component;
     }
-    
-    private CompositeComponentBeanInfo _createCompositeComponentMetadata(
-            FaceletContext ctx, UIComponent parent)
+
+    public boolean isCacheable()
     {
-        BeanDescriptor descriptor = new BeanDescriptor(parent.getClass());
-        CompositeComponentBeanInfo beanInfo = new CompositeComponentBeanInfo(descriptor);
-        
-        // Add values to descriptor according to pld javadoc
-        if (_name != null)
-        {
-            descriptor.setName(_name.getValue(ctx));
-        }
-        if (_componentType != null)
-        {
-            // componentType is required by Application.createComponent(FacesContext, Resource)
-            // to instantiate the base component for this composite component. It should be
-            // as family javax.faces.NamingContainer .
-            descriptor.setValue(UIComponent.COMPOSITE_COMPONENT_TYPE_KEY, 
-                    _componentType.getValueExpression(ctx, String.class));
-        }
-        if (_displayName != null)
-        {
-            descriptor.setDisplayName(_displayName.getValue(ctx));
-        }
-        if (_preferred != null)
-        {
-            descriptor.setPreferred(_preferred.getBoolean(ctx));
-        }
-        if (_expert != null)
-        {
-            descriptor.setExpert(_expert.getBoolean(ctx));
-        }
-        if (_shortDescription != null)
+        return _cacheable;
+    }
+
+    public void setCacheable(boolean cacheable)
+    {
+        _cacheable = cacheable;
+        for (InterfaceDescriptorCreator handler : attrHandlerList)
         {
-            descriptor.setShortDescription(_shortDescription.getValue(ctx));
+            handler.setCacheable(cacheable);
         }
-        
-        return beanInfo;
     }
     
-    /*
-    private static Collection<InterfaceDescriptorCreator> findNextByType(FaceletHandler nextHandler)
+    public Location getLocation()
     {
-        List<InterfaceDescriptorCreator> found = new ArrayList<InterfaceDescriptorCreator>();
-        if (nextHandler instanceof InterfaceDescriptorCreator)
-        {
-            InterfaceDescriptorCreator pdc = (InterfaceDescriptorCreator)nextHandler; 
-            found.add(pdc);
-            found.addAll(findNextByType(pdc.getNextHandler()));
-        }
-        else if (nextHandler instanceof javax.faces.view.facelets.CompositeFaceletHandler)
-        {
-            InterfaceDescriptorCreator pdc = null;
-            for (FaceletHandler handler : ((javax.faces.view.facelets.CompositeFaceletHandler)nextHandler).getHandlers())
-            {
-                if (handler instanceof InterfaceDescriptorCreator)
-                {
-                    pdc = (InterfaceDescriptorCreator) handler;
-                    found.add(pdc);
-                    found.addAll(findNextByType(pdc.getNextHandler()));
-                }
-            }
-        }
-        
-        return found;
+        return this.tag.getLocation();
     }
-    */
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/RenderFacetHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/RenderFacetHandler.java?rev=950357&r1=950356&r2=950357&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/RenderFacetHandler.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/RenderFacetHandler.java Wed Jun  2 03:45:21 2010
@@ -18,6 +18,13 @@
  */
 package org.apache.myfaces.view.facelets.tag.composite;
 
+import java.beans.BeanDescriptor;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
 import javax.faces.component.UIComponent;
 import javax.faces.view.facelets.ComponentConfig;
 import javax.faces.view.facelets.ComponentHandler;
@@ -27,6 +34,7 @@ import javax.faces.view.facelets.TagExce
 
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletAttribute;
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
+import org.apache.myfaces.view.facelets.AbstractFaceletContext;
 
 /**
  * Render the facet defined on the composite component body to the current location
@@ -37,6 +45,10 @@ import org.apache.myfaces.buildtools.mav
 @JSFFaceletTag(name="composite:renderFacet")
 public class RenderFacetHandler extends ComponentHandler
 {
+    private static final Logger log = Logger.getLogger(RenderFacetHandler.class.getName());
+    
+    public static String RENDER_FACET_USED = "org.apache.myfaces.RENDER_FACET_USED";
+    
     /**
      * The name that identify the current facet.
      */
@@ -62,20 +74,62 @@ public class RenderFacetHandler extends 
         _required = getAttribute("required");
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public void apply(FaceletContext ctx, UIComponent parent)
+            throws IOException
+    {
+        if (((AbstractFaceletContext)ctx).isBuildingCompositeComponentMetadata())
+        {
+            String facetName = _name.getValue(ctx);
+            CompositeComponentBeanInfo beanInfo = 
+                (CompositeComponentBeanInfo) parent.getAttributes()
+                .get(UIComponent.BEANINFO_KEY);
+            
+            if (beanInfo == null)
+            {
+                if (log.isLoggable(Level.SEVERE))
+                {
+                    log.severe("Cannot found composite bean descriptor UIComponent.BEANINFO_KEY ");
+                }
+                return;
+            }
+            
+            BeanDescriptor beanDescriptor = beanInfo.getBeanDescriptor(); 
+
+            List<String> facetList = (List<String>) beanDescriptor.getValue(RENDER_FACET_USED);
+            
+            if (facetList == null)
+            {
+                //2. If not found create it and set
+                facetList = new ArrayList<String>();
+                beanDescriptor.setValue(
+                        RENDER_FACET_USED,
+                        facetList);
+            }
+            
+            facetList.add(facetName);
+        }
+        super.apply(ctx, parent);
+    }
+
     @Override
     public void onComponentPopulated(FaceletContext ctx, UIComponent c,
             UIComponent parent)
     {
-        UIComponent parentCompositeComponent = UIComponent.getCurrentCompositeComponent(ctx.getFacesContext());
-        
-        String facetName = _name.getValue(ctx);
-
-        if (_required != null && _required.getBoolean(ctx) && parentCompositeComponent.getFacet(facetName) == null)
+        if (!((AbstractFaceletContext)ctx).isBuildingCompositeComponentMetadata())
         {
-            throw new TagException(this.tag, "Cannot found facet with name "+facetName+" in composite component "
-                    +parentCompositeComponent.getClientId(ctx.getFacesContext()));
+            UIComponent parentCompositeComponent = UIComponent.getCurrentCompositeComponent(ctx.getFacesContext());
+            
+            String facetName = _name.getValue(ctx);
+    
+            if (_required != null && _required.getBoolean(ctx) && parentCompositeComponent.getFacet(facetName) == null)
+            {
+                throw new TagException(this.tag, "Cannot found facet with name "+facetName+" in composite component "
+                        +parentCompositeComponent.getClientId(ctx.getFacesContext()));
+            }
+            
+            c.getAttributes().put(UIComponent.FACETS_KEY, facetName);
         }
-        
-        c.getAttributes().put(UIComponent.FACETS_KEY, facetName);
     }
 }