You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ja...@apache.org on 2010/12/10 19:40:17 UTC

svn commit: r1044474 [2/2] - in /myfaces/core/trunk/impl/src: main/java/org/apache/myfaces/config/ main/java/org/apache/myfaces/spi/ main/java/org/apache/myfaces/spi/impl/ test/java/org/apache/myfaces/config/

Modified: 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=1044474&r1=1044473&r2=1044474&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/DefaultFacesConfigurationProvider.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/DefaultFacesConfigurationProvider.java Fri Dec 10 18:40:16 2010
@@ -18,49 +18,34 @@
  */
 package org.apache.myfaces.config;
 
+import org.apache.myfaces.config.annotation.AnnotationConfigurator;
+import org.apache.myfaces.config.element.FacesConfig;
+import org.apache.myfaces.config.impl.digester.DigesterFacesConfigUnmarshallerImpl;
+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.apache.myfaces.spi.ServiceProviderFinderFactory;
+import org.xml.sax.SAXException;
+
+import javax.faces.FacesException;
+import javax.faces.FactoryFinder;
+import javax.faces.context.ExternalContext;
+import javax.faces.webapp.FacesServlet;
 import java.io.IOException;
 import java.io.InputStream;
 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.apache.myfaces.spi.FacesConfigurationProviderFactory;
-import org.apache.myfaces.spi.ServiceProviderFinderFactory;
-import org.xml.sax.SAXException;
-
 /**
  * 
  * @author Leonardo Uribe
@@ -171,13 +156,17 @@ public class DefaultFacesConfigurationPr
     {
         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();
+            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)
             {
-                List<String> classList = ServiceProviderFinderFactory.getServiceProviderFinder(ectx).getServiceProviderList(factoryName);
+                List<String> classList = ServiceProviderFinderFactory.getServiceProviderFinder(ectx)
+                        .getServiceProviderList(factoryName);
                 
                 for (String className : classList)
                 {
@@ -221,13 +210,6 @@ public class DefaultFacesConfigurationPr
         }
     }
 
-    private InputStream openStreamWithoutCache(URL url) throws IOException
-    {
-        URLConnection connection = url.openConnection();
-        connection.setUseCaches(false);
-        return connection.getInputStream();
-    }
-
     /**
      * This method fixes MYFACES-208
      */
@@ -314,35 +296,7 @@ public class DefaultFacesConfigurationPr
         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;
-    }
-
+    @Override
     public FacesConfig getWebAppFacesConfig(ExternalContext ectx)
     {
         try
@@ -378,1008 +332,50 @@ public class DefaultFacesConfigurationPr
         }
 
     }
-    
-    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(FacesConfigDispenser dispenser, 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)
-                    {
-                        dispenser.feed(resource);
-                    }
-                }
-                else
-                {
-                    //Add it to the sorted list
-                    FacesConfigNameSlot nameSlot = (FacesConfigNameSlot) slot;
-                    // We need to check if the resource is on appConfigResources, otherwise we can
-                    // ignore it safely.
-                    FacesConfig targetFacesConfig = getFacesConfig(appConfigResources, nameSlot.getName());
-                    if (targetFacesConfig != null)
-                    {
-                        dispenser.feed(targetFacesConfig);
-                    }
-                }
-            }
-        }
-        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
-                dispenser.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)
-        {
-            dispenser.feed(webAppConfig);
-        }
-    }
 
-    /**
-     * Sort using topological ordering algorithm.
-     * 
-     * @param appConfigResources
-     * @return
-     * @throws FacesException
-     */
-    protected List<FacesConfig> applySortingAlgorithm(List<FacesConfig> appConfigResources) throws FacesException
+    private InputStream openStreamWithoutCache(URL url) throws IOException
     {
-        
-        //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;
+        URLConnection connection = url.openConnection();
+        connection.setUseCaches(false);
+        return connection.getInputStream();
     }
-    
-    /**
-     * 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)
+    private List<String> getConfigFilesList(ExternalContext ectx) {
+        String configFiles = ectx.getInitParameter(FacesServlet.CONFIG_FILES_ATTR);
+        List<String> configFilesList = new ArrayList<String>();
+        if (configFiles != null)
         {
-            Ordering ordering = resource.getOrdering();
-            if (ordering != null)
+            StringTokenizer st = new StringTokenizer(configFiles, ",", false);
+            while (st.hasMoreTokens())
             {
-                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; 
+                String systemId = st.nextToken().trim();
 
-        //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)
+                if (DEFAULT_FACES_CONFIG.equals(systemId))
                 {
-                    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
+                    if (log.isLoggable(Level.WARNING))
                     {
-                        pointingResource = true;
+                        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");
                     }
                 }
-            }
-            
-            for (OrderSlot slot : facesConfig.getOrdering().getAfterList())
-            {
-                if (slot instanceof FacesConfigNameSlot)
+                else
                 {
-                    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;
-                    }
+                    configFilesList.add(systemId);
                 }
             }
-            
-            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;
+        return configFilesList;
     }
     
-    private boolean containsResourceInSlot(List<OrderSlot> slots, String name)
+    private void validateFacesConfig(ExternalContext ectx, URL url) throws IOException, SAXException
     {
-        for (OrderSlot slot: slots)
+        String version = ConfigFilesXmlValidationUtils.getFacesConfigVersion(url);
+        if ("1.2".equals(version) || "2.0".equals(version))
         {
-            if (slot instanceof FacesConfigNameSlot)
-            {
-                FacesConfigNameSlot nameSlot = (FacesConfigNameSlot) slot;
-                if (name.equals(nameSlot.getName()))
-                {
-                    return true;
-                }
-            }
+            ConfigFilesXmlValidationUtils.validateFacesConfigFile(url, ectx, version);
         }
-        return false;
     }
-    
-    
-
-    @Override
-    public FacesConfigData getFacesConfigData(ExternalContext _externalContext)
-    {
-        boolean metadataComplete = false;
-
-        FacesConfigurationProvider provider = FacesConfigurationProviderFactory.
-            getFacesConfigurationProviderFactory(_externalContext).
-                getFacesConfigurationProvider(_externalContext);
-        
-        FacesConfigDispenser dispenser = new DigesterFacesConfigDispenserImpl(); 
-        //1. Feed standard-faces-config.xml first.
-        dispenser.feed(provider.getStandardFacesConfig(_externalContext));
-        
-        dispenser.feed(provider.getMetaInfServicesFacesConfig(_externalContext));
-        
-        FacesConfig webAppFacesConfig = provider.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 = provider.getAnnotationsFacesConfig(_externalContext, metadataComplete);
-        
-        if (annotationFacesConfig != null)
-        {
-            dispenser.feed(annotationFacesConfig);
-        }
-        
-        List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
-        
-        appConfigResources.addAll(provider.getClassloaderFacesConfig(_externalContext));
-        appConfigResources.addAll(provider.getContextSpecifiedFacesConfig(_externalContext));
-        
-        orderAndFeedArtifacts(dispenser, appConfigResources,webAppFacesConfig);
-
-        return dispenser;
-    }    
-    
 
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java?rev=1044474&r1=1044473&r2=1044474&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java Fri Dec 10 18:40:16 2010
@@ -18,56 +18,6 @@
  */
 package org.apache.myfaces.config;
 
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.JarURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.el.ELResolver;
-import javax.faces.FacesException;
-import javax.faces.FactoryFinder;
-import javax.faces.application.Application;
-import javax.faces.application.ApplicationFactory;
-import javax.faces.application.ConfigurableNavigationHandler;
-import javax.faces.application.NavigationHandler;
-import javax.faces.application.ProjectStage;
-import javax.faces.application.ResourceHandler;
-import javax.faces.application.StateManager;
-import javax.faces.application.ViewHandler;
-import javax.faces.context.ExternalContext;
-import javax.faces.context.FacesContext;
-import javax.faces.el.PropertyResolver;
-import javax.faces.el.VariableResolver;
-import javax.faces.event.ActionListener;
-import javax.faces.event.ComponentSystemEvent;
-import javax.faces.event.PhaseListener;
-import javax.faces.event.PostConstructApplicationEvent;
-import javax.faces.event.PreDestroyCustomScopeEvent;
-import javax.faces.event.PreDestroyViewMapEvent;
-import javax.faces.event.SystemEvent;
-import javax.faces.lifecycle.Lifecycle;
-import javax.faces.lifecycle.LifecycleFactory;
-import javax.faces.render.RenderKit;
-import javax.faces.render.RenderKitFactory;
-import javax.faces.validator.BeanValidator;
-import javax.faces.webapp.FacesServlet;
-
 import org.apache.myfaces.application.ApplicationFactoryImpl;
 import org.apache.myfaces.application.BackwardsCompatibleNavigationHandlerWrapper;
 import org.apache.myfaces.component.visit.VisitContextFactoryImpl;
@@ -101,8 +51,8 @@ import org.apache.myfaces.shared_impl.ut
 import org.apache.myfaces.shared_impl.util.StateUtils;
 import org.apache.myfaces.shared_impl.util.serial.DefaultSerialFactory;
 import org.apache.myfaces.shared_impl.util.serial.SerialFactory;
-import org.apache.myfaces.spi.FacesConfigurationProvider;
-import org.apache.myfaces.spi.FacesConfigurationProviderFactory;
+import org.apache.myfaces.spi.FacesConfigurationMerger;
+import org.apache.myfaces.spi.FacesConfigurationMergerFactory;
 import org.apache.myfaces.util.ContainerUtils;
 import org.apache.myfaces.util.ExternalSpecifications;
 import org.apache.myfaces.view.ViewDeclarationLanguageFactoryImpl;
@@ -110,6 +60,55 @@ import org.apache.myfaces.view.facelets.
 import org.apache.myfaces.view.facelets.tag.ui.DebugPhaseListener;
 import org.apache.myfaces.webapp.ManagedBeanDestroyerListener;
 
+import javax.el.ELResolver;
+import javax.faces.FacesException;
+import javax.faces.FactoryFinder;
+import javax.faces.application.Application;
+import javax.faces.application.ApplicationFactory;
+import javax.faces.application.ConfigurableNavigationHandler;
+import javax.faces.application.NavigationHandler;
+import javax.faces.application.ProjectStage;
+import javax.faces.application.ResourceHandler;
+import javax.faces.application.StateManager;
+import javax.faces.application.ViewHandler;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.el.PropertyResolver;
+import javax.faces.el.VariableResolver;
+import javax.faces.event.ActionListener;
+import javax.faces.event.ComponentSystemEvent;
+import javax.faces.event.PhaseListener;
+import javax.faces.event.PostConstructApplicationEvent;
+import javax.faces.event.PreDestroyCustomScopeEvent;
+import javax.faces.event.PreDestroyViewMapEvent;
+import javax.faces.event.SystemEvent;
+import javax.faces.lifecycle.Lifecycle;
+import javax.faces.lifecycle.LifecycleFactory;
+import javax.faces.render.RenderKit;
+import javax.faces.render.RenderKitFactory;
+import javax.faces.validator.BeanValidator;
+import javax.faces.webapp.FacesServlet;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 /**
  * Configures everything for a given context. The FacesConfigurator is independent of the concrete implementations that
  * lie behind FacesConfigUnmarshaller and FacesConfigDispenser.
@@ -445,10 +444,12 @@ public class FacesConfigurator
 
     public void configure() throws FacesException
     {
-        FacesConfigurationProvider provider = FacesConfigurationProviderFactory.getFacesConfigurationProviderFactory(_externalContext).
-                            getFacesConfigurationProvider(_externalContext);
-        
-        setDispenser(provider.getFacesConfigData(_externalContext)); 
+        // get FacesConfigurationMerger SPI implementation
+        FacesConfigurationMerger facesConfigurationMerger = FacesConfigurationMergerFactory
+                .getFacesConfigurationMergerFactory(_externalContext).getFacesConfigurationMerger(_externalContext);
+
+        // get all faces-config data, merge it and set it as Dispenser
+        setDispenser(facesConfigurationMerger.getFacesConfigData(_externalContext));
 
         configureFactories();
         configureApplication();

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationMerger.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationMerger.java?rev=1044474&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationMerger.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationMerger.java Fri Dec 10 18:40:16 2010
@@ -0,0 +1,52 @@
+/*
+ * 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.spi;
+
+import org.apache.myfaces.config.element.FacesConfigData;
+
+import javax.faces.context.ExternalContext;
+
+/**
+ * SPI that uses the FacesConfigurationProvider-SPI to get all FacesConfig data
+ * and then it combines it into one FacesConfigData instance. For this merging
+ * process the ordering and sorting rules of the JSF spec must be applied.
+ *
+ * With this SPI it is possible to store the result of the complex ordering and
+ * sorting algorithm in order to skip it if no configuration changes are applied
+ * upon redeploy.
+ *
+ * Implementations of this SPI can take advantage of the decorator pattern in
+ * order to use the default SPI-impl.
+ *
+ * @author Jakob Korherr
+ * @since 2.0.3
+ */
+public abstract class FacesConfigurationMerger
+{
+
+    /**
+     * Returns an object that collect all config information used by MyFaces
+     * to initialize the web application.
+     *
+     * @param ectx
+     * @return
+     */
+    public abstract FacesConfigData getFacesConfigData(ExternalContext ectx);
+
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationMergerFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationMergerFactory.java?rev=1044474&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationMergerFactory.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationMergerFactory.java Fri Dec 10 18:40:16 2010
@@ -0,0 +1,100 @@
+/*
+ * 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.spi;
+
+import org.apache.myfaces.spi.impl.DefaultFacesConfigurationMergerFactory;
+import org.apache.myfaces.spi.impl.SpiUtils;
+
+import javax.faces.FacesException;
+import javax.faces.context.ExternalContext;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+
+/**
+ * SPI to provide a FacesConfigurationMergerFactory implementation and thus
+ * a custom FacesConfigurationMerger instance.
+ *
+ * @author Jakob Korherr
+ * @since 2.0.3
+ */
+public abstract class FacesConfigurationMergerFactory
+{
+
+    protected static final String FACTORY_DEFAULT = DefaultFacesConfigurationMergerFactory.class.getName();
+
+    private static final String FACTORY_KEY = FacesConfigurationMergerFactory.class.getName();
+
+    public static FacesConfigurationMergerFactory getFacesConfigurationMergerFactory(ExternalContext ctx)
+    {
+        FacesConfigurationMergerFactory factory
+                = (FacesConfigurationMergerFactory) ctx.getApplicationMap().get(FACTORY_KEY);
+        
+        if (factory != null)
+        {
+            // use cached instance
+            return factory;
+        }
+
+        // create new instance from service entry
+        try
+        {
+
+            if (System.getSecurityManager() != null)
+            {
+                final ExternalContext ectx = ctx;
+                factory = (FacesConfigurationMergerFactory) AccessController.doPrivileged(
+                        new java.security.PrivilegedExceptionAction<Object>()
+                        {
+                            public Object run() throws PrivilegedActionException
+                            {
+                                return SpiUtils.build(ectx,
+                                        FacesConfigurationMergerFactory.class,
+                                        FACTORY_DEFAULT);
+                            }
+                        });
+            }
+            else
+            {
+                factory = (FacesConfigurationMergerFactory) SpiUtils
+                        .build(ctx, FacesConfigurationMergerFactory.class, FACTORY_DEFAULT);
+            }
+        }
+        catch (PrivilegedActionException pae)
+        {
+            throw new FacesException(pae);
+        }
+
+        if (factory != null)
+        {
+            // cache instance on ApplicationMap
+            setFacesConfigurationMergerFactory(ctx, factory);
+        }
+
+        return factory;
+    }
+
+    public static void setFacesConfigurationMergerFactory(ExternalContext ctx,
+                                                          FacesConfigurationMergerFactory factory)
+    {
+        ctx.getApplicationMap().put(FACTORY_KEY, factory);
+    }
+
+    public abstract FacesConfigurationMerger getFacesConfigurationMerger(ExternalContext externalContext);
+
+}

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationProvider.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationProvider.java?rev=1044474&r1=1044473&r2=1044474&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationProvider.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationProvider.java Fri Dec 10 18:40:16 2010
@@ -92,13 +92,4 @@ public abstract class FacesConfiguration
      */
     public abstract FacesConfig getWebAppFacesConfig(ExternalContext ectx); 
     
-    /**
-     * Returns an object that collect all config information used by MyFaces
-     * to initialize the web application.
-     * 
-     * @param ectx
-     * @return
-     */
-    public abstract FacesConfigData getFacesConfigData(ExternalContext ectx);
-    
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationProviderWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationProviderWrapper.java?rev=1044474&r1=1044473&r2=1044474&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationProviderWrapper.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationProviderWrapper.java Fri Dec 10 18:40:16 2010
@@ -72,8 +72,4 @@ public abstract class FacesConfiguration
         return getWrapped().getWebAppFacesConfig(ectx);
     }
 
-    public FacesConfigData getFacesConfigData(ExternalContext ectx)
-    {
-        return getWrapped().getFacesConfigData(ectx);
-    }
 }

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultFacesConfigurationMergerFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultFacesConfigurationMergerFactory.java?rev=1044474&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultFacesConfigurationMergerFactory.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultFacesConfigurationMergerFactory.java Fri Dec 10 18:40:16 2010
@@ -0,0 +1,133 @@
+/*
+ * 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.spi.impl;
+
+import org.apache.myfaces.config.DefaultFacesConfigurationMerger;
+import org.apache.myfaces.shared_impl.util.ClassUtils;
+import org.apache.myfaces.spi.FacesConfigurationMerger;
+import org.apache.myfaces.spi.FacesConfigurationMergerFactory;
+import org.apache.myfaces.spi.ServiceProviderFinderFactory;
+
+import javax.faces.FacesException;
+import javax.faces.context.ExternalContext;
+import java.lang.reflect.InvocationTargetException;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * @author Jakob Korherr
+ */
+public class DefaultFacesConfigurationMergerFactory extends FacesConfigurationMergerFactory
+{
+
+    public static final String FACES_CONFIGURATION_MERGER = FacesConfigurationMerger.class.getName();
+    public static final String FACES_CONFIGURATION_MERGER_INSTANCE_KEY = FACES_CONFIGURATION_MERGER + ".INSTANCE";
+
+    @Override
+    public FacesConfigurationMerger getFacesConfigurationMerger(ExternalContext externalContext)
+    {
+        // check for cached instance
+        FacesConfigurationMerger returnValue = (FacesConfigurationMerger)
+                externalContext.getApplicationMap().get(FACES_CONFIGURATION_MERGER_INSTANCE_KEY);
+
+        if (returnValue == null)
+        {
+            final ExternalContext extContext = externalContext;
+            try
+            {
+                if (System.getSecurityManager() != null)
+                {
+                    returnValue = AccessController.doPrivileged(
+                            new java.security.PrivilegedExceptionAction<FacesConfigurationMerger>()
+                            {
+                                public FacesConfigurationMerger run() throws ClassNotFoundException,
+                                        NoClassDefFoundError,
+                                        InstantiationException,
+                                        IllegalAccessException,
+                                        InvocationTargetException,
+                                        PrivilegedActionException
+                                {
+                                    return resolveFacesConfigurationMergerFromService(extContext);
+                                }
+                            });
+                }
+                else
+                {
+                    returnValue = resolveFacesConfigurationMergerFromService(extContext);
+                }
+
+                // cache the result on the ApplicationMap
+                externalContext.getApplicationMap().put(FACES_CONFIGURATION_MERGER_INSTANCE_KEY, returnValue);
+            }
+            catch (ClassNotFoundException e)
+            {
+                // ignore
+            }
+            catch (NoClassDefFoundError e)
+            {
+                // ignore
+            }
+            catch (InstantiationException e)
+            {
+                getLogger().log(Level.SEVERE, "", e);
+            }
+            catch (IllegalAccessException e)
+            {
+                getLogger().log(Level.SEVERE, "", e);
+            }
+            catch (InvocationTargetException e)
+            {
+                getLogger().log(Level.SEVERE, "", e);
+            }
+            catch (PrivilegedActionException e)
+            {
+                throw new FacesException(e);
+            }
+        }
+
+
+        return returnValue;
+    }
+
+    private FacesConfigurationMerger resolveFacesConfigurationMergerFromService(ExternalContext externalContext)
+            throws ClassNotFoundException,
+                   NoClassDefFoundError,
+                   InstantiationException,
+                   IllegalAccessException,
+                   InvocationTargetException,
+                   PrivilegedActionException
+    {
+        // get all fitting SPI implementations (no need to cache this since it's only called once per JSF-app)
+        List<String> classList = ServiceProviderFinderFactory.getServiceProviderFinder(externalContext)
+                .getServiceProviderList(FACES_CONFIGURATION_MERGER);
+
+        // create the instance using decorator pattern
+        return ClassUtils.buildApplicationObject(FacesConfigurationMerger.class,
+                classList, new DefaultFacesConfigurationMerger());
+    }
+
+    private Logger getLogger()
+    {
+        return Logger.getLogger(DefaultFacesConfigurationMergerFactory.class.getName());
+    }
+
+}

Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/config/OrderingFacesConfigTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/config/OrderingFacesConfigTest.java?rev=1044474&r1=1044473&r2=1044474&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/config/OrderingFacesConfigTest.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/config/OrderingFacesConfigTest.java Fri Dec 10 18:40:16 2010
@@ -15,14 +15,6 @@
  */
 package org.apache.myfaces.config;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.faces.FacesException;
-
 import org.apache.myfaces.config.element.FacesConfig;
 import org.apache.myfaces.config.element.OrderSlot;
 import org.apache.myfaces.config.impl.digester.DigesterFacesConfigUnmarshallerImpl;
@@ -30,9 +22,15 @@ import org.apache.myfaces.config.impl.di
 import org.apache.myfaces.config.impl.digester.elements.ConfigOthersSlot;
 import org.apache.myfaces.config.impl.digester.elements.FacesConfigNameSlot;
 import org.apache.myfaces.config.impl.digester.elements.Ordering;
-import org.apache.myfaces.spi.FacesConfigurationProvider;
 import org.apache.myfaces.test.base.AbstractJsfTestCase;
 
+import javax.faces.FacesException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
 public class OrderingFacesConfigTest extends AbstractJsfTestCase
 {
     private static final Logger log = Logger.getLogger(OrderingFacesConfigTest.class.getName());
@@ -404,19 +402,16 @@ public class OrderingFacesConfigTest ext
 
     public void applyAlgorithm(List<FacesConfig> appConfigResources) throws FacesException
     {
-        //FacesConfigurator configurator = new FacesConfigurator(externalContext);
-        DefaultFacesConfigurationProvider configurator = new DefaultFacesConfigurationProvider();
-        
-        //printFacesConfigList("Start List", appConfigResources);
-        
-        List<FacesConfig> postOrderedList = configurator.getPostOrderedList(appConfigResources);
+        DefaultFacesConfigurationMerger merger = new DefaultFacesConfigurationMerger();
+
+        List<FacesConfig> postOrderedList = merger.getPostOrderedList(appConfigResources);
         
-        List<FacesConfig> sortedList = configurator.sortRelativeOrderingList(postOrderedList);
+        List<FacesConfig> sortedList = merger.sortRelativeOrderingList(postOrderedList);
         
         if (sortedList == null)
         {
             //The previous algorithm can't sort correctly, try this one
-            sortedList = configurator.applySortingAlgorithm(appConfigResources);
+            sortedList = merger.applySortingAlgorithm(appConfigResources);
         }
         
         //printFacesConfigList("Sorted List", sortedList);
@@ -644,8 +639,7 @@ public class OrderingFacesConfigTest ext
 
     public void applyAlgorithm2(List<FacesConfig> appConfigResources) throws FacesException
     {
-        //FacesConfigurator configurator = new FacesConfigurator(externalContext);
-        DefaultFacesConfigurationProvider configurator = new DefaultFacesConfigurationProvider();
+        DefaultFacesConfigurationMerger merger = new DefaultFacesConfigurationMerger();
         
         System.out.println("");
         System.out.print("Start List: [");
@@ -662,7 +656,7 @@ public class OrderingFacesConfigTest ext
         }
         System.out.println("]");
         
-        List<FacesConfig> postOrderedList = configurator.getPostOrderedList(appConfigResources);
+        List<FacesConfig> postOrderedList = merger.getPostOrderedList(appConfigResources);
         
         System.out.print("Pre-Ordered-List: [");
         for (int i = 0; i < postOrderedList.size();i++)
@@ -678,7 +672,7 @@ public class OrderingFacesConfigTest ext
         }
         System.out.println("]");
         
-        List<FacesConfig> sortedList = configurator.sortRelativeOrderingList(postOrderedList);
+        List<FacesConfig> sortedList = merger.sortRelativeOrderingList(postOrderedList);
         
         System.out.print("Sorted-List: [");
         for (int i = 0; i < sortedList.size();i++)