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/11/26 21:32:42 UTC

svn commit: r1039554 [1/4] - in /myfaces/core/trunk/impl/src: main/java/org/apache/myfaces/application/ main/java/org/apache/myfaces/config/ main/java/org/apache/myfaces/config/annotation/ main/java/org/apache/myfaces/config/element/ main/java/org/apac...

Author: lu4242
Date: Fri Nov 26 20:32:39 2010
New Revision: 1039554

URL: http://svn.apache.org/viewvc?rev=1039554&view=rev
Log:
MYFACES-2945 Make a way to get the FacesConfig from a provider

Added:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/DefaultFacesConfigurationProvider.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/AbsoluteOrdering.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/Application.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/Attribute.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/Component.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ConfigOthersSlot.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/Converter.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesConfig.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesConfigData.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesConfigNameSlot.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/Factory.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/LocaleConfig.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/NamedEvent.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/OrderSlot.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/Ordering.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/Property.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/RenderKit.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ResourceBundle.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/SystemEventListener.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationProvider.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationProviderFactory.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultFacesConfigurationProviderFactory.java
Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigDispenser.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/RuntimeConfig.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/annotation/AnnotationConfigurator.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/Behavior.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ClientBehaviorRenderer.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ListEntries.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ListEntry.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ManagedBean.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ManagedProperty.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/MapEntries.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/MapEntry.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/NavigationCase.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/NavigationRule.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/Redirect.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/Renderer.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ViewParam.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/DigesterFacesConfigDispenserImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/DigesterFacesConfigUnmarshallerImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/AbsoluteOrdering.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/Application.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/Attribute.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/Behavior.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ClientBehaviorRenderer.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/Component.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ConfigOthersSlot.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/Converter.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesConfig.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesConfigNameSlot.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/Factory.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ListEntries.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/LocaleConfig.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ManagedBean.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ManagedProperty.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/MapEntries.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/NamedEvent.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/NavigationCase.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/NavigationRule.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/OrderSlot.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/Ordering.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/Property.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/Redirect.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/RenderKit.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/Renderer.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ResourceBundle.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/SystemEventListener.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ViewParam.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/ResourceBundleResolver.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/config/FacesConfigValidatorTestCase.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/config/OrderingFacesConfigTest.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/config/impl/digister/DigesterFacesConfigUnmarshallerImplTest.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/FaceletTestCase.java

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java?rev=1039554&r1=1039553&r2=1039554&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java Fri Nov 26 20:32:39 2010
@@ -22,8 +22,8 @@ import org.apache.commons.beanutils.Bean
 import org.apache.myfaces.application.jsp.JspStateManagerImpl;
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
 import org.apache.myfaces.config.RuntimeConfig;
-import org.apache.myfaces.config.impl.digester.elements.Property;
-import org.apache.myfaces.config.impl.digester.elements.ResourceBundle;
+import org.apache.myfaces.config.element.Property;
+import org.apache.myfaces.config.element.ResourceBundle;
 import org.apache.myfaces.context.RequestViewContext;
 import org.apache.myfaces.el.PropertyResolverImpl;
 import org.apache.myfaces.el.VariableResolverToApplicationELResolverAdapter;
@@ -1498,7 +1498,7 @@ public class ApplicationImpl extends App
 
     private void setConverterProperties(final Class<?> converterClass, final Converter converter)
     {
-        final org.apache.myfaces.config.impl.digester.elements.Converter converterConfig = _runtimeConfig
+        final org.apache.myfaces.config.element.Converter converterConfig = _runtimeConfig
                 .getConverterConfiguration(converterClass.getName());
         
         // if the converter is a DataTimeConverter, check the init param for the default timezone (since 2.0)

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/DefaultFacesConfigurationProvider.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/DefaultFacesConfigurationProvider.java?rev=1039554&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/DefaultFacesConfigurationProvider.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/DefaultFacesConfigurationProvider.java Fri Nov 26 20:32:39 2010
@@ -0,0 +1,1428 @@
+/*
+ * 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.config;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.faces.FacesException;
+import javax.faces.FactoryFinder;
+import javax.faces.context.ExternalContext;
+import javax.faces.webapp.FacesServlet;
+
+import org.apache.myfaces.config.annotation.AnnotationConfigurator;
+import org.apache.myfaces.config.element.ConfigOthersSlot;
+import org.apache.myfaces.config.element.FacesConfig;
+import org.apache.myfaces.config.element.FacesConfigData;
+import org.apache.myfaces.config.element.FacesConfigNameSlot;
+import org.apache.myfaces.config.element.OrderSlot;
+import org.apache.myfaces.config.element.Ordering;
+import org.apache.myfaces.config.impl.digester.DigesterFacesConfigDispenserImpl;
+import org.apache.myfaces.config.impl.digester.DigesterFacesConfigUnmarshallerImpl;
+import org.apache.myfaces.config.util.CyclicDependencyException;
+import org.apache.myfaces.config.util.DirectedAcyclicGraphVerifier;
+import org.apache.myfaces.config.util.Vertex;
+import org.apache.myfaces.shared_impl.config.MyfacesConfig;
+import org.apache.myfaces.shared_impl.util.ClassUtils;
+import org.apache.myfaces.spi.FacesConfigResourceProvider;
+import org.apache.myfaces.spi.FacesConfigResourceProviderFactory;
+import org.apache.myfaces.spi.FacesConfigurationProvider;
+import org.xml.sax.SAXException;
+
+/**
+ * 
+ * @author Leonardo Uribe
+ * @since 2.0.3
+ */
+public class DefaultFacesConfigurationProvider extends FacesConfigurationProvider
+{
+
+    private static final String STANDARD_FACES_CONFIG_RESOURCE = "META-INF/standard-faces-config.xml";
+    
+    private static final String META_INF_SERVICES_RESOURCE_PREFIX = "META-INF/services/";
+
+    private static final String DEFAULT_FACES_CONFIG = "/WEB-INF/faces-config.xml";
+
+    private static final Set<String> FACTORY_NAMES = new HashSet<String>();
+    {
+        FACTORY_NAMES.add(FactoryFinder.APPLICATION_FACTORY);
+        FACTORY_NAMES.add(FactoryFinder.EXCEPTION_HANDLER_FACTORY);
+        FACTORY_NAMES.add(FactoryFinder.EXTERNAL_CONTEXT_FACTORY);
+        FACTORY_NAMES.add(FactoryFinder.FACES_CONTEXT_FACTORY);
+        FACTORY_NAMES.add(FactoryFinder.LIFECYCLE_FACTORY);
+        FACTORY_NAMES.add(FactoryFinder.RENDER_KIT_FACTORY);
+        FACTORY_NAMES.add(FactoryFinder.TAG_HANDLER_DELEGATE_FACTORY);
+        FACTORY_NAMES.add(FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY);
+        FACTORY_NAMES.add(FactoryFinder.VISIT_CONTEXT_FACTORY);
+        FACTORY_NAMES.add(FactoryFinder.VIEW_DECLARATION_LANGUAGE_FACTORY);
+    }
+
+    private static final Logger log = Logger.getLogger(DefaultFacesConfigurationProvider.class.getName());
+
+    private FacesConfigUnmarshaller<? extends FacesConfig> _unmarshaller;
+    
+    private AnnotationConfigurator _annotationConfigurator;
+
+    private FacesConfigDispenser _dispenser;
+
+    protected void setUnmarshaller(ExternalContext ectx, FacesConfigUnmarshaller<? extends FacesConfig> unmarshaller)
+    {
+        _unmarshaller = unmarshaller;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected FacesConfigUnmarshaller<? extends FacesConfig> getUnmarshaller(ExternalContext ectx)
+    {
+        if (_unmarshaller == null)
+        {
+            _unmarshaller = new DigesterFacesConfigUnmarshallerImpl(ectx);
+        }
+        return _unmarshaller;
+    }
+    
+    /**
+     * @param dispenser
+     *            the dispenser to set
+     */
+    protected void setDispenser(FacesConfigDispenser dispenser)
+    {
+        _dispenser = dispenser;
+    }
+
+    /**
+     * @return the dispenser
+     */
+    protected FacesConfigDispenser getDispenser()
+    {
+        if (_dispenser == null)
+        {
+            _dispenser = new DigesterFacesConfigDispenserImpl();
+        }
+
+        return _dispenser;
+    }
+    
+    protected void setAnnotationConfigurator(AnnotationConfigurator configurator)
+    {
+        _annotationConfigurator = configurator;
+    }
+    
+    protected AnnotationConfigurator getAnnotationConfigurator()
+    {
+        if (_annotationConfigurator == null)
+        {
+            _annotationConfigurator = new AnnotationConfigurator();
+        }
+        return _annotationConfigurator;
+    }
+
+
+    protected FacesConfig getStandardFacesConfig(ExternalContext ectx)
+    {
+        try
+        {
+            if (MyfacesConfig.getCurrentInstance(ectx).isValidateXML())
+            {
+                URL url = ClassUtils.getContextClassLoader().getResource(STANDARD_FACES_CONFIG_RESOURCE);
+                if (url == null)
+                {
+                    url = this.getClass().getResource(STANDARD_FACES_CONFIG_RESOURCE);
+                }
+                if (url != null)
+                {
+                    validateFacesConfig(ectx, url);
+                }
+            }
+            InputStream stream = ClassUtils.getResourceAsStream(STANDARD_FACES_CONFIG_RESOURCE);
+            if (stream == null)
+                throw new FacesException("Standard faces config " + STANDARD_FACES_CONFIG_RESOURCE + " not found");
+            if (log.isLoggable(Level.INFO))
+                log.info("Reading standard config " + STANDARD_FACES_CONFIG_RESOURCE);
+            
+            FacesConfig facesConfig = getUnmarshaller(ectx).getFacesConfig(stream, STANDARD_FACES_CONFIG_RESOURCE);
+            stream.close();
+            return facesConfig;
+        }
+        catch (IOException e)
+        {
+            throw new FacesException(e);
+        }
+        catch (SAXException e)
+        {
+            throw new FacesException(e);
+        }
+    }
+
+
+    protected FacesConfig getAnnotationsFacesConfig(ExternalContext ectx, boolean metadataComplete)
+    {
+        return getAnnotationConfigurator().createFacesConfig(ectx, metadataComplete);
+    }
+
+    /**
+     * This method performs part of the factory search outlined in section 10.2.6.1.
+     */
+    protected FacesConfig getMetaInfServicesFacesConfig(ExternalContext ectx)
+    {
+        try
+        {
+            org.apache.myfaces.config.impl.digester.elements.FacesConfig facesConfig = new org.apache.myfaces.config.impl.digester.elements.FacesConfig();
+            org.apache.myfaces.config.impl.digester.elements.Factory factory = new org.apache.myfaces.config.impl.digester.elements.Factory();
+            facesConfig.addFactory(factory);
+            for (String factoryName : FACTORY_NAMES)
+            {
+                Iterator<URL> it = ClassUtils.getResources(META_INF_SERVICES_RESOURCE_PREFIX + factoryName, this);
+                while (it.hasNext())
+                {
+                    URL url = it.next();
+                    InputStream stream = openStreamWithoutCache(url);
+                    InputStreamReader isr = new InputStreamReader(stream);
+                    BufferedReader br = new BufferedReader(isr);
+                    String className;
+                    try
+                    {
+                        className = br.readLine();
+                    }
+                    catch (IOException e)
+                    {
+                        throw new FacesException("Unable to read class name from file " + url.toExternalForm(), e);
+                    }
+                    finally
+                    {
+                        if (br != null)
+                        {
+                            br.close();
+                        }
+                        if (isr != null)
+                        {
+                            isr.close();
+                        }
+                        if (stream != null)
+                        {
+                            stream.close();
+                        }
+                    }
+
+
+                    if (log.isLoggable(Level.INFO))
+                    {
+                        log.info("Found " + factoryName + " factory implementation: " + className);
+                    }
+
+                    if (factoryName.equals(FactoryFinder.APPLICATION_FACTORY))
+                    {
+                        factory.addApplicationFactory(className);
+                    } else if (factoryName.equals(FactoryFinder.EXTERNAL_CONTEXT_FACTORY))
+                    {
+                        factory.addExternalContextFactory(className);
+                    } else if (factoryName.equals(FactoryFinder.FACES_CONTEXT_FACTORY))
+                    {
+                        factory.addFacesContextFactory(className);
+                    } else if (factoryName.equals(FactoryFinder.LIFECYCLE_FACTORY))
+                    {
+                        factory.addLifecycleFactory(className);
+                    } else if (factoryName.equals(FactoryFinder.RENDER_KIT_FACTORY))
+                    {
+                        factory.addRenderkitFactory(className);
+                    } else if (factoryName.equals(FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY))
+                    {
+                        factory.addPartialViewContextFactory(className);
+                    } else if(factoryName.equals(FactoryFinder.VISIT_CONTEXT_FACTORY)) 
+                    {
+                        factory.addVisitContextFactory(className);
+                    } else
+                    {
+                        throw new IllegalStateException("Unexpected factory name " + factoryName);
+                    }
+                }
+            }
+            return facesConfig;
+        }
+        catch (Throwable e)
+        {
+            throw new FacesException(e);
+        }
+    }
+
+    private InputStream openStreamWithoutCache(URL url) throws IOException
+    {
+        URLConnection connection = url.openConnection();
+        connection.setUseCaches(false);
+        return connection.getInputStream();
+    }
+
+    /**
+     * This method fixes MYFACES-208
+     */
+    protected List<FacesConfig> getClassloaderFacesConfig(ExternalContext ectx)
+    {
+        List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
+        try
+        {
+            FacesConfigResourceProvider provider = FacesConfigResourceProviderFactory.
+                getFacesConfigResourceProviderFactory(ectx).createFacesConfigResourceProvider(ectx);
+            
+            Collection<URL> facesConfigs = provider.getMetaInfConfigurationResources(ectx);
+            
+            for (URL url : facesConfigs)
+            {
+                if (MyfacesConfig.getCurrentInstance(ectx).isValidateXML())
+                {
+                    validateFacesConfig(ectx, url);
+                }
+                InputStream stream = null;
+                try
+                {
+                    stream = openStreamWithoutCache(url);
+                    if (log.isLoggable(Level.INFO))
+                    {
+                        log.info("Reading config : " + url.toExternalForm());
+                    }
+                    appConfigResources.add(getUnmarshaller(ectx).getFacesConfig(stream, url.toExternalForm()));
+                    //getDispenser().feed(getUnmarshaller().getFacesConfig(stream, entry.getKey()));
+                }
+                finally
+                {
+                    if (stream != null)
+                    {
+                        stream.close();
+                    }
+                }
+            }
+        }
+        catch (Throwable e)
+        {
+            throw new FacesException(e);
+        }
+        return appConfigResources;
+    }
+
+    protected List<FacesConfig> getContextSpecifiedFacesConfig(ExternalContext ectx)
+    {
+        List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
+        try
+        {
+            for (String systemId : getConfigFilesList(ectx))
+            {
+                if (MyfacesConfig.getCurrentInstance(ectx).isValidateXML())
+                {
+                    URL url = ectx.getResource(systemId);
+                    if (url != null)
+                    {
+                        validateFacesConfig(ectx, url);
+                    }
+                }            
+                InputStream stream = ectx.getResourceAsStream(systemId);
+                if (stream == null)
+                {
+                    log.severe("Faces config resource " + systemId + " not found");
+                    continue;
+                }
+    
+                if (log.isLoggable(Level.INFO))
+                {
+                    log.info("Reading config " + systemId);
+                }
+                appConfigResources.add(getUnmarshaller(ectx).getFacesConfig(stream, systemId));
+                //getDispenser().feed(getUnmarshaller().getFacesConfig(stream, systemId));
+                stream.close();
+            }
+        }
+        catch (Throwable e)
+        {
+            throw new FacesException(e);
+        }
+        return appConfigResources;
+    }
+    
+    private List<String> getConfigFilesList(ExternalContext ectx) {
+        String configFiles = ectx.getInitParameter(FacesServlet.CONFIG_FILES_ATTR);
+        List<String> configFilesList = new ArrayList<String>();
+        if (configFiles != null)
+        {
+            StringTokenizer st = new StringTokenizer(configFiles, ",", false);
+            while (st.hasMoreTokens())
+            {
+                String systemId = st.nextToken().trim();
+
+                if (DEFAULT_FACES_CONFIG.equals(systemId))
+                {
+                    if (log.isLoggable(Level.WARNING))
+                    {
+                        log.warning(DEFAULT_FACES_CONFIG + " has been specified in the " + FacesServlet.CONFIG_FILES_ATTR
+                                + " context parameter of "
+                                + "the deployment descriptor. This will automatically be removed, "
+                                + "if we wouldn't do this, it would be loaded twice.  See JSF spec 1.1, 10.3.2");
+                    }
+                }
+                else
+                {
+                    configFilesList.add(systemId);
+                }
+            }
+        }
+        return configFilesList;
+    }
+
+    protected FacesConfig getWebAppFacesConfig(ExternalContext ectx)
+    {
+        try
+        {
+            FacesConfig webAppConfig = null;
+            // web application config
+            if (MyfacesConfig.getCurrentInstance(ectx).isValidateXML())
+            {
+                URL url = ectx.getResource(DEFAULT_FACES_CONFIG);
+                if (url != null)
+                {
+                    validateFacesConfig(ectx, url);
+                }
+            }
+            InputStream stream = ectx.getResourceAsStream(DEFAULT_FACES_CONFIG);
+            if (stream != null)
+            {
+                if (log.isLoggable(Level.INFO))
+                    log.info("Reading config /WEB-INF/faces-config.xml");
+                webAppConfig = getUnmarshaller(ectx).getFacesConfig(stream, DEFAULT_FACES_CONFIG);
+                //getDispenser().feed(getUnmarshaller().getFacesConfig(stream, DEFAULT_FACES_CONFIG));
+                stream.close();
+            }
+            return webAppConfig;
+        }
+        catch (IOException e)
+        {
+            throw new FacesException(e);
+        }
+        catch (SAXException e)
+        {
+            throw new FacesException(e);
+        }
+
+    }
+    
+    private void validateFacesConfig(ExternalContext ectx, URL url) throws IOException, SAXException
+    {
+        String version = ConfigFilesXmlValidationUtils.getFacesConfigVersion(url);
+        if ("1.2".equals(version) || "2.0".equals(version))
+        {
+            ConfigFilesXmlValidationUtils.validateFacesConfigFile(url, ectx, version);                
+        }
+    }
+    
+    protected void orderAndFeedArtifacts(List<FacesConfig> appConfigResources, FacesConfig webAppConfig)
+        throws FacesException
+    {
+        if (webAppConfig != null && webAppConfig.getAbsoluteOrdering() != null)
+        {
+            if (webAppConfig.getOrdering() != null)
+            {
+                if (log.isLoggable(Level.WARNING))
+                {
+                    log.warning("<ordering> element found in application faces config. " +
+                            "This description will be ignored and the actions described " +
+                            "in <absolute-ordering> element will be taken into account instead.");
+                }                
+            }
+            //Absolute ordering
+            
+            //1. Scan all appConfigResources and create a list
+            //containing all resources not mentioned directly, preserving the
+            //order founded
+            List<FacesConfig> othersResources = new ArrayList<FacesConfig>();
+            List<OrderSlot> slots = webAppConfig.getAbsoluteOrdering().getOrderList();
+            for (FacesConfig resource : appConfigResources)
+            {
+                // First condition: if faces-config.xml does not have name it is 1) pre-JSF-2.0 or 2) has no <name> element,
+                // -> in both cases cannot be ordered
+                // Second condition : faces-config.xml has a name but <ordering> element does not have slot with that name
+                //  -> resource can be ordered, but will fit into <others /> element
+                if ((resource.getName() == null) || (resource.getName() != null && !containsResourceInSlot(slots, resource.getName())))
+                {
+                    othersResources.add(resource);
+                }
+            }
+            
+            //2. Scan slot by slot and merge information according
+            for (OrderSlot slot : webAppConfig.getAbsoluteOrdering().getOrderList())
+            {
+                if (slot instanceof ConfigOthersSlot)
+                {
+                    //Add all mentioned in othersResources
+                    for (FacesConfig resource : othersResources)
+                    {
+                        getDispenser().feed(resource);
+                    }
+                }
+                else
+                {
+                    //Add it to the sorted list
+                    FacesConfigNameSlot nameSlot = (FacesConfigNameSlot) slot;
+                    getDispenser().feed(getFacesConfig(appConfigResources, nameSlot.getName()));
+                }
+            }
+        }
+        else if (!appConfigResources.isEmpty())
+        {
+            //Relative ordering
+            for (FacesConfig resource : appConfigResources)
+            {
+                if (resource.getAbsoluteOrdering() != null)
+                {
+                    if (log.isLoggable(Level.WARNING))
+                    {
+                        log.warning("<absolute-ordering> element found in application " +
+                                "configuration resource "+resource.getName()+". " +
+                                "This description will be ignored and the actions described " +
+                                "in <ordering> elements will be taken into account instead.");
+                    }
+                }
+            }
+            
+            List<FacesConfig> postOrderedList = getPostOrderedList(appConfigResources);
+            
+            List<FacesConfig> sortedList = sortRelativeOrderingList(postOrderedList);
+            
+            if (sortedList == null)
+            {
+                //The previous algorithm can't sort correctly, try this one
+                sortedList = applySortingAlgorithm(appConfigResources);
+            }
+            
+            for (FacesConfig resource : sortedList)
+            {
+                //Feed
+                getDispenser().feed(resource);
+            }            
+        }
+        
+        if(webAppConfig != null)    //add null check for apps which don't have a faces-config.xml (e.g. tomahawk examples for 1.1/1.2)
+        {
+            getDispenser().feed(webAppConfig);
+        }
+    }
+
+    /**
+     * Sort using topological ordering algorithm.
+     * 
+     * @param appConfigResources
+     * @return
+     * @throws FacesException
+     */
+    protected List<FacesConfig> applySortingAlgorithm(List<FacesConfig> appConfigResources) throws FacesException
+    {
+        
+        //0. Convert the references into a graph
+        List<Vertex<FacesConfig>> vertexList = new ArrayList<Vertex<FacesConfig>>();
+        for (FacesConfig config : appConfigResources)
+        {
+            Vertex<FacesConfig> v = null;
+            if (config.getName() != null)
+            {
+                v = new Vertex<FacesConfig>(config.getName(), config);
+            }
+            else
+            {
+                v = new Vertex<FacesConfig>(config);
+            }
+            vertexList.add(v);
+        }
+        
+        //1. Resolve dependencies (before-after rules) and mark referenced vertex
+        boolean[] referencedVertex = new boolean[vertexList.size()];
+        
+        for (int i = 0; i < vertexList.size(); i++)
+        {
+            Vertex<FacesConfig> v = vertexList.get(i);
+            FacesConfig f = (FacesConfig) v.getNode();
+            
+            if (f.getOrdering() != null)
+            {
+                for (OrderSlot slot : f.getOrdering().getBeforeList())
+                {
+                    if (slot instanceof FacesConfigNameSlot)
+                    {
+                        String name = ((FacesConfigNameSlot) slot).getName();
+                        int j = DirectedAcyclicGraphVerifier.findVertex(vertexList, name);
+                        Vertex<FacesConfig> v1 = vertexList.get(j);
+                        if (v1 != null)
+                        {
+                            referencedVertex[i] = true;
+                            referencedVertex[j] = true;
+                            v1.addDependency(v);
+                        }
+                    }
+                }
+                for (OrderSlot slot : f.getOrdering().getAfterList())
+                {
+                    if (slot instanceof FacesConfigNameSlot)
+                    {
+                        String name = ((FacesConfigNameSlot) slot).getName();
+                        int j = DirectedAcyclicGraphVerifier.findVertex(vertexList, name);
+                        Vertex<FacesConfig> v1 = vertexList.get(j);
+                        if (v1 != null)
+                        {
+                            referencedVertex[i] = true;
+                            referencedVertex[j] = true;
+                            v.addDependency(v1);
+                        }
+                    }
+                }
+            }
+        }
+        
+        //2. Classify into categories
+        List<Vertex<FacesConfig>> beforeAfterOthersList = new ArrayList<Vertex<FacesConfig>>();
+        List<Vertex<FacesConfig>> othersList = new ArrayList<Vertex<FacesConfig>>();
+        List<Vertex<FacesConfig>> referencedList = new ArrayList<Vertex<FacesConfig>>();
+        
+        for (int i = 0; i < vertexList.size(); i++)
+        {
+            if (!referencedVertex[i])
+            {
+                Vertex<FacesConfig> v = vertexList.get(i);
+                FacesConfig f = (FacesConfig) v.getNode();
+                boolean added = false;
+                if (f.getOrdering() != null)
+                {
+                    if (!f.getOrdering().getBeforeList().isEmpty())
+                    {
+                        added = true;
+                        beforeAfterOthersList.add(v);
+                    }
+                    else if (!f.getOrdering().getAfterList().isEmpty())
+                    {
+                        added = true;
+                        beforeAfterOthersList.add(v);
+                    }
+                }
+                if (!added)
+                {
+                    othersList.add(v);
+                }
+            }
+            else
+            {
+                referencedList.add(vertexList.get(i));
+            }
+        }
+        
+        //3. Sort all referenced nodes
+        try
+        {
+            DirectedAcyclicGraphVerifier.topologicalSort(referencedList);
+        }
+        catch (CyclicDependencyException e)
+        {
+            e.printStackTrace();
+        }
+        
+        //4. Add referenced nodes
+        List<FacesConfig> sortedList = new ArrayList<FacesConfig>();
+        for (Vertex<FacesConfig> v : referencedList)
+        {
+            sortedList.add((FacesConfig)v.getNode());
+        }
+        
+        //5. add nodes without instructions at the end
+        for (Vertex<FacesConfig> v : othersList)
+        {
+            sortedList.add((FacesConfig)v.getNode());
+        }
+        
+        //6. add before/after nodes
+        for (Vertex<FacesConfig> v : beforeAfterOthersList)
+        {
+            FacesConfig f = (FacesConfig) v.getNode();
+            boolean added = false;
+            if (f.getOrdering() != null)
+            {
+                if (!f.getOrdering().getBeforeList().isEmpty())
+                {
+                    added = true;
+                    sortedList.add(0,f);
+                }
+            }
+            if (!added)
+            {
+                sortedList.add(f);
+            }            
+        }
+        
+        //Check
+        for (int i = 0; i < sortedList.size(); i++)
+        {
+            FacesConfig resource = sortedList.get(i);
+            
+            if (resource.getOrdering() != null)
+            {
+                for (OrderSlot slot : resource.getOrdering().getBeforeList())
+                {
+                    if (slot instanceof FacesConfigNameSlot)
+                    {
+                        String name = ((FacesConfigNameSlot) slot).getName();
+                        if (name != null && !"".equals(name))
+                        {
+                            boolean founded = false;
+                            for (int j = i-1; j >= 0; j--)
+                            {
+                                if (name.equals(sortedList.get(j).getName()))
+                                {
+                                    founded=true;
+                                    break;
+                                }
+                            }
+                            if (founded)
+                            {
+                                log.severe("Circular references detected when sorting " +
+                                          "application config resources. Use absolute ordering instead.");
+                                throw new FacesException("Circular references detected when sorting " +
+                                        "application config resources. Use absolute ordering instead.");
+                            }
+                        }
+                    }
+                }
+                for (OrderSlot slot : resource.getOrdering().getAfterList())
+                {
+                    if (slot instanceof FacesConfigNameSlot)
+                    {
+                        String name = ((FacesConfigNameSlot) slot).getName();
+                        if (name != null && !"".equals(name))
+                        {
+                            boolean founded = false;
+                            for (int j = i+1; j < sortedList.size(); j++)
+                            {
+                                if (name.equals(sortedList.get(j).getName()))
+                                {
+                                    founded=true;
+                                    break;
+                                }
+                            }
+                            if (founded)
+                            {
+                                log.severe("Circular references detected when sorting " +
+                                    "application config resources. Use absolute ordering instead.");
+                                throw new FacesException("Circular references detected when sorting " +
+                                    "application config resources. Use absolute ordering instead.");
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        
+        return sortedList;
+    }
+    
+    /**
+     * Sort a list of pre ordered elements. It scans one by one the elements
+     * and apply the conditions mentioned by Ordering object if it is available.
+     * 
+     * The preOrderedList ensures that application config resources referenced by
+     * other resources are processed first, making more easier the sort procedure. 
+     * 
+     * @param preOrderedList
+     * @return
+     */
+    protected List<FacesConfig> sortRelativeOrderingList(List<FacesConfig> preOrderedList)
+    {
+        List<FacesConfig> sortedList = new ArrayList<FacesConfig>();
+        
+        for (int i=0; i < preOrderedList.size(); i++)
+        {
+            FacesConfig resource = preOrderedList.get(i);
+            if (resource.getOrdering() != null)
+            {
+                if (resource.getOrdering().getBeforeList().isEmpty() &&
+                    resource.getOrdering().getAfterList().isEmpty())
+                {
+                    //No order rules, just put it as is
+                    sortedList.add(resource);
+                }
+                else if (resource.getOrdering().getBeforeList().isEmpty())
+                {
+                    //Only after rules
+                    applyAfterRule(sortedList, resource);
+                }
+                else if (resource.getOrdering().getAfterList().isEmpty())
+                {
+                    //Only before rules
+                    
+                    //Resolve if there is a later reference to this node before
+                    //apply it
+                    boolean referenceNode = false;
+
+                    for (int j = i+1; j < preOrderedList.size(); j++)
+                    {
+                        FacesConfig pointingResource = preOrderedList.get(j);
+                        for (OrderSlot slot : pointingResource.getOrdering().getBeforeList())
+                        {
+                            if (slot instanceof FacesConfigNameSlot &&
+                                    resource.getName().equals(((FacesConfigNameSlot)slot).getName()) )
+                            {
+                                referenceNode = true;
+                            }
+                            if (slot instanceof ConfigOthersSlot)
+                            {
+                                //No matter if there is a reference, because this rule
+                                //is not strict and before other ordering is unpredictable.
+                                //
+                                referenceNode = false;
+                                break;
+                            }
+                        }
+                        if (referenceNode)
+                        {
+                            break;
+                        }
+                        for (OrderSlot slot : pointingResource.getOrdering().getAfterList())
+                        {
+                            if (slot instanceof FacesConfigNameSlot &&
+                                resource.getName().equals(((FacesConfigNameSlot)slot).getName()) )
+                            {
+                                referenceNode = true;
+                                break;
+                            }
+                        }
+                    }
+                    
+                    applyBeforeRule(sortedList, resource, referenceNode);
+                }
+                else
+                {
+                    //Both before and after rules
+                    //In this case we should compare before and after rules
+                    //and the one with names takes precedence over the other one.
+                    //It both have names references, before rules takes
+                    //precedence over after
+                    //after some action is applied a check of the condition is made.
+                    int beforeWeight = 0;
+                    int afterWeight = 0;
+                    for (OrderSlot slot : resource.getOrdering()
+                            .getBeforeList())
+                    {
+                        if (slot instanceof FacesConfigNameSlot)
+                        {
+                            beforeWeight++;
+                        }
+                    }
+                    for (OrderSlot slot : resource.getOrdering()
+                            .getAfterList())
+                    {
+                        if (slot instanceof FacesConfigNameSlot)
+                        {
+                            afterWeight++;
+                        }
+                    }
+                    
+                    if (beforeWeight >= afterWeight)
+                    {
+                        applyBeforeRule(sortedList, resource,false);
+                    }
+                    else
+                    {
+                        applyAfterRule(sortedList, resource);
+                    }
+                    
+                    
+                }
+            }
+            else
+            {
+                //No order rules, just put it as is
+                sortedList.add(resource);
+            }
+        }
+        
+        //Check
+        for (int i = 0; i < sortedList.size(); i++)
+        {
+            FacesConfig resource = sortedList.get(i);
+            
+            if (resource.getOrdering() != null)
+            {
+                for (OrderSlot slot : resource.getOrdering().getBeforeList())
+                {
+                    if (slot instanceof FacesConfigNameSlot)
+                    {
+                        String name = ((FacesConfigNameSlot) slot).getName();
+                        if (name != null && !"".equals(name))
+                        {
+                            boolean founded = false;                                
+                            for (int j = i-1; j >= 0; j--)
+                            {
+                                if (name.equals(sortedList.get(j).getName()))
+                                {
+                                    founded=true;
+                                    break;
+                                }
+                            }
+                            if (founded)
+                            {
+                                //Cyclic reference
+                                return null;
+                            }
+                        }
+                    }
+                }
+                for (OrderSlot slot : resource.getOrdering().getAfterList())
+                {
+                    if (slot instanceof FacesConfigNameSlot)
+                    {
+                        String name = ((FacesConfigNameSlot) slot).getName();
+                        if (name != null && !"".equals(name))
+                        {
+                            boolean founded = false;                                
+                            for (int j = i+1; j < sortedList.size(); j++)
+                            {
+                                if (name.equals(sortedList.get(j).getName()))
+                                {
+                                    founded=true;
+                                    break;
+                                }
+                            }
+                            if (founded)
+                            {
+                                //Cyclic reference
+                                return null;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        
+        return sortedList;
+    }
+    
+    private void applyBeforeRule(List<FacesConfig> sortedList, FacesConfig resource, boolean referenced) throws FacesException
+    {
+        //Only before rules
+        boolean configOthers = false;
+        List<String> names = new ArrayList<String>();
+        
+        for (OrderSlot slot : resource.getOrdering().getBeforeList())
+        {
+            if (slot instanceof ConfigOthersSlot)
+            {
+                configOthers = true;
+                break;
+            }
+            else
+            {
+                FacesConfigNameSlot nameSlot = (FacesConfigNameSlot) slot;
+                names.add(nameSlot.getName());
+            }
+        }
+        
+        if (configOthers)
+        {
+            //<before>....<others/></before> case
+            //other reference where already considered when
+            //pre ordered list was calculated, so just add to the end.
+            
+            //There is one very special case, and it is when there
+            //is another resource with a reference on it. In this case,
+            //it is better do not apply this rule and add it to the end
+            //to give the chance to the other one to be applied.
+            if (resource.getOrdering().getBeforeList().size() > 1)
+            {
+                //If there is a reference apply it
+                sortedList.add(0,resource);
+            }
+            else if (!referenced)
+            {
+                //If it is not referenced apply it
+                sortedList.add(0,resource);
+            }
+            else
+            {
+                //if it is referenced bypass the rule and add it to the end
+                sortedList.add(resource);
+            }
+        }
+        else
+        {
+            //Scan the nearest reference and add it after
+            boolean founded = false;
+            for (int i = 0; i < sortedList.size() ; i++)
+            {
+                if (names.contains(sortedList.get(i).getName()))
+                {
+                    sortedList.add(i,resource);
+                    founded = true;
+                    break;
+                }
+            }
+            if (!founded)
+            {
+                //just add it to the end
+                sortedList.add(resource);
+            }
+        }        
+    }
+    
+    private void applyAfterRule(List<FacesConfig> sortedList, FacesConfig resource) throws FacesException
+    {
+        boolean configOthers = false;
+        List<String> names = new ArrayList<String>();
+        
+        for (OrderSlot slot : resource.getOrdering().getAfterList())
+        {
+            if (slot instanceof ConfigOthersSlot)
+            {
+                configOthers = true;
+                break;
+            }
+            else
+            {
+                FacesConfigNameSlot nameSlot = (FacesConfigNameSlot) slot;
+                names.add(nameSlot.getName());
+            }
+        }
+        
+        if (configOthers)
+        {
+            //<after>....<others/></after> case
+            //other reference where already considered when
+            //pre ordered list was calculated, so just add to the end.
+            sortedList.add(resource);
+        }
+        else
+        {
+            //Scan the nearest reference and add it after
+            boolean founded = false;
+            for (int i = sortedList.size()-1 ; i >=0 ; i--)
+            {
+                if (names.contains(sortedList.get(i).getName()))
+                {
+                    if (i+1 < sortedList.size())
+                    {
+                        sortedList.add(i+1,resource);
+                    }
+                    else
+                    {
+                        sortedList.add(resource);
+                    }
+                    founded = true;
+                    break;
+                }
+            }
+            if (!founded)
+            {
+                //just add it to the end
+                sortedList.add(resource);
+            }
+        }        
+    }
+    
+    
+    /**
+     * Pre Sort the appConfigResources, detecting cyclic references, so when sort process
+     * start, it is just necessary to traverse the preOrderedList once. To do that, we just
+     * scan "before" and "after" lists for references, and then those references are traversed
+     * again, so the first elements of the pre ordered list does not have references and
+     * the next elements has references to the already added ones.
+     * 
+     * The elements on the preOrderedList looks like this:
+     * 
+     * [ no ordering elements , referenced elements ... more referenced elements, 
+     *  before others / after others non referenced elements]
+     * 
+     * @param appConfigResources
+     * @return
+     */
+    protected List<FacesConfig> getPostOrderedList(final List<FacesConfig> appConfigResources) throws FacesException
+    {
+        
+        //0. Clean up: remove all not found resource references from the ordering 
+        //descriptions.
+        List<String> availableReferences = new ArrayList<String>();
+        for (FacesConfig resource : appConfigResources)
+        {
+            String name = resource.getName();
+            if (name != null && !"".equals(name))
+            {
+                availableReferences.add(name);
+            }
+        }
+        
+        for (FacesConfig resource : appConfigResources)
+        {
+            Ordering ordering = resource.getOrdering();
+            if (ordering != null)
+            {
+                for (Iterator<OrderSlot> it =  resource.getOrdering().getBeforeList().iterator();it.hasNext();)
+                {
+                    OrderSlot slot = it.next();
+                    if (slot instanceof FacesConfigNameSlot)
+                    {
+                        String name = ((FacesConfigNameSlot) slot).getName();
+                        if (!availableReferences.contains(name))
+                        {
+                            it.remove();
+                        }
+                    }
+                }
+                for (Iterator<OrderSlot> it =  resource.getOrdering().getAfterList().iterator();it.hasNext();)
+                {
+                    OrderSlot slot = it.next();
+                    if (slot instanceof FacesConfigNameSlot)
+                    {
+                        String name = ((FacesConfigNameSlot) slot).getName();
+                        if (!availableReferences.contains(name))
+                        {
+                            it.remove();
+                        }
+                    }
+                }
+            }
+        }
+
+        List<FacesConfig> appFilteredConfigResources = null; 
+
+        //1. Pre filtering: Sort nodes according to its weight. The weight is the number of named
+        //nodes containing in both before and after lists. The sort is done from the more complex
+        //to the most simple
+        if (appConfigResources instanceof ArrayList)
+        {
+            appFilteredConfigResources = (List<FacesConfig>)
+                ((ArrayList<FacesConfig>)appConfigResources).clone();
+        }
+        else
+        {
+            appFilteredConfigResources = new ArrayList<FacesConfig>();
+            appFilteredConfigResources.addAll(appConfigResources);
+        }
+        Collections.sort(appFilteredConfigResources,
+                new Comparator<FacesConfig>()
+                {
+                    public int compare(FacesConfig o1, FacesConfig o2)
+                    {
+                        int o1Weight = 0;
+                        int o2Weight = 0;
+                        if (o1.getOrdering() != null)
+                        {
+                            for (OrderSlot slot : o1.getOrdering()
+                                    .getBeforeList())
+                            {
+                                if (slot instanceof FacesConfigNameSlot)
+                                {
+                                    o1Weight++;
+                                }
+                            }
+                            for (OrderSlot slot : o1.getOrdering()
+                                    .getAfterList())
+                            {
+                                if (slot instanceof FacesConfigNameSlot)
+                                {
+                                    o1Weight++;
+                                }
+                            }
+                        }
+                        if (o2.getOrdering() != null)
+                        {
+                            for (OrderSlot slot : o2.getOrdering()
+                                    .getBeforeList())
+                            {
+                                if (slot instanceof FacesConfigNameSlot)
+                                {
+                                    o2Weight++;
+                                }
+                            }
+                            for (OrderSlot slot : o2.getOrdering()
+                                    .getAfterList())
+                            {
+                                if (slot instanceof FacesConfigNameSlot)
+                                {
+                                    o2Weight++;
+                                }
+                            }
+                        }
+                        return o2Weight - o1Weight;
+                    }
+                });
+        
+        List<FacesConfig> postOrderedList = new LinkedList<FacesConfig>();
+        List<FacesConfig> othersList = new ArrayList<FacesConfig>();
+        
+        List<String> nameBeforeStack = new ArrayList<String>();
+        List<String> nameAfterStack = new ArrayList<String>();
+        
+        boolean[] visitedSlots = new boolean[appFilteredConfigResources.size()];
+        
+        //2. Scan and resolve conflicts
+        for (int i = 0; i < appFilteredConfigResources.size(); i++)
+        {
+            if (!visitedSlots[i])
+            {
+                resolveConflicts(appFilteredConfigResources, i, visitedSlots, 
+                        nameBeforeStack, nameAfterStack, postOrderedList, othersList, false);
+            }
+        }
+        
+        //Add othersList to postOrderedList so <before><others/></before> and <after><others/></after>
+        //ordering conditions are handled at last if there are not referenced by anyone
+        postOrderedList.addAll(othersList);
+        
+        return postOrderedList;
+    }
+        
+    private void resolveConflicts(final List<FacesConfig> appConfigResources, int index, boolean[] visitedSlots,
+            List<String> nameBeforeStack, List<String> nameAfterStack, List<FacesConfig> postOrderedList,
+            List<FacesConfig> othersList, boolean indexReferenced) throws FacesException
+    {
+        FacesConfig facesConfig = appConfigResources.get(index);
+        
+        if (nameBeforeStack.contains(facesConfig.getName()))
+        {
+            //Already referenced, just return. Later if there exists a
+            //circular reference, it will be detected and solved.
+            return;
+        }
+        
+        if (nameAfterStack.contains(facesConfig.getName()))
+        {
+            //Already referenced, just return. Later if there exists a
+            //circular reference, it will be detected and solved.
+            return;
+        }
+        
+        if (facesConfig.getOrdering() != null)
+        {
+            boolean pointingResource = false;
+            
+            //Deal with before restrictions first
+            for (OrderSlot slot : facesConfig.getOrdering().getBeforeList())
+            {
+                if (slot instanceof FacesConfigNameSlot)
+                {
+                    FacesConfigNameSlot nameSlot = (FacesConfigNameSlot) slot;
+                    //The resource pointed is not added yet?
+                    boolean alreadyAdded = false;
+                    for (FacesConfig res : postOrderedList)
+                    {
+                        if (nameSlot.getName().equals(res.getName()))
+                        {
+                            alreadyAdded = true;
+                            break;
+                        }
+                    }
+                    if (!alreadyAdded)
+                    {
+                        int indexSlot = -1;
+                        //Find it
+                        for (int i = 0; i < appConfigResources.size(); i++)
+                        {
+                            FacesConfig resource = appConfigResources.get(i);
+                            if (resource.getName() != null && nameSlot.getName().equals(resource.getName()))
+                            {
+                                indexSlot = i;
+                                break;
+                            }
+                        }
+                        
+                        //Resource founded on appConfigResources
+                        if (indexSlot != -1)
+                        {
+                            pointingResource = true;
+                            //Add to nameStac
+                            nameBeforeStack.add(facesConfig.getName());
+                            
+                            resolveConflicts(appConfigResources, indexSlot, visitedSlots, 
+                                    nameBeforeStack, nameAfterStack, postOrderedList,
+                                    othersList,true);
+                            
+                            nameBeforeStack.remove(facesConfig.getName());
+                        }
+                    }
+                    else
+                    {
+                        pointingResource = true;
+                    }
+                }
+            }
+            
+            for (OrderSlot slot : facesConfig.getOrdering().getAfterList())
+            {
+                if (slot instanceof FacesConfigNameSlot)
+                {
+                    FacesConfigNameSlot nameSlot = (FacesConfigNameSlot) slot;
+                    //The resource pointed is not added yet?
+                    boolean alreadyAdded = false;
+                    for (FacesConfig res : postOrderedList)
+                    {
+                        if (nameSlot.getName().equals(res.getName()))
+                        {
+                            alreadyAdded = true;
+                            break;
+                        }
+                    }
+                    if (!alreadyAdded)
+                    {
+                        int indexSlot = -1;
+                        //Find it
+                        for (int i = 0; i < appConfigResources.size(); i++)
+                        {
+                            FacesConfig resource = appConfigResources.get(i);
+                            if (resource.getName() != null && nameSlot.getName().equals(resource.getName()))
+                            {
+                                indexSlot = i;
+                                break;
+                            }
+                        }
+                        
+                        //Resource founded on appConfigResources
+                        if (indexSlot != -1)
+                        {
+                            pointingResource = true;
+                            //Add to nameStac
+                            nameAfterStack.add(facesConfig.getName());
+                            
+                            resolveConflicts(appConfigResources, indexSlot, visitedSlots, 
+                                    nameBeforeStack, nameAfterStack, postOrderedList,
+                                    othersList,true);
+                            
+                            nameAfterStack.remove(facesConfig.getName());
+                        }
+                    }
+                    else
+                    {
+                        pointingResource = true;
+                    }
+                }
+            }
+            
+            if (facesConfig.getOrdering().getBeforeList().isEmpty() &&
+                facesConfig.getOrdering().getAfterList().isEmpty())
+            {
+                //Fits in the category "others", put at beginning
+                postOrderedList.add(0,appConfigResources.get(index));
+            }
+            else if (pointingResource || indexReferenced)
+            {
+                //If the node points to other or is referenced from other,
+                //add to the postOrderedList at the end
+                postOrderedList.add(appConfigResources.get(index));                    
+            }
+            else
+            {
+                //Add to othersList
+                othersList.add(appConfigResources.get(index));
+            }
+        }
+        else
+        {
+            //Add at start of the list, since does not have any ordering
+            //instructions and on the next step makes than "before others" and "after others"
+            //works correctly
+            postOrderedList.add(0,appConfigResources.get(index));
+        }
+        //Set the node as visited
+        visitedSlots[index] = true;
+    }    
+    
+    private FacesConfig getFacesConfig(List<FacesConfig> appConfigResources, String name)
+    {
+        for (FacesConfig cfg: appConfigResources)
+        {
+            if (cfg.getName() != null && name.equals(cfg.getName()))
+            {
+                return cfg;
+            }
+        }
+        return null;
+    }
+    
+    private boolean containsResourceInSlot(List<OrderSlot> slots, String name)
+    {
+        for (OrderSlot slot: slots)
+        {
+            if (slot instanceof FacesConfigNameSlot)
+            {
+                FacesConfigNameSlot nameSlot = (FacesConfigNameSlot) slot;
+                if (name.equals(nameSlot.getName()))
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+    
+    
+
+    @Override
+    public FacesConfigData getFacesConfigData(ExternalContext _externalContext)
+    {
+        boolean metadataComplete = false;
+
+        setDispenser(new DigesterFacesConfigDispenserImpl());
+        //1. Feed standard-faces-config.xml first.
+        getDispenser().feed(getStandardFacesConfig(_externalContext));
+        
+        getDispenser().feed(getMetaInfServicesFacesConfig(_externalContext));
+        
+        FacesConfig webAppFacesConfig = getWebAppFacesConfig(_externalContext);
+        
+        //read metadata-complete attribute on WEB-INF/faces-config.xml
+        if(webAppFacesConfig != null)
+        {
+            metadataComplete = Boolean.valueOf(webAppFacesConfig.getMetadataComplete());    
+        }
+        else
+        {
+            metadataComplete = false;   //assume false if no faces-config.xml was found
+                                        //metadata-complete can only be specified in faces-config.xml per the JSF 2.0 schema 
+        }
+        
+        FacesConfig annotationFacesConfig = getAnnotationsFacesConfig(_externalContext, metadataComplete);
+        
+        if (annotationFacesConfig != null)
+        {
+            getDispenser().feed(annotationFacesConfig);
+        }
+        
+        List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
+        
+        appConfigResources.addAll(getClassloaderFacesConfig(_externalContext));
+        appConfigResources.addAll(getContextSpecifiedFacesConfig(_externalContext));
+        
+        orderAndFeedArtifacts(appConfigResources,webAppFacesConfig);
+
+        return getDispenser();
+    }    
+    
+
+}

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigDispenser.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigDispenser.java?rev=1039554&r1=1039553&r2=1039554&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigDispenser.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigDispenser.java Fri Nov 26 20:32:39 2010
@@ -24,13 +24,14 @@ import javax.el.ELResolver;
 
 import org.apache.myfaces.config.element.Behavior;
 import org.apache.myfaces.config.element.ClientBehaviorRenderer;
+import org.apache.myfaces.config.element.FacesConfigData;
 import org.apache.myfaces.config.element.ManagedBean;
 import org.apache.myfaces.config.element.NavigationRule;
 import org.apache.myfaces.config.element.Renderer;
-import org.apache.myfaces.config.impl.digester.elements.Converter;
-import org.apache.myfaces.config.impl.digester.elements.NamedEvent;
-import org.apache.myfaces.config.impl.digester.elements.ResourceBundle;
-import org.apache.myfaces.config.impl.digester.elements.SystemEventListener;
+import org.apache.myfaces.config.element.Converter;
+import org.apache.myfaces.config.element.NamedEvent;
+import org.apache.myfaces.config.element.ResourceBundle;
+import org.apache.myfaces.config.element.SystemEventListener;
 
 /**
  * Subsumes several unmarshalled faces config objects and presents a simple interface
@@ -39,246 +40,77 @@ import org.apache.myfaces.config.impl.di
  * @author Manfred Geiler (latest modification by $Author$)
  * @version $Revision$ $Date$
  */
-public interface FacesConfigDispenser<C>
+public abstract class FacesConfigDispenser extends FacesConfigData
 {
     /**
+     * 
+     */
+    private static final long serialVersionUID = 9123062381457766144L;
+
+    /**
      * Add another unmarshalled faces config object.
      * @param facesConfig unmarshalled faces config object
      */
-    public void feed(C facesConfig);
+    public abstract void feed(org.apache.myfaces.config.element.FacesConfig facesConfig);
 
     /**
      * Add another ApplicationFactory class name
      * @param factoryClassName a class name
      */
-    public void feedApplicationFactory(String factoryClassName);
+    public abstract void feedApplicationFactory(String factoryClassName);
 
     /**
      * Add another ExceptionHandlerFactory class name
      * @param factoryClassName a class name
      */
-    public void feedExceptionHandlerFactory(String factoryClassName);
+    public abstract void feedExceptionHandlerFactory(String factoryClassName);
 
     /**
      * Add another ExternalContextFactory class name
      * @param factoryClassName a class name
      */
-    public void feedExternalContextFactory(String factoryClassName);
+    public abstract void feedExternalContextFactory(String factoryClassName);
 
     /**
      * Add another FacesContextFactory class name
      * @param factoryClassName a class name
      */
-    public void feedFacesContextFactory(String factoryClassName);
+    public abstract void feedFacesContextFactory(String factoryClassName);
 
     /**
      * Add another LifecycleFactory class name
      * @param factoryClassName a class name
      */
-    public void feedLifecycleFactory(String factoryClassName);
+    public abstract void feedLifecycleFactory(String factoryClassName);
     
     /**
      * Add another ViewDeclarationLanguageFactory class name
      * @param factoryClassName a class name
      */
-    public void feedViewDeclarationLanguageFactory(String factoryClassName);
+    public abstract void feedViewDeclarationLanguageFactory(String factoryClassName);
 
     /**
      * Add another PartialViewContextFactory class name
      * @param factoryClassName a class name
      */
-    public void feedPartialViewContextFactory(String factoryClassName);
+    public abstract void feedPartialViewContextFactory(String factoryClassName);
 
     /**
      * Add another RenderKitFactory class name
      * @param factoryClassName a class name
      */
-    public void feedRenderKitFactory(String factoryClassName);
+    public abstract void feedRenderKitFactory(String factoryClassName);
     
     /**
      * Add another TagHandlerDelegateFactory class name
      * @param factoryClassName a class name
      */
-    public void feedTagHandlerDelegateFactory(String factoryClassName);
+    public abstract void feedTagHandlerDelegateFactory(String factoryClassName);
 
     /**
      * Add another VisitContextFactory class name
      * @param factoryClassName a class name
      */
-    public void feedVisitContextFactory(String factoryClassName);
-
-
-
-    /** @return Iterator over ApplicationFactory class names */
-    public Collection<String> getApplicationFactoryIterator();
-    
-    /** @return Iterator over ExceptionHandlerFactory class names */
-    public Collection<String> getExceptionHandlerFactoryIterator();
-
-    /** @return Iterator over ExternalContextFactory class names */
-    public Collection<String> getExternalContextFactoryIterator();
-
-    /** @return Iterator over FacesContextFactory class names */
-    public Collection<String> getFacesContextFactoryIterator();
-
-    /** @return Iterator over LifecycleFactory class names */
-    public Collection<String> getLifecycleFactoryIterator();
-
-    /** @return Iterator over ViewDeclarationLanguageFactory class names */
-    public Collection<String> getViewDeclarationLanguageFactoryIterator();
-
-    /** @return Iterator over PartialViewContextFactory class names */
-    public Collection<String> getPartialViewContextFactoryIterator();
-
-    /** @return Iterator over RenderKit factory class names */
-    public Collection<String> getRenderKitFactoryIterator();
-    
-    /** @return Iterator over TagHandlerDelegateFactory factory class names */
-    public Collection<String> getTagHandlerDelegateFactoryIterator();
-
-    /** @return Iterator over VisitContextFactory factory class names */
-    public Collection<String> getVisitContextFactoryIterator();
-
-
-    /** @return Iterator over ActionListener class names (in reverse order!) */
-    public Collection<String> getActionListenerIterator();
-
-    /** @return the default render kit id */
-    public String getDefaultRenderKitId();
-
-    /** @return Iterator over message bundle names (in reverse order!) */
-    public String getMessageBundle();
-
-    /** @return Iterator over NavigationHandler class names */
-    public Collection<String> getNavigationHandlerIterator();
-
-    /** @return Iterator over ViewHandler class names */
-    public Collection<String> getViewHandlerIterator();
-
-    /** @return Iterator over StateManager class names*/
-    public Collection<String> getStateManagerIterator();
-    
-    /** @return Iterator over ResourceHandler class names*/
-    public Collection<String> getResourceHandlerIterator();
-
-    /** @return Iterator over PropertyResolver class names */
-    public Collection<String> getPropertyResolverIterator();
-
-    /** @return Iterator over VariableResolver class names  */
-    public Collection<String> getVariableResolverIterator();
-
-    /** @return the default locale name */
-    public String getDefaultLocale();
-
-    /** @return Iterator over supported locale names */
-    public Collection<String> getSupportedLocalesIterator();
-
-
-    /** @return Iterator over all defined component types */
-    public Collection<String> getComponentTypes();
-
-    /** @return component class that belongs to the given component type */
-    public String getComponentClass(String componentType);
-
-
-    /** @return Iterator over all defined converter ids */
-    public Collection<String> getConverterIds();
-
-    /** @return Iterator over all classes with an associated converter  */
-    public Collection<String> getConverterClasses();
-
-    /** @return Iterator over the config classes for the converters  */
-    Collection<String> getConverterConfigurationByClassName();
-
-    /** delivers a converter-configuration for one class-name */
-    Converter getConverterConfiguration(String converterClassName);
-
-    /** @return converter class that belongs to the given converter id */
-    public String getConverterClassById(String converterId);
-
-    /** @return converter class that is associated with the given class name  */
-    public String getConverterClassByClass(String className);
-
-
-    /** @return Iterator over all defined validator ids */
-    public Collection<String> getValidatorIds();
-
-    /** @return validator class name that belongs to the given validator id */
-    public String getValidatorClass(String validatorId);
-
-
-    /**
-     * @return Iterator over {@link org.apache.myfaces.config.element.ManagedBean ManagedBean}s
-     */
-    public Collection<ManagedBean> getManagedBeans();
-
-    /**
-     * @return Iterator over {@link org.apache.myfaces.config.element.NavigationRule NavigationRule}s
-     */
-    public Collection<NavigationRule> getNavigationRules();
-
-
-
-    /** @return Iterator over all defined renderkit ids */
-    public Collection<String> getRenderKitIds();
-
-    /** @return renderkit class name for given renderkit id */
-    public Collection<String> getRenderKitClasses(String renderKitId);
-
-    /**
-     * @return Iterator over {@link org.apache.myfaces.config.element.ClientBehaviorRenderer ClientBehaviorRenderer}s for the given renderKitId
-     */
-    public Collection<ClientBehaviorRenderer> getClientBehaviorRenderers (String renderKitId);
-    
-    /**
-     * @return Iterator over {@link org.apache.myfaces.config.element.Renderer Renderer}s for the given renderKitId
-     */
-    public Collection<Renderer> getRenderers(String renderKitId);
-
-
-    /**
-     * @return Iterator over {@link javax.faces.event.PhaseListener} implementation class names
-     */
-    public Collection<String> getLifecyclePhaseListeners();
-
-    /**
-     * @return Iterator over {@link ResourceBundle}
-     */
-    public Collection<ResourceBundle> getResourceBundles();
+    public abstract void feedVisitContextFactory(String factoryClassName);
 
-    /**
-     * @return Iterator over {@link ELResolver} implementation class names
-     */
-    public Collection<String> getElResolvers();
-    
-    /**
-     * @return Iterator over (@link SystemEventListener) implementation class names 
-     */
-    public Collection<SystemEventListener> getSystemEventListeners();
-    
-    /**
-     * @return Collection over behaviors
-     */
-    public Collection<Behavior> getBehaviors ();
-    
-    /**
-     * @return Collection over all defined default validator ids
-     */
-    public Collection<String> getDefaultValidatorIds ();
-    
-    /**
-     * @return the partial traversal class name
-     */
-    public String getPartialTraversal ();
-    
-    /**
-     * @return Faces application version.
-     */
-    public String getFacesVersion ();
-    
-    /**
-     * 
-     * @return
-     */
-    public Collection<NamedEvent> getNamedEvents();
 }