You are viewing a plain text version of this content. The canonical link for it is here.
Posted to adffaces-commits@incubator.apache.org by jw...@apache.org on 2006/11/15 03:16:51 UTC

svn commit: r475104 - in /incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal: skin/ ui/laf/xml/parse/ webapp/

Author: jwaldman
Date: Tue Nov 14 19:16:50 2006
New Revision: 475104

URL: http://svn.apache.org/viewvc?view=rev&rev=475104
Log:
ADF-FACES 292 Allow registering stylesheets on a particular skin via an xml config file
Tested by creating a jar with trinidad-skins.xml and stylesheets
and putting it in the demo bundle project's library. Then I ran a demo file with the skin
that is in the jar, and it finds it, and finds the stylesheets fine.
I also tested multiple jars that have skins that extend one another to make sure the
ordering code was tested.


Added:
    incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinAdditionNode.java
    incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinAdditionNodeParser.java
    incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinNode.java
    incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinNodeParser.java
    incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinsNode.java
Removed:
    incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinExtensionParser.java
Modified:
    incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinUtils.java
    incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinsNodeParser.java
    incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/webapp/TrinidadFilterImpl.java

Modified: incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinUtils.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinUtils.java?view=diff&rev=475104&r1=475103&r2=475104
==============================================================================
--- incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinUtils.java (original)
+++ incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinUtils.java Tue Nov 14 19:16:50 2006
@@ -20,27 +20,34 @@
 import java.io.IOException;
 
 import java.io.InputStream;
+
+import java.net.URL;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+
+import java.util.Iterator;
+import java.util.List;
+
+import javax.faces.context.FacesContext;
+
 import javax.servlet.ServletContext;
 import javax.xml.parsers.SAXParserFactory;
 
-import org.apache.myfaces.trinidad.skin.Skin;
 import org.apache.myfaces.trinidad.skin.SkinFactory;
-import org.apache.myfaces.trinidad.skin.Icon;
 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
 
 
-
+import org.apache.myfaces.trinidad.skin.Skin;
 import org.apache.myfaces.trinidadinternal.renderkit.core.skin.MinimalDesktopSkinExtension;
 import org.apache.myfaces.trinidadinternal.renderkit.core.skin.MinimalPdaSkinExtension;
 import org.apache.myfaces.trinidadinternal.renderkit.core.skin.SimpleDesktopSkin;
 import org.apache.myfaces.trinidadinternal.renderkit.core.skin.SimplePdaSkin;
-import org.apache.myfaces.trinidadinternal.ui.laf.xml.parse.SkinPropertyNode;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 
 import org.apache.myfaces.trinidadinternal.share.io.NameResolver;
 import org.apache.myfaces.trinidadinternal.share.xml.ClassParserFactory;
-import org.apache.myfaces.trinidadinternal.share.xml.ParseContext;
 import org.apache.myfaces.trinidadinternal.share.xml.ParseContextImpl;
 import org.apache.myfaces.trinidadinternal.share.xml.ParserFactory;
 import org.apache.myfaces.trinidadinternal.share.xml.ParserManager;
@@ -48,11 +55,10 @@
 import org.apache.myfaces.trinidadinternal.share.xml.XMLProvider;
 import org.apache.myfaces.trinidadinternal.share.xml.XMLUtils;
 
-import org.apache.myfaces.trinidadinternal.style.Style;
-
-import org.apache.myfaces.trinidadinternal.ui.laf.xml.parse.IconNode;
-import org.apache.myfaces.trinidadinternal.ui.laf.xml.parse.IconParserFactory;
 import org.apache.myfaces.trinidadinternal.ui.laf.xml.XMLConstants;
+import org.apache.myfaces.trinidadinternal.ui.laf.xml.parse.SkinAdditionNode;
+import org.apache.myfaces.trinidadinternal.ui.laf.xml.parse.SkinNode;
+import org.apache.myfaces.trinidadinternal.ui.laf.xml.parse.SkinsNode;
 
 /**
  * Utility functions for creating Skins from the trinidad-skins.xml file
@@ -63,7 +69,7 @@
 {
 
   /**
-   * Register the base skins with the SkinFactory.
+   * Register the base skins with the SkinFactory. (simple/minimal)
    * Make sure the SkinFactory.getFactory() does not return null before
    * calling this method.
    */
@@ -73,14 +79,14 @@
     SkinFactory skinFactory = SkinFactory.getFactory();
 
     // skinFactory should be non-null when this is called since it is
-    // initiated in the AdfFacesFilterImpl, but in case it isn't do this
+    // initiated in the TrinidadFilterImpl, but in case it isn't do this
     if (skinFactory == null)
     {
       SkinFactory.setFactory(new SkinFactoryImpl());
       skinFactory = SkinFactory.getFactory();
     }
 
-    _registerAdfFacesSkins(skinFactory);
+    _registerTrinidadSkins(skinFactory);
   }
   
   /**
@@ -99,7 +105,7 @@
     SkinFactory skinFactory = SkinFactory.getFactory();
 
     // skinFactory should be non-null when this is called since it is
-    // initiated in the AdfFacesFilterImpl, but in case it isn't do this
+    // initiated in the TrinidadFilterImpl, but in case it isn't do this
     if (skinFactory == null)
     {
       SkinFactory.setFactory(new SkinFactoryImpl());
@@ -111,83 +117,86 @@
   }
 
   /**
-   * Create a SkinExtension[] off a generic SAX input source, using
-   * the default parsing manager.
+   * Create a SkinExtension off a generic SAX input source, using
+   * a custom parsing manager.
    * <p>
-   * @param skinFactory The SkinFactory that will be used
-   *        to obtain references to Skin instances that this
-   *        SkinExtension depends on, such as the base Skin.
-   * @param provider an XMLProvider implementation
+   * @param provider
    * @param resolver A NameResolver that can be used to locate
    *                 resources, such as source images for colorized
    *                 icons.
-   * @param source the SAX input source to load the Skin contents from
+   * @param parserManager the ParserManager to use for parsing
+   *                Must  be non-null.
+   * @throws NullPointerException when inputStream or parserManager
+   *         is null.
    */
-  static private SkinExtension[] _createSkinExtensions(
-    SkinFactory        skinFactory,
-    XMLProvider        provider,
-    NameResolver       resolver,
-    InputSource        source
-    ) throws IOException, SAXException
-  {
-    return _createSkinExtensions(skinFactory,
-                                provider,
-                                resolver,
-                                source,
-                                _getDefaultManager());
-  }
-
   /**
-   * Create a SkinExtension off a generic SAX input source, using
-   * a custom parsing manager.
-   * <p>
-   * @param skinFactory The SkinFactory that will be used
-   *        to obtain references to Skin instances that this
-   *        SkinExtension depends on, such as the base Skin. Must  be non-null.
+   * 
    * @param provider an XMLProvider implementation.
    * @param resolver A NameResolver that can be used to locate
    *                 resources, such as source images for colorized
    *                 icons.
-   * @param source the SAX input source to load the LookAndFeel contents from
-   *               Must  be non-null.
-   * @param manager the ParserManager to use for parsing
+   * @param inputStream the inputStream. Must be non-null
+   * @param parserManager the ParserManager to use for parsing
    *                Must  be non-null.
-   * @throws NullPointerException when skinFactory, source, or parserManager
-   *         is null.
+   * @param configFile The name of the config file we are parsing.
+   * @return A SkinsNode object (contains a List of SkinNode and a List of SkinAdditionNode)
    */
-  static private SkinExtension[] _createSkinExtensions(
-    SkinFactory        skinFactory,
+  static private SkinsNode _getSkinsNodeFromInputStream(
     XMLProvider        provider,
     NameResolver       resolver,
-    InputSource        source,
-    ParserManager      parserManager
-    ) throws IOException, SAXException
+    InputStream        inputStream,
+    ParserManager      parserManager,
+    String             configFile
+    )
   {
-    if (skinFactory == null)
-      throw new NullPointerException("Null skinFactory");
-    if (source == null)
-      throw new NullPointerException("Null source");
+  
+    if (inputStream == null)
+      throw new NullPointerException("Null inputStream");
     if (parserManager == null)
       throw new NullPointerException("Null parserManager");
-
-
-    ParseContextImpl context = new ParseContextImpl();
-
-    // Set up the SkinFactory on the ParseContext
-    context.setProperty(XMLConstants.SKIN_NAMESPACE,
-                        _SKIN_FACTORY_PROPERTY,
-                        skinFactory);
-
-    // Set up the NameResolver if we have one
-    if (resolver != null)
-      XMLUtils.setResolver(context, resolver);
-
-    // Create the TreeBuilder
-    TreeBuilder builder = new TreeBuilder(parserManager,
-                                          SkinExtension[].class);
-
-    return ((SkinExtension[])builder.parse(provider, source, context));
-
+    SkinsNode skinsNode = null;
+    try
+    {
+      InputSource input = new InputSource();
+      input.setByteStream(inputStream);
+      input.setPublicId(configFile);
+
+      SAXParserFactory factory = SAXParserFactory.newInstance();
+      factory.setNamespaceAware(true);   
+      
+      ParseContextImpl context = new ParseContextImpl();
+
+      // Set up the NameResolver if we have one
+      if (resolver != null)
+        XMLUtils.setResolver(context, resolver);
+
+      // Create the TreeBuilder
+      TreeBuilder builder = new TreeBuilder(parserManager,
+                                            SkinsNode.class);
+      skinsNode = ((SkinsNode)builder.parse(provider, input, context));
+   
+    }
+    catch (IOException ioe)
+    {
+      _LOG.warning(ioe);
+    }
+    catch (SAXException saxe)
+    {
+      _LOG.warning(saxe);
+    }
+    finally
+    {
+      try
+      {
+        inputStream.close();
+      }
+      catch (IOException ioe)
+      {
+        // Ignore
+        ;
+      }
+    }
+    return skinsNode;
   }
 
   /**
@@ -199,65 +208,15 @@
     ParserManager manager = new ParserManager();
 
     // Register top-level factory
-    _registerFactory(manager,
-                     SkinExtension[].class,
-                     "SkinsNode");
-    _registerFactory(manager,
-                     SkinExtension.class,
-                     "SkinExtension");
-
-    // Icon-related factories
-    _registerFactory(manager, IconNode[].class, "IconsNode");
-    _registerFactory(manager, IconNode.class, "IconNode");
-    manager.registerFactory(Icon.class,
-                            XMLConstants.SKIN_NAMESPACE,
-                            new IconParserFactory());
-
-    // Property-related factories
-    _registerFactory(manager, SkinPropertyNode[].class, "SkinPropertiesNode");
-    _registerFactory(manager, SkinPropertyNode.class, "SkinPropertyNode");
-
-    // Parser for inline styles ????
-    ClassParserFactory styleFactory = new ClassParserFactory(
-        "org.apache.myfaces.trinidadinternal.style.xml.parse.CSSStyleParser");
-    manager.registerFactory(Style.class,
-                            XMLConstants.SKIN_NAMESPACE,
-                            styleFactory);
+     _registerFactory(manager, SkinsNode.class, "SkinsNode");
+    
+    // Register skin node factory and skin addition node factory
+    _registerFactory(manager, SkinNode.class, "SkinNode");
+    _registerFactory(manager, SkinAdditionNode.class, "SkinAdditionNode");
 
     return manager;
   }
 
-  /**
-   * Returns the Skin with the specified id for
-   * the current SkinFactory. Used to get the base skin while parsing
-   * SkinExtensions.
-   * @param context The current ParseContext
-   * @param id The id of the Skin to retrieve.
-   */
-  static public Skin getSkin(
-    ParseContext context,
-    String       id
-    )
-  {
-    // get the SkinFactory from the ParseContext.
-    SkinFactory factory = getSkinFactory(context);
-    if (factory == null)
-     throw new NullPointerException("Null skin factory");
-
-    return factory.getSkin(null, id);
-  }
-
-  /**
-   * Returns the current SkinFactory.
-   * @param context The current ParseContext
-   */
-  static public SkinFactory getSkinFactory(ParseContext context)
-  {
-    return (SkinFactory)context.getProperty(
-                                 XMLConstants.SKIN_NAMESPACE,
-                                 _SKIN_FACTORY_PROPERTY);
-  }
-
   // Returns a singleton instance of the default ParserManager
   static private ParserManager _getDefaultManager()
   {
@@ -283,11 +242,11 @@
   }
 
   /**
-   * register the AdfFaces skins: simpleDesktopSkin, simplePdaSkin,
+   * register the Trinidad skins: simpleDesktopSkin, simplePdaSkin,
    * and minimalDesktopSkin, minimalPdaSkin, and blafPlusDesktopSkin.
    * @param skinFactory
    */
-  private static void _registerAdfFacesSkins(
+  private static void _registerTrinidadSkins(
     SkinFactory skinFactory)
   {
     // SimpleDesktopSkin is the BASE skin for org.apache.myfaces.trinidad.desktop renderKit
@@ -312,6 +271,11 @@
   /**
    * Parse the trinidad-skins.xml file for SkinExtensions and add each
    * SkinExtension to the skinFactory.
+   * First find all the trinidad-skins.xml files that are in META-INF directory, and 
+   * add those skins to the skin factory.
+   * Then find the WEB-INF/trinidad-skins.xml file and add those skins to the skin factory.
+   * The skins are ordered so that the 'extended' skins are registered before the skins that extend
+   * them.
    * @param context
    * @param skinFactory
    */
@@ -321,48 +285,358 @@
   {
     if (context == null)
       return;
-
-    // =-=jmw @todo find trinidad-skins.xml in jar
-    InputStream in = context.getResourceAsStream(_CONFIG_FILE);
-    if (in != null)
+     
+    // Add META-INF/trinidad-skins.xml skins to skin factory. (sorted first to make sure 
+    // we register the most 'base' skins first)
+    List<SkinsNode> metaInfSkinsNodeList = _getMetaInfSkinsNodeList(); 
+    // Go through each SkinsNode object 
+    // (contains List of SkinNodes and List of SkinAdditionNodes)
+    // and return a List of the SkinNodes.
+    List<SkinNode> metaInfSkinNodes = new ArrayList<SkinNode>();
+    for (SkinsNode skinsNode : metaInfSkinsNodeList)
     {
-      try
-      {
-        InputSource input = new InputSource();
-        input.setByteStream(in);
-        input.setPublicId(_CONFIG_FILE);
-
-        SAXParserFactory factory = SAXParserFactory.newInstance();
-        factory.setNamespaceAware(true);
-
-        // as we parse each skin, we register with the skin factory.
-        // this way we can extend any skin we want.
-        _createSkinExtensions(skinFactory, null, null, input);
+      metaInfSkinNodes.addAll(skinsNode.getSkinNodes());
+    }    
+    
+    List<SkinNode> sortedMetaInfSkinNodes = _sortSkinNodes(skinFactory, metaInfSkinNodes);
+    
+    for (SkinNode skinNode : sortedMetaInfSkinNodes)
+    {
+      _addSkinToFactory(skinFactory, skinNode, true);
+    }
+    
+    // Add WEB-INF/trinidad-skins.xml skins to skin factory. (sorted first)    
+    SkinsNode webInfSkinsNode = _getWebInfSkinsNode(context);
+    List<SkinNode> webInfSkinNodes = webInfSkinsNode.getSkinNodes();
+
+    List<SkinNode> sortedWebInfSkinNodes = _sortSkinNodes(skinFactory, webInfSkinNodes);
+    
+    // register skins found in webInfSkinNodes
+    for (SkinNode skinNode : sortedWebInfSkinNodes)
+    {
+      _addSkinToFactory(skinFactory, skinNode, false);
+    }
+    
+    // register all the skin additions from META-INF trinidad-skins.xml and WEB-INF
+    // trinidad-skins.xml that we have stored in the metaInfSkinsNodeList object and the
+    // webInfSkinsNode object
+    FacesContext fContext = FacesContext.getCurrentInstance();
+    // register skin-additions from META-INF/trinidad-skins.xml files
+    for (SkinsNode skinsNode : metaInfSkinsNodeList)
+    {
+      List<SkinAdditionNode> skinAdditionNodeList = skinsNode.getSkinAdditionNodes();
+      _registerSkinAdditions(fContext, skinFactory, skinAdditionNodeList, true);    
+    } 
+    // register skin-additions from WEB-INF/trinidad-skins.xml file
+    List<SkinAdditionNode> skinAdditionNodeList = webInfSkinsNode.getSkinAdditionNodes();
+    _registerSkinAdditions(fContext, skinFactory, skinAdditionNodeList, false);    
+    
+  }
+  
+  /**
+   * Given the a List of SkinNodes, sort them so that the SkinNodes in such a way so that
+   * when we register the skins we make sure that the 'base' skins are registered before
+   * skins that extend them.
+   * @param skinFactory
+   * @param skinNodes
+   * @return sorted List of SkinNodes
+   */
+  private static List<SkinNode> _sortSkinNodes(
+    SkinFactory    skinFactory,
+    List<SkinNode> skinNodes)
+  {
+    List<SkinNode> sortedSkinNodes = new ArrayList<SkinNode>();
+    List<String>   skinNodesAdded = new ArrayList<String>();
+    List<String>   baseSkinIds = new ArrayList<String>();
+    for (Iterator i=skinFactory.getSkinIds(); i.hasNext(); ) 
+       baseSkinIds.add((String)i.next());
+   
+    // first, the skins that don't extend anything
+    for (SkinNode skinNode : skinNodes)
+    {
+      String skinExtends = skinNode.getSkinExtends();
 
+      if (skinExtends == null)
+      {
+        sortedSkinNodes.add(skinNode);
+        skinNodesAdded.add(skinNode.getId());
       }
-      catch (IOException ioe)
+    }
+    
+    // second, the skins that extend another skin
+    _sortSkinNodesWithExtensions(skinNodes, sortedSkinNodes, skinNodesAdded, baseSkinIds, 0);
+      
+    return sortedSkinNodes;
+    
+  }
+  
+  /**
+   * This sorts SkinNodes that have their 'extends' value set, which means the skin
+   * extends another skin. The order of our skin nodes matters in this case. We want the 
+   * base skin to be registered first.
+   * @param skinNodes
+   * @param sortedSkinNodes
+   * @param skinNodesAdded
+   * @param baseSkinIds
+   */
+  private static void _sortSkinNodesWithExtensions(
+    List<SkinNode> skinNodes,
+    List<SkinNode> sortedSkinNodes,
+    List<String>   skinNodesAdded,
+    List<String>   baseSkinIds,
+    int            originalLeftOverListSize)
+  {
+    List<SkinNode> leftOverList = new ArrayList<SkinNode>();
+  
+    for (SkinNode skinNode : skinNodes)
+    {
+      String skinExtends = skinNode.getSkinExtends();
+
+      if (skinExtends != null)
       {
-        _LOG.warning(ioe);
+        if (skinNodesAdded.contains(skinExtends) ||
+            baseSkinIds.contains(skinExtends))
+        {
+          sortedSkinNodes.add(skinNode);
+          skinNodesAdded.add(skinNode.getId());
+        }
+        else
+        { 
+          // left over, put in a left-over list
+          leftOverList.add(skinNode);
+        }  
       }
-      catch (SAXException saxe)
+    } 
+    if ((originalLeftOverListSize > 0) && 
+         (leftOverList.size() == originalLeftOverListSize))
+    {
+      // Ok, we are left with skinNodes that cannot be registered because the skin they extend is
+      // not in the skinNodesAdded List. The skin they extend might not exist at all, or 
+      // there is a circular dependency.
+      // So..., just add these to the list. When we register these, they will cause a severe error
+      // and the default base skin will be used.
+       StringBuffer buffer = new StringBuffer();
+       for (SkinNode leftOverNode : leftOverList)
+       {
+         buffer.append("Skin with id: " + leftOverNode.getId() + 
+                      " extends skin with id: " + leftOverNode.getSkinExtends() + "\n");
+         sortedSkinNodes.add(leftOverNode);
+         skinNodesAdded.add(leftOverNode.getId());
+
+       }
+      _LOG.warning("The following skins extend each other in a circular " +
+                   "fashion or the skin they extend does not exist.\n" + buffer.toString());
+ 
+    } 
+    else  if (leftOverList.size() > 0)   
+    {
+      _sortSkinNodesWithExtensions(leftOverList, sortedSkinNodes, 
+                                   skinNodesAdded, baseSkinIds, leftOverList.size());      
+    }
+  }
+ 
+  /**
+   * Given a skinNode, create a Skin object and 
+   * register the SkinExtension object with the skinFactory
+   * @param skinFactory
+   * @param skinNode
+   */
+  private static void _addSkinToFactory(
+    SkinFactory skinFactory, 
+    SkinNode    skinNode,
+    boolean     isMetaInfFile)
+  {
+    // if the renderKitId is not specified,
+    // set it to _RENDER_KIT_ID_CORE.
+    String renderKitId = skinNode.getRenderKitId();
+    String id = skinNode.getId();
+    String family = skinNode.getFamily();
+    String styleSheetName = skinNode.getStyleSheetName();
+    String bundleName = skinNode.getBundleName();
+    
+    if (renderKitId == null)
+      renderKitId = _RENDER_KIT_ID_DESKTOP;
+
+
+    // figure out the base skin.
+    Skin baseSkin = null;
+    String skinExtends = skinNode.getSkinExtends();
+    
+    if (skinExtends != null)
+      baseSkin = skinFactory.getSkin(null, skinExtends);
+    if (baseSkin == null)
+    {
+      baseSkin = _getDefaultBaseSkin(skinFactory, renderKitId);
+      
+      if (skinExtends != null)
       {
-        _LOG.warning(saxe);
+        _LOG.severe("Unable to locate base skin \"{0}\" for " +
+                    "use in defining skin of id \"{1}\", family " +
+                    "\"{2}\", renderkit ID \"{3}\". Using the default base skin \"{4}\".",
+                    new String[]{skinExtends, id, family, renderKitId, baseSkin.getId()});
       }
-      finally
+
+    }
+
+    SkinExtension skin = new SkinExtension(baseSkin,
+                                           id,
+                                           family,
+                                           renderKitId);
+
+    // Set the style sheet
+    if (styleSheetName != null)
+    {
+      // If the styleSheetName is in the META-INF/trinidad-skins.xml file, then
+      // we prepend META-INF to the styleSheetName if it doesn't begin with '/'.
+      // This way we can find the file when we go to parse it later.
+      if (isMetaInfFile)
+        styleSheetName = _prependMetaInf(styleSheetName);
+      skin.setStyleSheetName(styleSheetName);
+    }
+    // And the bundle
+    if (bundleName != null)
+      skin.setBundleName(bundleName);
+
+    // Create a SkinExtension object and register skin with factory
+    skinFactory.addSkin(id, skin);    
+  }
+  
+  /**
+   * Get the WEB-INF/trinidad-skins.xml file, parse it, and return a List SkinNode objects. 
+   * @param context ServletContext used to getResourceAsStream
+   * @return List of SkinNodes (skin elements) found in trinidad-skins.xml
+   */
+  private static SkinsNode _getWebInfSkinsNode(
+    ServletContext context)
+  {
+    InputStream in = context.getResourceAsStream(_CONFIG_FILE);
+    if (in != null)
+    {
+      SkinsNode webInfSkinsNode = 
+        _getSkinsNodeFromInputStream(null, null, in, _getDefaultManager(), _CONFIG_FILE);
+
+      return webInfSkinsNode;
+    }
+    else
+    {
+      return null;
+    }
+  }
+ 
+  /**
+   * Get all the META-INF/trinidad-skins.xml files, parse them, and from each file we get
+   * a SkinsNode object -- the information inside the &lt;skins&gt; element -- each skin
+   * and each skin-addition.
+   * @return Each SkinsNode object we get from each META-INF/trinidad-skins.xml file, 
+   * in a List<SkinsNode>.
+   */
+  private static List<SkinsNode> _getMetaInfSkinsNodeList()
+  {
+        
+    List<SkinsNode> allSkinsNodes = new ArrayList<SkinsNode>(); 
+    ClassLoader loader = Thread.currentThread().getContextClassLoader();     
+    
+    try
+    {
+  
+      Enumeration<URL> urls = loader.getResources(_META_INF_CONFIG_FILE);
+      while (urls.hasMoreElements())
       {
+        URL url = urls.nextElement();
+        
+        _LOG.finest("Processing:{0}", url);
         try
         {
-          in.close();
+          // parse the config file and register the skin's additional stylesheets.
+          InputStream in = url.openStream();
+          if (in != null)
+          {
+            SkinsNode  metaInfSkinsNode = 
+              _getSkinsNodeFromInputStream(null, null, in, _getDefaultManager(), 
+                                           _META_INF_CONFIG_FILE);
+              
+            allSkinsNodes.add(metaInfSkinsNode);
+          }
         }
-        catch (IOException ioe)
+        catch (Exception e)
         {
-          // Ignore
-          ;
+         _LOG.warning("Error parsing:"+url, e);
         }
       }
     }
+    catch (IOException e)
+    {
+      _LOG.severe("error loading file:"+ _META_INF_CONFIG_FILE, e);
+    }
+    
+    return allSkinsNodes;
+  } 
+
+  private static Skin _getDefaultBaseSkin(
+    SkinFactory factory,
+    String      renderKitId)
+  {
+
+    String baseSkinId = (_RENDER_KIT_ID_PDA.equals(renderKitId)) ?
+                          _SIMPLE_PDA_SKIN_ID :
+                          _SIMPLE_DESKTOP_SKIN_ID;
+
+    Skin baseSkin = factory.getSkin(null, baseSkinId);
+
+    // It is an error if we were unable to find the base skin
+    if (baseSkin == null)
+      _LOG.severe(_UNKNOWN_BASE_SKIN_ERROR + baseSkinId);
+
+    return baseSkin;
+  }
+  
+  /**
+   * Get the skin id and stylesheet name from each SkinAdditionNode and
+   * get the skin and register the styleSheetName with the skin
+   * @param fContext
+   * @param skinFactory
+   * @param skinAdditionNodeList
+   * @param isMetaInfFile true if the trinidad-skins.xml file is in the META-INF
+   * directory.
+   */
+  private static void _registerSkinAdditions(
+    FacesContext fContext,
+    SkinFactory  skinFactory,
+    List<SkinAdditionNode> skinAdditionNodeList,
+    boolean      isMetaInfFile
+    )
+  {
+    for (SkinAdditionNode skinAdditionNode : skinAdditionNodeList)
+    {
+      String skinId = skinAdditionNode.getSkinId();
+      String styleSheetName = skinAdditionNode.getStyleSheetName();
+  
+      Skin skin = skinFactory.getSkin(fContext, skinId);
+      if (skin != null && styleSheetName != null)
+      {  
+        // If the styleSheetName is in the META-INF/trinidad-skins.xml file, then
+        // we prepend META-INF to the styleSheetName if it doesn't begin with '/'.
+        // This way we can find the file when we go to parse it later.
+        if (isMetaInfFile)
+          styleSheetName = _prependMetaInf(styleSheetName);
+        skin.registerStyleSheet(styleSheetName); 
+      }
+    }    
   }
 
+  /**
+   * Prepend META-INF to the styleSheetName if it doesn't begin with '/'.
+   * @param styleSheetName
+   * @return String styleSheetName or the styleSheetName prepended with META-INF/
+   */
+  private static String _prependMetaInf(String styleSheetName)
+  {
+    if (!(styleSheetName.startsWith("/")))
+      return _META_INF_DIR.concat(styleSheetName);
+    else
+      return styleSheetName;
+  }
+  
   private SkinUtils() {}
 
   // The default ParserManager
@@ -374,11 +648,19 @@
   static private final String _LAF_PARSE_PACKAGE =
     "org.apache.myfaces.trinidadinternal.ui.laf.xml.parse.";
 
-  // Property for storing/retrieving the SkinFactory
-  static private final String _SKIN_FACTORY_PROPERTY = "_skinFactory";
 
   static private final String _CONFIG_FILE = "/WEB-INF/trinidad-skins.xml";
-
+  static private final String _META_INF_CONFIG_FILE = "META-INF/trinidad-skins.xml";
+  static private final String _META_INF_DIR = "META-INF/";
   static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(SkinUtils.class);
+
+  // Error messages
+  private static final String _UNKNOWN_BASE_SKIN_ERROR =
+    "Unable to locate base skin: ";
+
+  static private final String _RENDER_KIT_ID_DESKTOP = "org.apache.myfaces.trinidad.desktop";
+  static private final String _RENDER_KIT_ID_PDA = "org.apache.myfaces.trinidad.pda";
+  static private final String _SIMPLE_PDA_SKIN_ID = "simple.pda";
+  static private final String _SIMPLE_DESKTOP_SKIN_ID = "simple.desktop";
 
 }

Added: incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinAdditionNode.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinAdditionNode.java?view=auto&rev=475104
==============================================================================
--- incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinAdditionNode.java (added)
+++ incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinAdditionNode.java Tue Nov 14 19:16:50 2006
@@ -0,0 +1,65 @@
+/*
+ * Copyright  2003-2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.myfaces.trinidadinternal.ui.laf.xml.parse;
+
+
+
+/**
+ * Object which represents a single &lt;skin-addition&gt; element in trinidad-skins.xml.
+ *
+ * @version $Name:  $ ($Revision: adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/ui/laf/xml/parse/SkinPropertyNode.java#0 $) $Date: 10-nov-2005.18:50:45 $
+ * @author The Oracle ADF Faces Team
+ */
+public class SkinAdditionNode
+{
+
+  /**
+   * 
+   */
+  public SkinAdditionNode (
+    String skinId,
+    String styleSheetName
+    )
+  {
+    _styleSheetName = styleSheetName;
+    _skinId = skinId;
+  }
+  
+  public String getSkinId()
+  {
+    return _skinId;
+  }  
+  
+  public void setSkinId(String id)
+  {
+    _skinId = id;
+  }
+  
+  public String getStyleSheetName()
+  {
+    return _styleSheetName;
+  } 
+  
+  public void setStyleSheetName(String ssName)
+  {
+    _styleSheetName = ssName;
+  }
+  
+  private String _skinId;
+  private String _styleSheetName;
+
+}
\ No newline at end of file

Added: incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinAdditionNodeParser.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinAdditionNodeParser.java?view=auto&rev=475104
==============================================================================
--- incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinAdditionNodeParser.java (added)
+++ incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinAdditionNodeParser.java Tue Nov 14 19:16:50 2006
@@ -0,0 +1,117 @@
+
+/*
+ * Copyright  2003-2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.myfaces.trinidadinternal.ui.laf.xml.parse;
+
+import java.util.ArrayList;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidadinternal.share.xml.StringParser;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXParseException;
+
+import org.apache.myfaces.trinidadinternal.share.xml.BaseNodeParser;
+import org.apache.myfaces.trinidadinternal.share.xml.NodeParser;
+import org.apache.myfaces.trinidadinternal.share.xml.ParseContext;
+
+import org.apache.myfaces.trinidad.skin.Skin;
+import org.apache.myfaces.trinidadinternal.skin.SkinExtension;
+
+import org.apache.myfaces.trinidadinternal.skin.SkinUtils;
+import org.apache.myfaces.trinidadinternal.ui.laf.xml.XMLConstants;
+
+/**
+ * NodeParser for &lt;skin-addition&gt; node in trinidad-skins.xml
+ *
+ * @version $Name:  $ ($Revision: adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/ui/laf/xml/parse/SkinExtensionParser.java#0 $) $Date: 10-nov-2005.18:50:44 $
+ * @author The Oracle ADF Faces Team
+ * @todo ELIMINATE NAMESPACE
+ */
+public class SkinAdditionNodeParser extends BaseNodeParser
+  implements XMLConstants
+{
+  @Override
+  public void startElement(
+    ParseContext context,
+    String       namespaceURI,
+    String       localName,
+    Attributes   attrs
+    ) throws SAXParseException
+  {
+  }
+
+  @Override
+  public Object endElement(
+    ParseContext context,
+    String       namespaceURI,
+    String       localName
+    ) throws SAXParseException
+  {
+
+    // id and family are required. log a severe error if they are null.
+    if ((_skinId == null) && (_LOG.isWarning()))
+      _LOG.severe("Required element 'skin-id' not found.");
+    if ((_styleSheetName == null) && (_LOG.isWarning()))
+      _LOG.severe("Required element 'style-sheet-name' not found.");
+
+      
+    return new SkinAdditionNode(_skinId, _styleSheetName);
+  }
+
+  @Override
+  public NodeParser startChildElement(
+    ParseContext context,
+    String       namespaceURI,
+    String       localName,
+    Attributes   attrs
+    ) throws SAXParseException
+  {
+  
+    if ("skin-id".equals(localName) ||
+        "style-sheet-name".equals(localName))
+
+    {
+      return new StringParser();
+    }
+
+    return null;
+  }
+
+  @Override
+  public void addCompletedChild(
+    ParseContext context,
+    String       namespaceURI,
+    String       localName,
+    Object       child
+    ) throws SAXParseException
+  {
+
+    if ("skin-id".equals(localName))
+      _skinId = (String) child;
+    else if ("style-sheet-name".equals(localName))
+      _styleSheetName = (String) child;
+  }
+
+
+  private String      _skinId;
+  private String      _styleSheetName;
+
+
+  private static final TrinidadLogger _LOG = 
+    TrinidadLogger.createTrinidadLogger(SkinAdditionNodeParser.class);
+
+}

Added: incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinNode.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinNode.java?view=auto&rev=475104
==============================================================================
--- incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinNode.java (added)
+++ incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinNode.java Tue Nov 14 19:16:50 2006
@@ -0,0 +1,117 @@
+/*
+ * Copyright  2003-2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.myfaces.trinidadinternal.ui.laf.xml.parse;
+
+
+
+
+/**
+ * Object which represents a single &lt;skin&gt; element in trinidad-skins.xml.
+ *
+ * @version $Name:  $ ($Revision: adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/ui/laf/xml/parse/SkinPropertyNode.java#0 $) $Date: 10-nov-2005.18:50:45 $
+ * @author The Oracle ADF Faces Team
+ */
+public class SkinNode
+{
+  /**
+   * 
+   */
+  public SkinNode (
+    String id,
+    String family,
+    String renderKitId,
+    String skinExtends,
+    String styleSheetName,
+    String bundleName)
+  {
+    
+    if (id==null)
+    {
+      throw new NullPointerException("Null id");
+    }    
+    if (family==null)
+    {
+      throw new NullPointerException("Null family");
+    }
+
+    _id = id;
+    _family = family;
+    _renderKitId = renderKitId;
+    _skinExtends = skinExtends;
+    _styleSheetName = styleSheetName;
+    _bundleName = bundleName;
+
+  }
+
+  /**
+   * Returns the skin id for this node
+   */
+  public String getId()
+  {
+    return _id ;
+  }
+
+  /**
+   * Returns the skin family for this node
+   */
+  public String getFamily()
+  {
+    return _family;
+  }
+
+  /**
+   * Returns the renderKitId for this node.
+   */
+  public String getRenderKitId()
+  {
+    return _renderKitId;
+  }
+  
+  /**
+   * Returns the skinExtends for this node.
+   */
+  public String getSkinExtends()
+  {
+    return _skinExtends;
+  } 
+  
+  /**
+   * Returns the styleSheetName for this node.
+   */
+  public String getStyleSheetName()
+  {
+    return _styleSheetName;
+  }  
+  
+  /**
+   * Returns the bundleName for this node.
+   */
+  public String getBundleName()
+  {
+    return _bundleName;
+  }  
+
+  
+  private String _id;
+  private String _family;
+  private String _renderKitId;
+  private String _skinExtends;
+  private String _styleSheetName;
+  private String _bundleName;
+
+
+}

Added: incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinNodeParser.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinNodeParser.java?view=auto&rev=475104
==============================================================================
--- incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinNodeParser.java (added)
+++ incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinNodeParser.java Tue Nov 14 19:16:50 2006
@@ -0,0 +1,137 @@
+
+/*
+ * Copyright  2003-2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.myfaces.trinidadinternal.ui.laf.xml.parse;
+
+import java.util.ArrayList;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidadinternal.share.xml.StringParser;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXParseException;
+
+import org.apache.myfaces.trinidadinternal.share.xml.BaseNodeParser;
+import org.apache.myfaces.trinidadinternal.share.xml.NodeParser;
+import org.apache.myfaces.trinidadinternal.share.xml.ParseContext;
+
+import org.apache.myfaces.trinidad.skin.Skin;
+import org.apache.myfaces.trinidadinternal.skin.SkinExtension;
+
+import org.apache.myfaces.trinidadinternal.skin.SkinUtils;
+import org.apache.myfaces.trinidadinternal.ui.laf.xml.XMLConstants;
+
+/**
+ * NodeParser for &lt;skin&gt; node in trinidad-skins.xml
+ *
+ * @version $Name:  $ ($Revision: adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/ui/laf/xml/parse/SkinExtensionParser.java#0 $) $Date: 10-nov-2005.18:50:44 $
+ * @author The Oracle ADF Faces Team
+ * @todo ELIMINATE NAMESPACE
+ */
+public class SkinNodeParser extends BaseNodeParser
+  implements XMLConstants
+{
+  @Override
+  public void startElement(
+    ParseContext context,
+    String       namespaceURI,
+    String       localName,
+    Attributes   attrs
+    ) throws SAXParseException
+  {
+    _namespace = namespaceURI;
+  }
+
+  @Override
+  public Object endElement(
+    ParseContext context,
+    String       namespaceURI,
+    String       localName
+    ) throws SAXParseException
+  {
+
+    // id and family are required. log a severe error if they are null.
+    if ((_id == null) && (_LOG.isWarning()))
+      _LOG.severe("Required element 'id' not found.");
+    if ((_family == null) && (_LOG.isWarning()))
+      _LOG.severe("Required element 'family' not found.");
+
+      
+    return new SkinNode(_id, _family, _renderKitId, _extends, _styleSheetName, _bundleName);
+  }
+
+  @Override
+  public NodeParser startChildElement(
+    ParseContext context,
+    String       namespaceURI,
+    String       localName,
+    Attributes   attrs
+    ) throws SAXParseException
+  {
+    if (!namespaceURI.equals(_namespace))
+      return null;
+
+    if ("id".equals(localName) ||
+        "family".equals(localName) ||
+        "render-kit-id".equals(localName) ||
+        "style-sheet-name".equals(localName) ||
+        "bundle-name".equals(localName) ||
+        "extends".equals(localName))
+
+    {
+      return new StringParser();
+    }
+
+    return null;
+  }
+
+  @Override
+  public void addCompletedChild(
+    ParseContext context,
+    String       namespaceURI,
+    String       localName,
+    Object       child
+    ) throws SAXParseException
+  {
+
+    if ("id".equals(localName))
+      _id = (String) child;
+    else if ("family".equals(localName))
+      _family = (String) child;
+    else if ("render-kit-id".equals(localName))
+      _renderKitId = (String) child;
+    else if ("style-sheet-name".equals(localName))
+      _styleSheetName = (String) child;
+    else if ("bundle-name".equals(localName))
+      _bundleName = (String) child;
+    else if ("extends".equals(localName))
+      _extends = (String) child;
+  }
+
+
+  private String      _namespace;
+  private String      _id;
+  private String      _family;
+  private String      _styleSheetName;
+  private String      _renderKitId;
+  private String      _bundleName;
+  private String      _extends;
+
+
+  private static final TrinidadLogger _LOG = 
+    TrinidadLogger.createTrinidadLogger(SkinNodeParser.class);
+
+}

Added: incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinsNode.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinsNode.java?view=auto&rev=475104
==============================================================================
--- incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinsNode.java (added)
+++ incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinsNode.java Tue Nov 14 19:16:50 2006
@@ -0,0 +1,60 @@
+/*
+ * Copyright  2003-2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.myfaces.trinidadinternal.ui.laf.xml.parse;
+
+import java.net.URL;
+
+import java.util.List;
+
+
+/**
+ * Object which represents the skin and skin-addition nodes in trinidad-skins.xml.
+ *
+ * @version $Name:  $ ($Revision: adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/ui/laf/xml/parse/SkinPropertyNode.java#0 $) $Date: 10-nov-2005.18:50:45 $
+ * @author The Oracle ADF Faces Team
+ */
+public class SkinsNode
+{
+  /**
+   * 
+   */
+  public SkinsNode(
+    List<SkinNode> skinNodes,
+    List<SkinAdditionNode> skinAdditionNodes)
+  {
+    _skinAdditionNodes = skinAdditionNodes;
+    _skinNodes = skinNodes;
+  }
+
+  /**
+   */
+  public List<SkinAdditionNode> getSkinAdditionNodes()
+  {
+    return _skinAdditionNodes;
+  }
+  /**
+   * 
+   */
+  public List<SkinNode> getSkinNodes()
+  {
+    return _skinNodes;
+  }
+  
+  private List<SkinAdditionNode> _skinAdditionNodes;
+  private List<SkinNode> _skinNodes;
+
+}

Modified: incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinsNodeParser.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinsNodeParser.java?view=diff&rev=475104&r1=475103&r2=475104
==============================================================================
--- incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinsNodeParser.java (original)
+++ incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/xml/parse/SkinsNodeParser.java Tue Nov 14 19:16:50 2006
@@ -18,6 +18,8 @@
 
 import java.util.ArrayList;
 
+import java.util.List;
+
 import org.apache.myfaces.trinidadinternal.skin.SkinExtension;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXParseException;
@@ -32,7 +34,7 @@
 import org.apache.myfaces.trinidadinternal.ui.laf.xml.XMLConstants;
 
 /**
- * NodeParser for <skins> elements
+ * NodeParser for &lt;skins&gt; element in trinidad-skins.xml
  *
  * @version $Name:  $ ($Revision: adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/ui/laf/xml/parse/SkinsNodeParser.java#0 $) $Date: 10-nov-2005.18:50:46 $
  * @author The Oracle ADF Faces Team
@@ -48,7 +50,10 @@
     Attributes   attrs
     ) throws SAXParseException
   {
-    return context.getParser(SkinExtension.class, namespaceURI, localName);
+    if ("skin-addition".equals(localName))
+      return context.getParser(SkinAdditionNode.class, namespaceURI, localName);
+    else
+      return context.getParser(SkinNode.class, namespaceURI, localName);
   }
 
   @Override
@@ -59,19 +64,14 @@
     Object       child
     ) throws SAXParseException
   {
-    assert ((child == null) || (child instanceof SkinExtension));
-
-    SkinExtension skinExtension = (SkinExtension)child;
-    
-    // register skin with factory, this way when we create each skin
-    // in SkinExtensionParser, we can extend any skin that has already
-    // been registered with the skin factory.
-    SkinFactory skinFactory = SkinUtils.getSkinFactory(context);
-    skinFactory.addSkin(skinExtension.getId(), skinExtension);
+    assert ((child == null) || 
+            (child instanceof SkinNode) ||
+            (child instanceof SkinAdditionNode));
     
-    // add to list
-    if (child instanceof SkinExtension)
-      _skins.add((SkinExtension)child);
+    if ((child instanceof SkinAdditionNode))    
+      _skinAdditions.add((SkinAdditionNode)child);
+    else
+      _skins.add((SkinNode)child);
   }
 
   @Override
@@ -81,13 +81,11 @@
     String       localName
     ) throws SAXParseException
   {
-    if (_skins.isEmpty())
-      return null;
-
-    SkinExtension[] skinExtension = new SkinExtension[_skins.size()];
-
-    return _skins.toArray(skinExtension);
+    return new SkinsNode(_skins,
+                         _skinAdditions);
   }
 
-  private ArrayList<SkinExtension> _skins = new ArrayList<SkinExtension>();
+  private List<SkinNode> _skins = new ArrayList<SkinNode>();
+  private List<SkinAdditionNode> _skinAdditions = new ArrayList<SkinAdditionNode>();
+  
 }

Modified: incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/webapp/TrinidadFilterImpl.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/webapp/TrinidadFilterImpl.java?view=diff&rev=475104&r1=475103&r2=475104
==============================================================================
--- incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/webapp/TrinidadFilterImpl.java (original)
+++ incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/webapp/TrinidadFilterImpl.java Tue Nov 14 19:16:50 2006
@@ -137,12 +137,11 @@
       f.init(filterConfig);
     }
     // after the 'services' filters are initialized, then register
-    // the skin extensions found in trinidad-skins.xml. This
-    // gives a chance to the 'services' filters to create more base
+    // the skin extensions & skin additions found in trinidad-skins.xml. 
+    // This gives a chance to the 'services' filters to create more base
     // skins that the skins in trinidad-skins.xml can extend.
     SkinUtils.registerSkinExtensions(_servletContext);
 
-    
   }
 
   public void destroy()