View Javadoc

1   /*
2    * Copyright 2007 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.myfaces.config;
17  
18  import org.apache.myfaces.config.element.FacesConfig;
19  import org.apache.myfaces.config.element.OrderSlot;
20  import org.apache.myfaces.config.impl.digester.DigesterFacesConfigUnmarshallerImpl;
21  import org.apache.myfaces.config.impl.digester.elements.AbsoluteOrderingImpl;
22  import org.apache.myfaces.config.impl.digester.elements.ConfigOthersSlotImpl;
23  import org.apache.myfaces.config.impl.digester.elements.FacesConfigNameSlotImpl;
24  import org.apache.myfaces.config.impl.digester.elements.OrderingImpl;
25  import org.apache.myfaces.test.base.AbstractJsfTestCase;
26  
27  import javax.faces.FacesException;
28  import java.util.ArrayList;
29  import java.util.Collections;
30  import java.util.List;
31  import java.util.logging.Level;
32  import java.util.logging.Logger;
33  
34  public class OrderingFacesConfigTest extends AbstractJsfTestCase
35  {
36      private static final Logger log = Logger.getLogger(OrderingFacesConfigTest.class.getName());
37      
38      private DigesterFacesConfigUnmarshallerImpl _impl;
39      
40      public OrderingFacesConfigTest(String name)
41      {
42          super(name);
43      }
44      
45      protected void setUp() throws Exception
46      {
47          super.setUp();
48          _impl = new DigesterFacesConfigUnmarshallerImpl(null);
49      }
50      
51      public void printFacesConfigList(String label, List<FacesConfig> appConfigResources)
52      {
53          System.out.println("");
54          System.out.print(""+label+": [");
55          for (int i = 0; i < appConfigResources.size();i++)
56          {
57              if (appConfigResources.get(i).getName() == null)
58              {
59                  System.out.print("No_id,");
60              }
61              else
62              {
63                  System.out.print(appConfigResources.get(i).getName()+",");
64              }
65          }
66          System.out.println("]");
67  
68      }
69      
70      /**
71       * A before others
72       * B after C
73       * C after others
74       * 
75       * preferred result:
76       * 
77       * A C B No_id No_id 
78       * 
79       * @throws Exception
80       */
81      public void testSimpleOrdering() throws Exception
82      {
83          FacesConfig cfg = _impl.getFacesConfig(getClass().getResourceAsStream(
84          "empty-config.xml"), "empty-config.xml");
85          FacesConfig cfgA = _impl.getFacesConfig(getClass().getResourceAsStream(
86              "a-config.xml"), "a-config.xml");
87          FacesConfig cfgB = _impl.getFacesConfig(getClass().getResourceAsStream(
88              "b-config.xml"), "b-config.xml");
89          FacesConfig cfgC = _impl.getFacesConfig(getClass().getResourceAsStream(
90              "c-config.xml"), "c-config.xml");
91          
92          
93          List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
94          appConfigResources.add(cfgA);
95          appConfigResources.add(cfgB);
96          appConfigResources.add(cfgC);
97          appConfigResources.add(cfg);
98          appConfigResources.add(cfg);
99          
100         //Brute force       
101         for (int i = 0; i < 30; i++)
102         {
103             Collections.shuffle(appConfigResources);
104             applyAlgorithm(appConfigResources);
105         }
106     }
107     
108     /**
109      * A before B
110      * A before E
111      * C after A
112      * C after B
113      * C before D
114      * C before E
115      * E after D
116      * D before others
117      * 
118      * preferred results:
119      * 
120      * A B C D E No_id
121      * 
122      * @throws Exception
123      */
124     public void testMiddleOrdering() throws Exception
125     {
126         FacesConfig cfg = _impl.getFacesConfig(getClass().getResourceAsStream(
127         "empty-config.xml"), "empty-config.xml");        
128         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgA = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
129         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgB = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
130         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgC = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
131         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgD = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
132         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgE = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
133         
134         cfgA.setName("A");
135         cfgB.setName("B");
136         cfgC.setName("C");
137         cfgD.setName("D");
138         cfgE.setName("E");
139         
140         cfgC.setOrdering(new OrderingImpl());
141         FacesConfigNameSlotImpl temp = new FacesConfigNameSlotImpl();
142         temp.setName("D");
143         cfgC.getOrdering().getBeforeList().add(temp);
144         temp = new FacesConfigNameSlotImpl();
145         temp.setName("E");
146         cfgC.getOrdering().getBeforeList().add(temp);        
147         temp = new FacesConfigNameSlotImpl();
148         temp.setName("A");
149         cfgC.getOrdering().getAfterList().add(temp);
150         temp = new FacesConfigNameSlotImpl();
151         temp.setName("B");
152         cfgC.getOrdering().getAfterList().add(temp);
153         
154         cfgA.setOrdering(new OrderingImpl());
155         temp = new FacesConfigNameSlotImpl();
156         temp.setName("B");
157         cfgA.getOrdering().getBeforeList().add(temp);
158         temp = new FacesConfigNameSlotImpl();
159         temp.setName("E");
160         cfgA.getOrdering().getBeforeList().add(temp);
161         
162         cfgE.setOrdering(new OrderingImpl());
163         temp = new FacesConfigNameSlotImpl();
164         temp.setName("D");
165         cfgE.getOrdering().getAfterList().add(temp);
166         
167         cfgD.setOrdering(new OrderingImpl());
168         cfgD.getOrdering().getBeforeList().add(new ConfigOthersSlotImpl());
169         
170         List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
171         appConfigResources.add(cfgA);
172         appConfigResources.add(cfgB);
173         appConfigResources.add(cfgC);
174         appConfigResources.add(cfgD);
175         appConfigResources.add(cfgE);
176         appConfigResources.add(cfg);
177         
178         //Brute force       
179         for (int i = 0; i < 30; i++)
180         {
181             Collections.shuffle(appConfigResources);
182             applyAlgorithm(appConfigResources);
183         }
184     }
185     
186     /**
187      * A before B
188      * A before C
189      * B after A
190      * B before C
191      * C after A
192      * C after B
193      * 
194      * preferred result
195      * 
196      * A B C
197      * 
198      * @throws Exception
199      */
200     public void testMaxConditionsOrdering() throws Exception
201     {
202         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfg = _impl.getFacesConfig(getClass().getResourceAsStream(
203         "empty-config.xml"), "empty-config.xml");        
204         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgA = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
205         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgB = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
206         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgC = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
207 
208         cfgA.setName("A");
209         cfgB.setName("B");
210         cfgC.setName("C");
211         
212         cfgA.setOrdering(new OrderingImpl());
213         FacesConfigNameSlotImpl temp = new FacesConfigNameSlotImpl();
214         temp.setName("B");
215         cfgA.getOrdering().getBeforeList().add(temp);
216         temp = new FacesConfigNameSlotImpl();
217         temp.setName("C");
218         cfgA.getOrdering().getBeforeList().add(temp);
219         
220         cfgB.setOrdering(new OrderingImpl());
221         temp = new FacesConfigNameSlotImpl();
222         temp.setName("A");
223         cfgB.getOrdering().getAfterList().add(temp);
224         temp = new FacesConfigNameSlotImpl();
225         temp.setName("C");
226         cfgB.getOrdering().getBeforeList().add(temp);
227         
228         cfgC.setOrdering(new OrderingImpl());
229         temp = new FacesConfigNameSlotImpl();
230         temp.setName("A");
231         cfgC.getOrdering().getAfterList().add(temp);
232         temp = new FacesConfigNameSlotImpl();
233         temp.setName("B");
234         cfgC.getOrdering().getAfterList().add(temp);
235         //cfgC.getOrdering().getBeforeList().add(new ConfigOthersSlot());
236         
237         List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
238         appConfigResources.add(cfgC);
239         appConfigResources.add(cfgA);
240         appConfigResources.add(cfgB);
241         
242         //Brute force       
243         for (int i = 0; i < 30; i++)
244         {
245             Collections.shuffle(appConfigResources);
246             applyAlgorithm(appConfigResources);
247         }
248     }
249     
250     public void testEx1()
251     {      
252         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgA = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
253         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgB = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
254         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgC = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
255         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgD = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
256         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgE = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
257         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgF = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
258 
259         cfgA.setName("A");
260         cfgB.setName("B");
261         cfgC.setName("C");
262         cfgD.setName("D");
263         cfgE.setName("E");
264         cfgF.setName("F");
265         
266         cfgA.setOrdering(new OrderingImpl());
267         cfgA.getOrdering().getAfterList().add(new ConfigOthersSlotImpl());
268         FacesConfigNameSlotImpl temp = new FacesConfigNameSlotImpl();
269         temp.setName("C");
270         cfgA.getOrdering().getAfterList().add(temp);
271         
272         cfgB.setOrdering(new OrderingImpl());
273         cfgB.getOrdering().getBeforeList().add(new ConfigOthersSlotImpl());
274 
275         cfgC.setOrdering(new OrderingImpl());
276         cfgC.getOrdering().getAfterList().add(new ConfigOthersSlotImpl());
277 
278         cfgF.setOrdering(new OrderingImpl());
279         cfgF.getOrdering().getBeforeList().add(new ConfigOthersSlotImpl());
280         temp = new FacesConfigNameSlotImpl();
281         temp.setName("B");
282         cfgF.getOrdering().getBeforeList().add(temp);
283         
284         
285         List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
286         appConfigResources.add(cfgA);
287         appConfigResources.add(cfgB);
288         appConfigResources.add(cfgC);
289         appConfigResources.add(cfgD);
290         appConfigResources.add(cfgE);
291         appConfigResources.add(cfgF);
292         
293         //Brute force       
294         for (int i = 0; i < 30; i++)
295         {
296             Collections.shuffle(appConfigResources);
297             applyAlgorithm(appConfigResources);
298         }
299     }
300     
301     public void testEx2()
302     {
303         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfg = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
304         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgB = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
305         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgC = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
306         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgD = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
307         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgE = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
308         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgF = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
309 
310         cfgB.setName("B");
311         cfgC.setName("C");
312         cfgD.setName("D");
313         cfgE.setName("E");
314         cfgF.setName("F");
315         
316         cfg.setOrdering(new OrderingImpl());
317         cfg.getOrdering().getAfterList().add(new ConfigOthersSlotImpl());
318         FacesConfigNameSlotImpl temp = new FacesConfigNameSlotImpl();
319         temp.setName("C");
320         cfg.getOrdering().getBeforeList().add(temp);
321 
322         cfgB.setOrdering(new OrderingImpl());
323         cfgB.getOrdering().getBeforeList().add(new ConfigOthersSlotImpl());
324         
325         cfgD.setOrdering(new OrderingImpl());
326         cfgD.getOrdering().getAfterList().add(new ConfigOthersSlotImpl());
327 
328         cfgE.setOrdering(new OrderingImpl());
329         cfgE.getOrdering().getBeforeList().add(new ConfigOthersSlotImpl());
330 
331         List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
332         appConfigResources.add(cfg);
333         appConfigResources.add(cfgB);
334         appConfigResources.add(cfgC);
335         appConfigResources.add(cfgD);
336         appConfigResources.add(cfgE);
337         appConfigResources.add(cfgF);
338 
339         //Brute force       
340         for (int i = 0; i < 30; i++)
341         {
342             Collections.shuffle(appConfigResources);
343             applyAlgorithm(appConfigResources);
344         }
345     }
346     
347     public void testEx3()
348     {
349         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgA = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
350         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgB = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
351         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgC = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
352         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgD = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
353 
354         cfgA.setName("A");
355         cfgB.setName("B");
356         cfgC.setName("C");
357         cfgD.setName("D");
358 
359         cfgA.setOrdering(new OrderingImpl());
360         FacesConfigNameSlotImpl temp = new FacesConfigNameSlotImpl();
361         temp.setName("B");
362         cfgA.getOrdering().getAfterList().add(temp);
363 
364         cfgC.setOrdering(new OrderingImpl());
365         cfgC.getOrdering().getBeforeList().add(new ConfigOthersSlotImpl());
366         
367         List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
368         appConfigResources.add(cfgA);
369         appConfigResources.add(cfgB);
370         appConfigResources.add(cfgC);
371         appConfigResources.add(cfgD);
372 
373         //Brute force       
374         for (int i = 0; i < 30; i++)
375         {
376             Collections.shuffle(appConfigResources);
377             applyAlgorithm(appConfigResources);
378         }
379     }
380     
381     public void testEx4() throws Exception
382     {
383         FacesConfig cfgA = _impl.getFacesConfig(getClass().getResourceAsStream(
384             "transitive-a-config.xml"), "transitive-a-config.xml");
385         FacesConfig cfgB = _impl.getFacesConfig(getClass().getResourceAsStream(
386             "transitive-b-config.xml"), "transitive-b-config.xml");
387         FacesConfig cfgC = _impl.getFacesConfig(getClass().getResourceAsStream(
388             "transitive-c-config.xml"), "transitive-c-config.xml");
389         
390         List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
391         appConfigResources.add(cfgA);
392         appConfigResources.add(cfgB);
393         appConfigResources.add(cfgC);
394         
395         //Brute force       
396         for (int i = 0; i < 30; i++)
397         {
398             Collections.shuffle(appConfigResources);
399             applyAlgorithm(appConfigResources);
400         }
401     }
402 
403     public void applyAlgorithm(List<FacesConfig> appConfigResources) throws FacesException
404     {
405         DefaultFacesConfigurationMerger merger = new DefaultFacesConfigurationMerger();
406 
407         List<FacesConfig> postOrderedList = merger.getPostOrderedList(appConfigResources);
408         
409         List<FacesConfig> sortedList = merger.sortRelativeOrderingList(postOrderedList);
410         
411         if (sortedList == null)
412         {
413             //The previous algorithm can't sort correctly, try this one
414             sortedList = merger.applySortingAlgorithm(appConfigResources);
415         }
416         
417         //printFacesConfigList("Sorted List", sortedList);
418     }
419 
420     public void testBeforeOthers1() throws Exception
421     {
422         FacesConfig cfgA = _impl.getFacesConfig(getClass().getResourceAsStream(
423             "no-name-config.xml"), "no-name-config.xml");
424         FacesConfig cfgB = _impl.getFacesConfig(getClass().getResourceAsStream(
425             "no-name-config.xml"), "no-name-config.xml");
426         FacesConfig cfgC = _impl.getFacesConfig(getClass().getResourceAsStream(
427             "before-others-config.xml"), "before-others-config.xml");
428         FacesConfig cfgD = _impl.getFacesConfig(getClass().getResourceAsStream(
429             "no-name-config.xml"), "no-name-config.xml");        
430         FacesConfig cfgE = _impl.getFacesConfig(getClass().getResourceAsStream(
431             "no-name-config.xml"), "no-name-config.xml");        
432         
433         List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
434         appConfigResources.add(cfgA);
435         appConfigResources.add(cfgB);
436         appConfigResources.add(cfgC);
437         appConfigResources.add(cfgD);
438         appConfigResources.add(cfgE);
439         
440         //Brute force       
441         for (int i = 0; i < 30; i++)
442         {
443             Collections.shuffle(appConfigResources);
444             List<FacesConfig> sortedList = applyFullAlgorithm(appConfigResources);
445             
446             assertEquals(cfgC, sortedList.get(0));
447         }
448     }
449 
450     public void testAfterOthers1() throws Exception
451     {
452         FacesConfig cfgA = _impl.getFacesConfig(getClass().getResourceAsStream(
453             "no-name-config.xml"), "no-name-config.xml");
454         FacesConfig cfgB = _impl.getFacesConfig(getClass().getResourceAsStream(
455             "no-name-config.xml"), "no-name-config.xml");
456         FacesConfig cfgC = _impl.getFacesConfig(getClass().getResourceAsStream(
457             "after-others-config.xml"), "after-others-config.xml");
458         FacesConfig cfgD = _impl.getFacesConfig(getClass().getResourceAsStream(
459             "no-name-config.xml"), "no-name-config.xml");        
460         FacesConfig cfgE = _impl.getFacesConfig(getClass().getResourceAsStream(
461             "no-name-config.xml"), "no-name-config.xml");        
462         
463         List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
464         appConfigResources.add(cfgA);
465         appConfigResources.add(cfgB);
466         appConfigResources.add(cfgC);
467         appConfigResources.add(cfgD);
468         appConfigResources.add(cfgE);
469         
470         //Brute force       
471         for (int i = 0; i < 30; i++)
472         {
473             Collections.shuffle(appConfigResources);
474             List<FacesConfig> sortedList = applyFullAlgorithm(appConfigResources);
475             
476             assertEquals(cfgC, sortedList.get(sortedList.size()-1));
477         }
478     }
479     
480     public void testBeforeOthers2() throws Exception
481     {
482         FacesConfig cfg1 = _impl.getFacesConfig(getClass().getResourceAsStream(
483             "no-name-config.xml"), "no-name-config.xml");
484         FacesConfig cfg2 = _impl.getFacesConfig(getClass().getResourceAsStream(
485             "no-name-config.xml"), "no-name-config.xml");
486         FacesConfig cfg3 = _impl.getFacesConfig(getClass().getResourceAsStream(
487             "before-others-config.xml"), "before-others-config.xml");
488         FacesConfig cfg4 = _impl.getFacesConfig(getClass().getResourceAsStream(
489             "no-name-config.xml"), "no-name-config.xml");        
490         FacesConfig cfg5 = _impl.getFacesConfig(getClass().getResourceAsStream(
491             "no-name-config.xml"), "no-name-config.xml");     
492         FacesConfig cfgA = _impl.getFacesConfig(getClass().getResourceAsStream(
493             "transitive-a-config.xml"), "transitive-a-config.xml");
494         FacesConfig cfgB = _impl.getFacesConfig(getClass().getResourceAsStream(
495             "transitive-b-config.xml"), "transitive-b-config.xml");
496         FacesConfig cfgC = _impl.getFacesConfig(getClass().getResourceAsStream(
497             "transitive-c-config.xml"), "transitive-c-config.xml");
498         FacesConfig cfg6 = _impl.getFacesConfig(getClass().getResourceAsStream(
499             "after-others-config.xml"), "after-others-config.xml");
500         
501         
502         List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
503         appConfigResources.add(cfgA);
504         appConfigResources.add(cfgB);
505         appConfigResources.add(cfgC);
506         appConfigResources.add(cfg1);
507         appConfigResources.add(cfg2);
508         appConfigResources.add(cfg3);
509         appConfigResources.add(cfg4);
510         appConfigResources.add(cfg5);
511         appConfigResources.add(cfg6);
512         
513         //Brute force       
514         for (int i = 0; i < 30; i++)
515         {
516             Collections.shuffle(appConfigResources);
517             List<FacesConfig> sortedList = applyFullAlgorithm(appConfigResources);
518             
519             assertEquals(cfg3, sortedList.get(0));
520             
521             assertEquals(cfg6, sortedList.get(sortedList.size()-1));
522         }
523     }
524     
525     public List<FacesConfig> applyFullAlgorithm(List<FacesConfig> appConfigResources) throws FacesException
526     {    
527         DefaultFacesConfigurationMerger merger = new DefaultFacesConfigurationMerger();
528         
529         System.out.println("");
530         System.out.print("Start List: [");
531         for (int i = 0; i < appConfigResources.size();i++)
532         {
533             if (appConfigResources.get(i).getName() == null)
534             {
535                 System.out.print("No id,");
536             }
537             else
538             {
539                 System.out.print(appConfigResources.get(i).getName()+",");
540             }
541         }
542         System.out.println("]");
543         
544         List<FacesConfig> postOrderedList = merger.getPostOrderedList(appConfigResources);
545         
546         System.out.print("Pre-Ordered-List: [");
547         for (int i = 0; i < postOrderedList.size();i++)
548         {
549             if (postOrderedList.get(i).getName() == null)
550             {
551                 System.out.print("No id,");
552             }
553             else
554             {
555                 System.out.print(postOrderedList.get(i).getName()+",");
556             }
557         }
558         System.out.println("]");
559         
560         List<FacesConfig> sortedList = merger.sortRelativeOrderingList(postOrderedList);
561 
562         if (sortedList == null)
563         {
564             System.out.print("After Fix ");
565             //The previous algorithm can't sort correctly, try this one
566             sortedList = merger.applySortingAlgorithm(appConfigResources);
567         }
568         
569         System.out.print("Sorted-List: [");
570         for (int i = 0; i < sortedList.size();i++)
571         {
572             if (sortedList.get(i).getName() == null)
573             {
574                 System.out.print("No id,");
575             }
576             else
577             {
578                 System.out.print(sortedList.get(i).getName()+",");
579             }
580         }
581         System.out.println("]");
582         
583         return sortedList;
584     }
585     /*
586     public void applyAlgorithm(List<FacesConfig> appConfigResources) throws FacesException
587     {
588         printFacesConfigList("Start List", appConfigResources);
589         
590         //0. Convert the references into a graph
591         List<Vertex> vertexList = new ArrayList<Vertex>();
592         for (FacesConfig config : appConfigResources)
593         {
594             Vertex v = null;
595             if (config.getName() != null)
596             {
597                 v = new Vertex(config.getName(), config);
598             }
599             else
600             {
601                 v = new Vertex(config);
602             }
603             vertexList.add(v);
604         }
605         
606         //1. Resolve dependencies (before-after rules) and mark referenced vertex
607         boolean[] referencedVertex = new boolean[vertexList.size()];
608 
609         for (int i = 0; i < vertexList.size(); i++)
610         {
611             Vertex v = vertexList.get(i);
612             FacesConfig f = (FacesConfig) v.getNode();
613             
614             if (f.getOrdering() != null)
615             {
616                 for (OrderSlot slot : f.getOrdering().getBeforeList())
617                 {
618                     if (slot instanceof FacesConfigNameSlot)
619                     {
620                         String name = ((FacesConfigNameSlot) slot).getName();
621                         int j = findVertex(vertexList, name);
622                         Vertex v1 = vertexList.get(j);
623                         if (v1 != null)
624                         {
625                             referencedVertex[i] = true;
626                             referencedVertex[j] = true;
627                             v1.addDependency(v);
628                         }
629                     }
630                 }
631                 for (OrderSlot slot : f.getOrdering().getAfterList())
632                 {
633                     if (slot instanceof FacesConfigNameSlot)
634                     {
635                         String name = ((FacesConfigNameSlot) slot).getName();
636                         int j = findVertex(vertexList, name);
637                         Vertex v1 = vertexList.get(j);
638                         if (v1 != null)
639                         {
640                             referencedVertex[i] = true;
641                             referencedVertex[j] = true;
642                             v.addDependency(v1);
643                         }
644                     }
645                 }
646             }
647         }
648 
649         //2. Classify into categories
650         List<Vertex> beforeAfterOthersList = new ArrayList<Vertex>();
651         List<Vertex> othersList = new ArrayList<Vertex>();
652         List<Vertex> referencedList = new ArrayList<Vertex>();
653         
654         for (int i = 0; i < vertexList.size(); i++)
655         {
656             if (!referencedVertex[i])
657             {
658                 Vertex v = vertexList.get(i);
659                 FacesConfig f = (FacesConfig) v.getNode();
660                 boolean added = false;
661                 if (f.getOrdering() != null)
662                 {
663                     if (!f.getOrdering().getBeforeList().isEmpty())
664                     {
665                         added = true;
666                         beforeAfterOthersList.add(v);                        
667                     }
668                     else if (!f.getOrdering().getAfterList().isEmpty())
669                     {
670                         added = true;
671                         beforeAfterOthersList.add(v);
672                     }
673                 }
674                 if (!added)
675                 {
676                     othersList.add(v);
677                 }
678             }
679             else
680             {
681                 referencedList.add(vertexList.get(i));
682             }
683         }
684         
685         //3. Sort all referenced nodes
686         try
687         {
688             DirectedAcyclicGraphVerifier.topologicalSort(referencedList);
689         }
690         catch (CyclicDependencyException e)
691         {
692             e.printStackTrace();
693         }
694 
695         //4. Add referenced nodes
696         List<FacesConfig> sortedList = new ArrayList<FacesConfig>();
697         for (Vertex v : referencedList)
698         {
699             sortedList.add((FacesConfig)v.getNode());
700         }
701         
702         //5. add nodes without instructions at the end
703         for (Vertex v : othersList)
704         {
705             sortedList.add((FacesConfig)v.getNode());
706         }
707         
708         //6. add before/after nodes
709         for (Vertex v : beforeAfterOthersList)
710         {
711             FacesConfig f = (FacesConfig) v.getNode();
712             boolean added = false;
713             if (f.getOrdering() != null)
714             {
715                 if (!f.getOrdering().getBeforeList().isEmpty())
716                 {
717                     added = true;
718                     sortedList.add(0,f);                        
719                 }
720             }
721             if (!added)
722             {
723                 sortedList.add(f);
724             }            
725         }
726         
727         printFacesConfigList("Sorted List", sortedList);
728         
729         //Check
730         for (int i = 0; i < sortedList.size(); i++)
731         {
732             FacesConfig resource = sortedList.get(i);
733             
734             if (resource.getOrdering() != null)
735             {
736                 for (OrderSlot slot : resource.getOrdering().getBeforeList())
737                 {
738                     if (slot instanceof FacesConfigNameSlot)
739                     {
740                         String name = ((FacesConfigNameSlot) slot).getName();
741                         if (name != null && !"".equals(name))
742                         {
743                             boolean founded = false;                                
744                             for (int j = i-1; j >= 0; j--)
745                             {
746                                 if (name.equals(sortedList.get(j).getName()))
747                                 {
748                                     founded=true;
749                                     break;
750                                 }
751                             }
752                             if (founded)
753                             {
754                                 log.severe("Circular references detected when sorting " +
755                                           "application config resources. Use absolute ordering instead.");
756                                 throw new FacesException("Circular references detected when sorting " +
757                                         "application config resources. Use absolute ordering instead.");
758                             }
759                         }
760                     }
761                 }
762                 for (OrderSlot slot : resource.getOrdering().getAfterList())
763                 {
764                     if (slot instanceof FacesConfigNameSlot)
765                     {
766                         String name = ((FacesConfigNameSlot) slot).getName();
767                         if (name != null && !"".equals(name))
768                         {
769                             boolean founded = false;                                
770                             for (int j = i+1; j < sortedList.size(); j++)
771                             {
772                                 if (name.equals(sortedList.get(j).getName()))
773                                 {
774                                     founded=true;
775                                     break;
776                                 }
777                             }
778                             if (founded)
779                             {
780                                 log.severe("Circular references detected when sorting " +
781                                     "application config resources. Use absolute ordering instead.");
782                                 throw new FacesException("Circular references detected when sorting " +
783                                     "application config resources. Use absolute ordering instead.");
784                             }
785                         }
786                     }
787                 }
788             }
789         }
790     }
791     
792     public int findVertex(List<Vertex> vertexList, String name)
793     {
794         for (int i = 0; i < vertexList.size(); i++)
795         {
796             Vertex v = vertexList.get(i);
797             if (name.equals(v.getName()))
798             {
799                 return i;
800             }
801         }
802         return -1;
803     }*/
804 
805     public void applyAlgorithm2(List<FacesConfig> appConfigResources) throws FacesException
806     {
807         DefaultFacesConfigurationMerger merger = new DefaultFacesConfigurationMerger();
808         
809         System.out.println("");
810         System.out.print("Start List: [");
811         for (int i = 0; i < appConfigResources.size();i++)
812         {
813             if (appConfigResources.get(i).getName() == null)
814             {
815                 System.out.print("No id,");
816             }
817             else
818             {
819                 System.out.print(appConfigResources.get(i).getName()+",");
820             }
821         }
822         System.out.println("]");
823         
824         List<FacesConfig> postOrderedList = merger.getPostOrderedList(appConfigResources);
825         
826         System.out.print("Pre-Ordered-List: [");
827         for (int i = 0; i < postOrderedList.size();i++)
828         {
829             if (postOrderedList.get(i).getName() == null)
830             {
831                 System.out.print("No id,");
832             }
833             else
834             {
835                 System.out.print(postOrderedList.get(i).getName()+",");
836             }
837         }
838         System.out.println("]");
839         
840         List<FacesConfig> sortedList = merger.sortRelativeOrderingList(postOrderedList);
841         
842         System.out.print("Sorted-List: [");
843         for (int i = 0; i < sortedList.size();i++)
844         {
845             if (sortedList.get(i).getName() == null)
846             {
847                 System.out.print("No id,");
848             }
849             else
850             {
851                 System.out.print(sortedList.get(i).getName()+",");
852             }
853         }
854         System.out.println("]");
855     }
856     
857     public void testAbsoluteOrdering1() throws Exception
858     {
859         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgAbs = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
860         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgMK = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
861         org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl cfgOWB = new org.apache.myfaces.config.impl.digester.elements.FacesConfigImpl();
862 
863         cfgMK.setName("cz_markoc_faces");
864         
865         AbsoluteOrderingImpl ao = new AbsoluteOrderingImpl();
866         FacesConfigNameSlotImpl temp = new FacesConfigNameSlotImpl();
867         temp.setName("cz_markoc_faces");
868         ao.addOrderSlot(temp);
869         ao.addOrderSlot(new ConfigOthersSlotImpl());
870         
871         cfgAbs.setAbsoluteOrdering(ao);
872 
873         List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
874         appConfigResources.add(cfgMK);
875         appConfigResources.add(cfgOWB);
876         
877         //printFacesConfigList("Start List: [", appConfigResources);
878         
879         List<FacesConfig> sortedResources = orderAndFeedArtifactsAbsolute(appConfigResources, cfgAbs);
880         
881         //printFacesConfigList("Sorted-List: [", sortedResources);
882         
883         assertTrue(sortedResources.containsAll(appConfigResources));
884 
885         appConfigResources = new ArrayList<FacesConfig>();
886         appConfigResources.add(cfgOWB);
887         appConfigResources.add(cfgMK);
888         
889         //printFacesConfigList("Start List: [", appConfigResources);
890         
891         sortedResources = orderAndFeedArtifactsAbsolute(appConfigResources, cfgAbs);
892         
893         //printFacesConfigList("Sorted-List: [", sortedResources);
894         
895         assertTrue(sortedResources.containsAll(appConfigResources));
896 
897     }
898     
899     public List<FacesConfig> orderAndFeedArtifactsAbsolute(List<FacesConfig> appConfigResources, FacesConfig webAppConfig)
900     {
901         FacesConfigurator configurator = new FacesConfigurator(externalContext);
902 
903         if (webAppConfig != null && webAppConfig.getAbsoluteOrdering() != null)
904         {
905             if (webAppConfig.getOrdering() != null)
906             {
907                 if (log.isLoggable(Level.WARNING))
908                 {
909                     log.warning("<ordering> element found in application faces config. " +
910                             "This description will be ignored and the actions described " +
911                             "in <absolute-ordering> element will be taken into account instead.");
912                 }                
913             }
914             //Absolute ordering
915             
916             //1. Scan all appConfigResources and create a list
917             //containing all resources not mentioned directly, preserving the
918             //order founded
919             List<FacesConfig> othersResources = new ArrayList<FacesConfig>();
920             List<OrderSlot> slots = webAppConfig.getAbsoluteOrdering().getOrderList();
921             for (FacesConfig resource : appConfigResources)
922             {
923                 // First condition: if faces-config.xml does not have name it is 1) pre-JSF-2.0 or 2) has no <name> element,
924                 // -> in both cases cannot be ordered
925                 // Second condition : faces-config.xml has a name but <ordering> element does not have slot with that name
926                 //  -> resource can be ordered, but will fit into <others /> element
927                 if ((resource.getName() == null) || (resource.getName() != null && !containsResourceInSlot(slots, resource.getName())))
928                 {
929                     othersResources.add(resource);
930                 }
931             }
932 
933             List<FacesConfig> sortedResources = new ArrayList<FacesConfig>();
934             //2. Scan slot by slot and merge information according
935             for (OrderSlot slot : webAppConfig.getAbsoluteOrdering().getOrderList())
936             {
937                 if (slot instanceof ConfigOthersSlotImpl)
938                 {
939                     //Add all mentioned in othersResources
940                     for (FacesConfig resource : othersResources)
941                     {
942                         sortedResources.add(resource);
943                     }
944                 }
945                 else
946                 {
947                     //Add it to the sorted list
948                     FacesConfigNameSlotImpl nameSlot = (FacesConfigNameSlotImpl) slot;
949                     sortedResources.add(getFacesConfig(appConfigResources, nameSlot.getName()));
950                 }
951             }
952             
953             return sortedResources;
954         }
955         
956         return null;
957     }
958 
959     private FacesConfig getFacesConfig(List<FacesConfig> appConfigResources, String name)
960     {
961         for (FacesConfig cfg: appConfigResources)
962         {
963             if (cfg.getName() != null && name.equals(cfg.getName()))
964             {
965                 return cfg;
966             }
967         }
968         return null;
969     }
970     
971     private boolean containsResourceInSlot(List<OrderSlot> slots, String name)
972     {
973         for (OrderSlot slot: slots)
974         {
975             if (slot instanceof FacesConfigNameSlotImpl)
976             {
977                 FacesConfigNameSlotImpl nameSlot = (FacesConfigNameSlotImpl) slot;
978                 if (name.equals(nameSlot.getName()))
979                 {
980                     return true;
981                 }
982             }
983         }
984         return false;
985     }
986 
987     /**
988      * Sort a list of pre ordered elements. It scans one by one the elements
989      * and apply the conditions mentioned by Ordering object if it is available.
990      * 
991      * The preOrderedList ensures that application config resources referenced by
992      * other resources are processed first, making more easier the sort procedure. 
993      * 
994      * @param preOrderedList
995      * @return
996      */
997     /*
998     private List<FacesConfig> sortRelativeOrderingList(List<FacesConfig> preOrderedList) throws FacesException
999     {
1000         List<FacesConfig> sortedList = new ArrayList<FacesConfig>();
1001         
1002         for (int i=0; i < preOrderedList.size(); i++)
1003         {
1004             FacesConfig resource = preOrderedList.get(i);
1005             if (resource.getOrdering() != null)
1006             {
1007                 if (resource.getOrdering().getBeforeList().isEmpty() &&
1008                     resource.getOrdering().getAfterList().isEmpty())
1009                 {
1010                     //No order rules, just put it as is
1011                     sortedList.add(resource);
1012                 }
1013                 else if (resource.getOrdering().getBeforeList().isEmpty())
1014                 {
1015                     //Only after rules
1016                     applyAfterRule(sortedList, resource);
1017                 }
1018                 else if (resource.getOrdering().getAfterList().isEmpty())
1019                 {
1020                     //Only before rules
1021                     
1022                     //Resolve if there is a later reference to this node before
1023                     //apply it
1024                     boolean referenceNode = false;
1025 
1026                     for (int j = i+1; j < preOrderedList.size(); j++)
1027                     {
1028                         FacesConfig pointingResource = preOrderedList.get(j);
1029                         for (OrderSlot slot : pointingResource.getOrdering().getBeforeList())
1030                         {
1031                             if (slot instanceof FacesConfigNameSlot &&
1032                                     resource.getName().equals(((FacesConfigNameSlot)slot).getName()) )
1033                             {
1034                                 referenceNode = true;
1035                             }
1036                             if (slot instanceof ConfigOthersSlot)
1037                             {
1038                                 //No matter if there is a reference, because this rule
1039                                 //is not strict and before other ordering is unpredictable.
1040                                 //
1041                                 referenceNode = false;
1042                                 break;
1043                             }
1044                         }
1045                         if (referenceNode)
1046                         {
1047                             break;
1048                         }
1049                         for (OrderSlot slot : pointingResource.getOrdering().getAfterList())
1050                         {
1051                             if (slot instanceof FacesConfigNameSlot &&
1052                                 resource.getName().equals(((FacesConfigNameSlot)slot).getName()) )
1053                             {
1054                                 referenceNode = true;
1055                                 break;
1056                             }
1057                         }
1058                     }
1059                     
1060                     applyBeforeRule(sortedList, resource, referenceNode);
1061                 }
1062                 else
1063                 {
1064                     //Both before and after rules
1065                     //In this case we should compare before and after rules
1066                     //and the one with names takes precedence over the other one.
1067                     //It both have names references, before rules takes
1068                     //precedence over after
1069                     //after some action is applied a check of the condition is made.
1070                     int beforeWeight = 0;
1071                     int afterWeight = 0;
1072                     for (OrderSlot slot : resource.getOrdering()
1073                             .getBeforeList())
1074                     {
1075                         if (slot instanceof FacesConfigNameSlot)
1076                         {
1077                             beforeWeight++;
1078                         }
1079                     }
1080                     for (OrderSlot slot : resource.getOrdering()
1081                             .getAfterList())
1082                     {
1083                         if (slot instanceof FacesConfigNameSlot)
1084                         {
1085                             afterWeight++;
1086                         }
1087                     }
1088                     
1089                     if (beforeWeight >= afterWeight)
1090                     {
1091                         applyBeforeRule(sortedList, resource,false);
1092                     }
1093                     else
1094                     {
1095                         applyAfterRule(sortedList, resource);
1096                     }
1097                     
1098                     
1099                 }
1100             }
1101             else
1102             {
1103                 //No order rules, just put it as is
1104                 sortedList.add(resource);
1105             }
1106         }
1107         
1108         //Check
1109         for (int i = 0; i < sortedList.size(); i++)
1110         {
1111             FacesConfig resource = sortedList.get(i);
1112             
1113             if (resource.getOrdering() != null)
1114             {
1115                 for (OrderSlot slot : resource.getOrdering().getBeforeList())
1116                 {
1117                     if (slot instanceof FacesConfigNameSlot)
1118                     {
1119                         String name = ((FacesConfigNameSlot) slot).getName();
1120                         if (name != null && !"".equals(name))
1121                         {
1122                             boolean founded = false;                                
1123                             for (int j = i-1; j >= 0; j--)
1124                             {
1125                                 if (name.equals(sortedList.get(j).getName()))
1126                                 {
1127                                     founded=true;
1128                                     break;
1129                                 }
1130                             }
1131                             if (founded)
1132                             {
1133                                 //LOG WARN MESSAGE ABOUT IT
1134                                 throw new FacesException();
1135                             }
1136                         }
1137                     }
1138                 }
1139                 for (OrderSlot slot : resource.getOrdering().getAfterList())
1140                 {
1141                     if (slot instanceof FacesConfigNameSlot)
1142                     {
1143                         String name = ((FacesConfigNameSlot) slot).getName();
1144                         if (name != null && !"".equals(name))
1145                         {
1146                             boolean founded = false;                                
1147                             for (int j = i+1; j < sortedList.size(); j++)
1148                             {
1149                                 if (name.equals(sortedList.get(j).getName()))
1150                                 {
1151                                     founded=true;
1152                                     break;
1153                                 }
1154                             }
1155                             if (founded)
1156                             {
1157                                 //LOG WARN MESSAGE ABOUT IT
1158                                 throw new FacesException();
1159                             }
1160                         }
1161                     }
1162                 }
1163             }
1164         }
1165         
1166         return sortedList;
1167     }
1168     
1169     private void applyBeforeRule(List<FacesConfig> sortedList, FacesConfig resource, boolean referenced) throws FacesException
1170     {
1171         //Only before rules
1172         boolean configOthers = false;
1173         List<String> names = new ArrayList<String>();
1174         
1175         for (OrderSlot slot : resource.getOrdering().getBeforeList())
1176         {
1177             if (slot instanceof ConfigOthersSlot)
1178             {
1179                 configOthers = true;
1180                 break;
1181             }
1182             else
1183             {
1184                 FacesConfigNameSlot nameSlot = (FacesConfigNameSlot) slot;
1185                 names.add(nameSlot.getName());
1186             }
1187         }
1188         
1189         if (configOthers)
1190         {
1191             //<before>....<others/></before> case
1192             //other reference where already considered when
1193             //pre ordered list was calculated, so just add to the end.
1194             
1195             //There is one very special case, and it is when there
1196             //is another resource with a reference on it. In this case,
1197             //it is better do not apply this rule and add it to the end
1198             //to give the chance to the other one to be applied.
1199             if (resource.getOrdering().getBeforeList().size() > 1)
1200             {
1201                 //If there is a reference apply it
1202                 sortedList.add(0,resource);
1203             }
1204             else if (!referenced)
1205             {
1206                 //If it is not referenced apply it
1207                 sortedList.add(0,resource);
1208             }
1209             else
1210             {
1211                 //if it is referenced bypass the rule and add it to the end
1212                 sortedList.add(resource);
1213             }
1214         }
1215         else
1216         {
1217             //Scan the nearest reference and add it after
1218             boolean founded = false;
1219             for (int i = 0; i < sortedList.size() ; i++)
1220             {
1221                 if (names.contains(sortedList.get(i).getName()))
1222                 {
1223                     sortedList.add(i,resource);
1224                     founded = true;
1225                     break;
1226                 }
1227             }
1228             if (!founded)
1229             {
1230                 //just add it to the end
1231                 sortedList.add(resource);
1232             }
1233         }        
1234     }
1235     
1236     private void applyAfterRule(List<FacesConfig> sortedList, FacesConfig resource) throws FacesException
1237     {
1238         boolean configOthers = false;
1239         List<String> names = new ArrayList<String>();
1240         
1241         for (OrderSlot slot : resource.getOrdering().getAfterList())
1242         {
1243             if (slot instanceof ConfigOthersSlot)
1244             {
1245                 configOthers = true;
1246                 break;
1247             }
1248             else
1249             {
1250                 FacesConfigNameSlot nameSlot = (FacesConfigNameSlot) slot;
1251                 names.add(nameSlot.getName());
1252             }
1253         }
1254         
1255         if (configOthers)
1256         {
1257             //<after>....<others/></after> case
1258             //other reference where already considered when
1259             //pre ordered list was calculated, so just add to the end.
1260             sortedList.add(resource);
1261         }
1262         else
1263         {
1264             //Scan the nearest reference and add it after
1265             boolean founded = false;
1266             for (int i = sortedList.size()-1 ; i >=0 ; i--)
1267             {
1268                 if (names.contains(sortedList.get(i).getName()))
1269                 {
1270                     if (i+1 < sortedList.size())
1271                     {
1272                         sortedList.add(i+1,resource);
1273                     }
1274                     else
1275                     {
1276                         sortedList.add(resource);
1277                     }
1278                     founded = true;
1279                     break;
1280                 }
1281             }
1282             if (!founded)
1283             {
1284                 //just add it to the end
1285                 sortedList.add(resource);
1286             }
1287         }        
1288     }*/
1289     
1290     
1291     /**
1292      * Pre Sort the appConfigResources, detecting cyclic references, so when sort process
1293      * start, it is just necessary to traverse the preOrderedList once. To do that, we just
1294      * scan "before" and "after" lists for references, and then those references are traversed
1295      * again, so the first elements of the pre ordered list does not have references and
1296      * the next elements has references to the already added ones.
1297      * 
1298      * The elements on the preOrderedList looks like this:
1299      * 
1300      * [ no ordering elements , referenced elements ... more referenced elements, 
1301      *  before others / after others non referenced elements]
1302      * 
1303      * @param appConfigResources
1304      * @return
1305      */
1306     /*
1307     private List<FacesConfig> getPostOrderedList(final List<FacesConfig> appConfigResources) throws FacesException
1308     {
1309         
1310         List<FacesConfig> appFilteredConfigResources = new ArrayList<FacesConfig>(); 
1311         
1312         //0. Clean up: remove all not found resource references from the ordering 
1313         //descriptions.
1314         List<String> availableReferences = new ArrayList<String>();
1315         for (FacesConfig resource : appFilteredConfigResources)
1316         {
1317             String name = resource.getName();
1318             if (name != null && "".equals(name))
1319             {
1320                 availableReferences.add(name);
1321             }
1322         }
1323         
1324         for (FacesConfig resource : appFilteredConfigResources)
1325         {
1326             for (Iterator<OrderSlot> it =  resource.getOrdering().getBeforeList().iterator();it.hasNext();)
1327             {
1328                 OrderSlot slot = it.next();
1329                 if (slot instanceof FacesConfigNameSlot)
1330                 {
1331                     String name = ((FacesConfigNameSlot) slot).getName();
1332                     if (!availableReferences.contains(name))
1333                     {
1334                         it.remove();
1335                     }
1336                 }
1337             }
1338             for (Iterator<OrderSlot> it =  resource.getOrdering().getAfterList().iterator();it.hasNext();)
1339             {
1340                 OrderSlot slot = it.next();
1341                 if (slot instanceof FacesConfigNameSlot)
1342                 {
1343                     String name = ((FacesConfigNameSlot) slot).getName();
1344                     if (!availableReferences.contains(name))
1345                     {
1346                         it.remove();
1347                     }
1348                 }
1349             }
1350         }
1351         
1352         //1. Pre filtering: Sort nodes according to its weight. The weight is the number of named
1353         //nodes containing in both before and after lists. The sort is done from the more complex
1354         //to the most simple
1355         if (appConfigResources instanceof ArrayList)
1356         {
1357             appFilteredConfigResources = (List<FacesConfig>)
1358                 ((ArrayList<FacesConfig>)appConfigResources).clone();
1359         }
1360         else
1361         {
1362             appFilteredConfigResources = new ArrayList<FacesConfig>();
1363             appFilteredConfigResources.addAll(appConfigResources);
1364         }
1365         Collections.sort(appFilteredConfigResources,
1366                 new Comparator<FacesConfig>()
1367                 {
1368                     public int compare(FacesConfig o1, FacesConfig o2)
1369                     {
1370                         int o1Weight = 0;
1371                         int o2Weight = 0;
1372                         if (o1.getOrdering() != null)
1373                         {
1374                             for (OrderSlot slot : o1.getOrdering()
1375                                     .getBeforeList())
1376                             {
1377                                 if (slot instanceof FacesConfigNameSlot)
1378                                 {
1379                                     o1Weight++;
1380                                 }
1381                             }
1382                             for (OrderSlot slot : o1.getOrdering()
1383                                     .getAfterList())
1384                             {
1385                                 if (slot instanceof FacesConfigNameSlot)
1386                                 {
1387                                     o1Weight++;
1388                                 }
1389                             }
1390                         }
1391                         if (o2.getOrdering() != null)
1392                         {
1393                             for (OrderSlot slot : o2.getOrdering()
1394                                     .getBeforeList())
1395                             {
1396                                 if (slot instanceof FacesConfigNameSlot)
1397                                 {
1398                                     o2Weight++;
1399                                 }
1400                             }
1401                             for (OrderSlot slot : o2.getOrdering()
1402                                     .getAfterList())
1403                             {
1404                                 if (slot instanceof FacesConfigNameSlot)
1405                                 {
1406                                     o2Weight++;
1407                                 }
1408                             }
1409                         }
1410                         return o2Weight - o1Weight;
1411                     }
1412                 });
1413         
1414         List<FacesConfig> postOrderedList = new LinkedList<FacesConfig>();
1415         List<FacesConfig> othersList = new ArrayList<FacesConfig>();
1416         
1417         List<String> nameBeforeStack = new ArrayList<String>();
1418         List<String> nameAfterStack = new ArrayList<String>();
1419         
1420         boolean[] visitedSlots = new boolean[appFilteredConfigResources.size()];
1421         
1422         //2. Scan and resolve conflicts
1423         for (int i = 0; i < appFilteredConfigResources.size(); i++)
1424         {
1425             if (!visitedSlots[i])
1426             {
1427                 resolveConflicts(appFilteredConfigResources, i, visitedSlots, 
1428                         nameBeforeStack, nameAfterStack, postOrderedList, othersList, false);
1429             }
1430         }
1431         
1432         //Add othersList to postOrderedList so <before><others/></before> and <after><others/></after>
1433         //ordering conditions are handled at last if there are not referenced by anyone
1434         postOrderedList.addAll(othersList);
1435         
1436         return postOrderedList;
1437     }
1438         
1439     private void resolveConflicts(final List<FacesConfig> appConfigResources, int index, boolean[] visitedSlots,
1440             List<String> nameBeforeStack, List<String> nameAfterStack, List<FacesConfig> postOrderedList,
1441             List<FacesConfig> othersList, boolean indexReferenced) throws FacesException
1442     {
1443         FacesConfig facesConfig = appConfigResources.get(index);
1444         
1445         if (nameBeforeStack.contains(facesConfig.getName()))
1446         {
1447             //Already referenced, just return. Later if there exists a
1448             //circular reference, it will be detected and solved.
1449             return;
1450             //log.fatal("Circular references detected when ordering " +
1451             //        "application faces config resources:"+nameBeforeStack.toString() +
1452             //        " already visited and trying to resolve "+facesConfig.getName());
1453             //throw new FacesException("Circular references detected when ordering " +
1454             //        "application faces config resources:"+nameBeforeStack.toString() +
1455             //        " already visited and trying to resolve "+facesConfig.getName());
1456         }
1457         
1458         if (nameAfterStack.contains(facesConfig.getName()))
1459         {
1460             //Already referenced, just return. Later if there exists a
1461             //circular reference, it will be detected and solved.
1462             return;
1463             //log.fatal("Circular references detected when ordering " +
1464             //        "application faces config resources:"+nameAfterStack.toString() +
1465             //        " already visited and trying to resolve "+facesConfig.getName());
1466             //throw new FacesException("Circular references detected when ordering " +
1467             //        "application faces config resources:"+nameAfterStack.toString() +
1468             //        " already visited and trying to resolve "+facesConfig.getName());
1469         }
1470         
1471         if (facesConfig.getOrdering() != null)
1472         {
1473             boolean pointingResource = false;
1474             
1475             //Deal with before restrictions first
1476             for (OrderSlot slot : facesConfig.getOrdering().getBeforeList())
1477             {
1478                 if (slot instanceof FacesConfigNameSlot)
1479                 {
1480                     FacesConfigNameSlot nameSlot = (FacesConfigNameSlot) slot;
1481                     //The resource pointed is not added yet?
1482                     boolean alreadyAdded = false;
1483                     for (FacesConfig res : postOrderedList)
1484                     {
1485                         if (nameSlot.getName().equals(res.getName()))
1486                         {
1487                             alreadyAdded = true;
1488                             break;
1489                         }
1490                     }
1491                     if (!alreadyAdded)
1492                     {
1493                         int indexSlot = -1;
1494                         //Find it
1495                         for (int i = 0; i < appConfigResources.size(); i++)
1496                         {
1497                             FacesConfig resource = appConfigResources.get(i);
1498                             if (resource.getName() != null && nameSlot.getName().equals(resource.getName()))
1499                             {
1500                                 indexSlot = i;
1501                                 break;
1502                             }
1503                         }
1504                         
1505                         //Resource founded on appConfigResources
1506                         if (indexSlot != -1)
1507                         {
1508                             pointingResource = true;
1509                             //Add to nameStac
1510                             nameBeforeStack.add(facesConfig.getName());
1511                             
1512                             resolveConflicts(appConfigResources, indexSlot, visitedSlots, 
1513                                     nameBeforeStack, nameAfterStack, postOrderedList,
1514                                     othersList,true);
1515                             
1516                             nameBeforeStack.remove(facesConfig.getName());
1517                         }
1518                     }
1519                     else
1520                     {
1521                         pointingResource = true;
1522                     }
1523                 }
1524             }
1525             
1526             for (OrderSlot slot : facesConfig.getOrdering().getAfterList())
1527             {
1528                 if (slot instanceof FacesConfigNameSlot)
1529                 {
1530                     FacesConfigNameSlot nameSlot = (FacesConfigNameSlot) slot;
1531                     //The resource pointed is not added yet?
1532                     boolean alreadyAdded = false;
1533                     for (FacesConfig res : postOrderedList)
1534                     {
1535                         if (nameSlot.getName().equals(res.getName()))
1536                         {
1537                             alreadyAdded = true;
1538                             break;
1539                         }
1540                     }
1541                     if (!alreadyAdded)
1542                     {
1543                         int indexSlot = -1;
1544                         //Find it
1545                         for (int i = 0; i < appConfigResources.size(); i++)
1546                         {
1547                             FacesConfig resource = appConfigResources.get(i);
1548                             if (resource.getName() != null && nameSlot.getName().equals(resource.getName()))
1549                             {
1550                                 indexSlot = i;
1551                                 break;
1552                             }
1553                         }
1554                         
1555                         //Resource founded on appConfigResources
1556                         if (indexSlot != -1)
1557                         {
1558                             pointingResource = true;
1559                             //Add to nameStac
1560                             nameAfterStack.add(facesConfig.getName());
1561                             
1562                             resolveConflicts(appConfigResources, indexSlot, visitedSlots, 
1563                                     nameBeforeStack, nameAfterStack, postOrderedList,
1564                                     othersList,true);
1565                             
1566                             nameAfterStack.remove(facesConfig.getName());
1567                         }
1568                     }
1569                     else
1570                     {
1571                         pointingResource = true;
1572                     }
1573                 }
1574             }
1575             
1576             if (facesConfig.getOrdering().getBeforeList().isEmpty() &&
1577                 facesConfig.getOrdering().getAfterList().isEmpty())
1578             {
1579                 //Fits in the category "others", put at beginning
1580                 postOrderedList.add(0,appConfigResources.get(index));
1581             }
1582             else if (pointingResource || indexReferenced)
1583             {
1584                 //If the node points to other or is referenced from other,
1585                 //add to the postOrderedList at the end
1586                 postOrderedList.add(appConfigResources.get(index));                    
1587             }
1588             else
1589             {
1590                 //Add to othersList
1591                 othersList.add(appConfigResources.get(index));
1592             }
1593         }
1594         else
1595         {
1596             //Add at start of the list, since does not have any ordering
1597             //instructions and on the next step makes than "before others" and "after others"
1598             //works correctly
1599             postOrderedList.add(0,appConfigResources.get(index));
1600         }
1601         //Set the node as visited
1602         visitedSlots[index] = true;
1603     }*/
1604     
1605 }