View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.config.impl.digester;
20  
21  import org.apache.commons.digester.Digester;
22  import org.apache.myfaces.config.FacesConfigUnmarshaller;
23  import org.apache.myfaces.config.impl.FacesConfigEntityResolver;
24  import org.apache.myfaces.config.impl.digester.elements.*;
25  import org.apache.myfaces.shared.util.ClassUtils;
26  import org.xml.sax.InputSource;
27  import org.xml.sax.SAXException;
28  
29  import javax.faces.context.ExternalContext;
30  import java.io.IOException;
31  import java.io.InputStream;
32  import java.io.Reader;
33  import org.apache.myfaces.config.element.FacesFlowDefinition;
34  
35  /**
36   * @author <a href="mailto:oliver@rossmueller.com">Oliver Rossmueller</a>
37   */
38  public class DigesterFacesConfigUnmarshallerImpl implements FacesConfigUnmarshaller<FacesConfigImpl>
39  {
40      private Digester digester;
41  
42      public DigesterFacesConfigUnmarshallerImpl(ExternalContext externalContext)
43      {
44          digester = new Digester();
45          // TODO: validation set to false during implementation of 1.2
46          digester.setValidating(false);
47          digester.setNamespaceAware(true);
48          digester.setEntityResolver(new FacesConfigEntityResolver(externalContext));
49          //digester.setUseContextClassLoader(true);
50          digester.setClassLoader(ClassUtils.getContextClassLoader());
51  
52          digester.addObjectCreate("faces-config", FacesConfigImpl.class);
53          // 2.0 specific start
54          digester.addSetProperties("faces-config", "metadata-complete", "metadataComplete");
55          digester.addSetProperties("faces-config", "version", "version");
56          // 2.0 specific end
57          // 2.0 config ordering name start
58          
59          digester.addCallMethod("faces-config/protected-views/url-pattern", "addProtectedViewUrlPattern", 0);
60          
61          digester.addCallMethod("faces-config/name", "setName", 0);
62          digester.addObjectCreate("faces-config/ordering", OrderingImpl.class);
63          digester.addSetNext("faces-config/ordering", "setOrdering");
64          digester.addObjectCreate("faces-config/ordering/before/name", FacesConfigNameSlotImpl.class);
65          digester.addSetNext("faces-config/ordering/before/name", "addBeforeSlot");
66          digester.addCallMethod("faces-config/ordering/before/name", "setName",0);        
67          digester.addObjectCreate("faces-config/ordering/before/others", ConfigOthersSlotImpl.class);
68          digester.addSetNext("faces-config/ordering/before/others", "addBeforeSlot");
69          
70          digester.addObjectCreate("faces-config/ordering/after/name", FacesConfigNameSlotImpl.class);
71          digester.addSetNext("faces-config/ordering/after/name", "addAfterSlot");
72          digester.addCallMethod("faces-config/ordering/after/name", "setName",0);        
73          digester.addObjectCreate("faces-config/ordering/after/others", ConfigOthersSlotImpl.class);
74          digester.addSetNext("faces-config/ordering/after/others", "addAfterSlot");        
75          
76          digester.addObjectCreate("faces-config/absolute-ordering", AbsoluteOrderingImpl.class);
77          digester.addSetNext("faces-config/absolute-ordering", "setAbsoluteOrdering");
78          digester.addObjectCreate("faces-config/absolute-ordering/name", FacesConfigNameSlotImpl.class);
79          digester.addSetNext("faces-config/absolute-ordering/name", "addOrderSlot");
80          digester.addCallMethod("faces-config/absolute-ordering/name", "setName",0);        
81          digester.addObjectCreate("faces-config/absolute-ordering/others", ConfigOthersSlotImpl.class);
82          digester.addSetNext("faces-config/absolute-ordering/others", "addOrderSlot");
83          // 2.0 config ordering name end
84          
85          digester.addObjectCreate("faces-config/application", ApplicationImpl.class);
86          digester.addSetNext("faces-config/application", "addApplication");
87          digester.addCallMethod("faces-config/application/action-listener", "addActionListener", 0);
88          digester.addCallMethod("faces-config/application/default-render-kit-id", "addDefaultRenderkitId", 0);
89          digester.addCallMethod("faces-config/application/default-validators", "setDefaultValidatorsPresent");
90          digester.addCallMethod("faces-config/application/default-validators/validator-id", "addDefaultValidatorId", 0);
91          digester.addCallMethod("faces-config/application/message-bundle", "addMessageBundle", 0);
92          digester.addCallMethod("faces-config/application/navigation-handler", "addNavigationHandler", 0);
93          digester.addCallMethod("faces-config/application/partial-traversal", "addPartialTraversal", 0);
94          digester.addCallMethod("faces-config/application/view-handler", "addViewHandler", 0);
95          digester.addCallMethod("faces-config/application/state-manager", "addStateManager", 0);
96          digester.addCallMethod("faces-config/application/property-resolver", "addPropertyResolver", 0);
97          digester.addCallMethod("faces-config/application/variable-resolver", "addVariableResolver", 0);
98          digester.addObjectCreate("faces-config/application/locale-config", LocaleConfigImpl.class);
99          digester.addSetNext("faces-config/application/locale-config", "addLocaleConfig");
100         digester.addCallMethod("faces-config/application/locale-config/default-locale", "setDefaultLocale", 0);
101         digester.addCallMethod("faces-config/application/locale-config/supported-locale", "addSupportedLocale", 0);
102 
103         // 1.2 specific start
104         digester.addCallMethod("faces-config/application/el-resolver", "addElResolver", 0);
105         digester.addObjectCreate("faces-config/application/resource-bundle", ResourceBundleImpl.class);
106         digester.addSetNext("faces-config/application/resource-bundle", "addResourceBundle");
107         digester.addCallMethod("faces-config/application/resource-bundle/base-name", "setBaseName", 0);
108         digester.addCallMethod("faces-config/application/resource-bundle/var", "setVar", 0);
109         digester.addCallMethod("faces-config/application/resource-bundle/display-name", "setDisplayName", 0);
110         // 1.2 specific end
111 
112         // 2.0 specific start
113         digester.addObjectCreate("faces-config/application/system-event-listener", SystemEventListenerImpl.class);
114         digester.addSetNext("faces-config/application/system-event-listener", "addSystemEventListener");
115         digester.addCallMethod("faces-config/application/system-event-listener/system-event-listener-class",
116                                "setSystemEventListenerClass",0);
117         digester.addCallMethod("faces-config/application/system-event-listener/system-event-class",
118                                "setSystemEventClass",0);
119         digester.addCallMethod("faces-config/application/system-event-listener/source-class", "setSourceClass",0);
120         digester.addCallMethod("faces-config/application/resource-handler", "addResourceHandler", 0);
121         digester.addCallMethod("faces-config/factory/exception-handler-factory", "addExceptionHandlerFactory", 0);
122         digester.addCallMethod("faces-config/factory/external-context-factory", "addExternalContextFactory", 0);
123         digester.addCallMethod("faces-config/factory/view-declaration-language-factory",
124                                "addViewDeclarationLanguageFactory", 0);
125         digester.addCallMethod("faces-config/factory/partial-view-context-factory", "addPartialViewContextFactory", 0);
126         digester.addCallMethod("faces-config/factory/tag-handler-delegate-factory", "addTagHandlerDelegateFactory", 0);
127         digester.addCallMethod("faces-config/factory/visit-context-factory", "addVisitContextFactory", 0);
128         // 2.0 specific end
129         // 2.3 specific start
130         digester.addCallMethod("faces-config/factory/search-expression-context-factory", 
131                 "addSearchExpressionContextFactory", 0);
132         digester.addCallMethod("faces-config/application/search-expression-handler", "addSearchExpressionHandler", 0);
133         digester.addCallMethod("faces-config/application/search-keyword-resolver", "addSearchKeywordResolver", 0);
134         // 2.3 specific end
135         digester.addObjectCreate("faces-config/application/resource-library-contracts/contract-mapping", 
136             ContractMappingImpl.class);
137         digester.addSetNext("faces-config/application/resource-library-contracts/contract-mapping", 
138             "addResourceLibraryContractMapping");
139         digester.addCallMethod(
140             "faces-config/application/resource-library-contracts/contract-mapping/url-pattern", "addUrlPattern", 0);
141         digester.addCallMethod(
142             "faces-config/application/resource-library-contracts/contract-mapping/contracts", "addContract", 0);
143         
144         // 2.1 specific start
145         digester.addCallMethod("faces-config/factory/facelet-cache-factory", "addFaceletCacheFactory", 0);
146         // 2.1 specific end
147         // 2.2 specific start
148         digester.addCallMethod("faces-config/factory/flash-factory", "addFlashFactory", 0);
149         // Note there is no client-window-factory, this factory can be set only using SPI.
150         digester.addCallMethod("faces-config/factory/flow-handler-factory", "addFlowHandlerFactory", 0);
151         // 2.2 specific end
152         digester.addCallMethod("faces-config/factory/client-window-factory", "addClientWindowFactory", 0);
153 
154         digester.addObjectCreate("faces-config/factory", FactoryImpl.class);
155         digester.addSetNext("faces-config/factory", "addFactory");
156         digester.addCallMethod("faces-config/factory/application-factory", "addApplicationFactory", 0);
157         digester.addCallMethod("faces-config/factory/faces-context-factory", "addFacesContextFactory", 0);
158         digester.addCallMethod("faces-config/factory/lifecycle-factory", "addLifecycleFactory", 0);
159         digester.addCallMethod("faces-config/factory/render-kit-factory", "addRenderkitFactory", 0);
160 
161         digester.addCallMethod("faces-config/component", "addComponent", 2);
162         digester.addCallParam("faces-config/component/component-type", 0);
163         digester.addCallParam("faces-config/component/component-class", 1);
164 
165         digester.addObjectCreate("faces-config/converter", ConverterImpl.class);
166         digester.addSetNext("faces-config/converter", "addConverter");
167         digester.addCallMethod("faces-config/converter/converter-id", "setConverterId", 0);
168         digester.addCallMethod("faces-config/converter/converter-for-class", "setForClass", 0);
169         digester.addCallMethod("faces-config/converter/converter-class", "setConverterClass", 0);
170         digester.addObjectCreate("faces-config/converter/attribute", AttributeImpl.class);
171         digester.addSetNext("faces-config/converter/attribute", "addAttribute");
172         digester.addCallMethod("faces-config/converter/attribute/description", "addDescription", 0);
173         digester.addCallMethod("faces-config/converter/attribute/display-name", "addDisplayName", 0);
174         digester.addCallMethod("faces-config/converter/attribute/icon", "addIcon", 0);
175         digester.addCallMethod("faces-config/converter/attribute/attribute-name", "setAttributeName", 0);
176         digester.addCallMethod("faces-config/converter/attribute/attribute-class", "setAttributeClass", 0);
177         digester.addCallMethod("faces-config/converter/attribute/default-value", "setDefaultValue", 0);
178         digester.addCallMethod("faces-config/converter/attribute/suggested-value", "setSuggestedValue", 0);
179         digester.addCallMethod("faces-config/converter/attribute/attribute-extension", "addAttributeExtension", 0);
180         digester.addObjectCreate("faces-config/converter/property", PropertyImpl.class);
181         digester.addSetNext("faces-config/converter/property", "addProperty");
182         digester.addCallMethod("faces-config/converter/property/description", "addDescription", 0);
183         digester.addCallMethod("faces-config/converter/property/display-name", "addDisplayName", 0);
184         digester.addCallMethod("faces-config/converter/property/icon", "addIcon", 0);
185         digester.addCallMethod("faces-config/converter/property/property-name", "setPropertyName", 0);
186         digester.addCallMethod("faces-config/converter/property/property-class", "setPropertyClass", 0);
187         digester.addCallMethod("faces-config/converter/property/default-value", "setDefaultValue", 0);
188         digester.addCallMethod("faces-config/converter/property/suggested-value", "setSuggestedValue", 0);
189         digester.addCallMethod("faces-config/converter/property/property-extension", "addPropertyExtension", 0);
190 
191         digester.addObjectCreate("faces-config/managed-bean", ManagedBeanImpl.class);
192         digester.addSetProperties("faces-config/managed-bean", "eager", "eager");
193         digester.addSetNext("faces-config/managed-bean", "addManagedBean");
194         digester.addCallMethod("faces-config/managed-bean/description", "setDescription", 0);
195         digester.addCallMethod("faces-config/managed-bean/managed-bean-name", "setName", 0);
196         digester.addCallMethod("faces-config/managed-bean/managed-bean-class", "setBeanClass", 0);
197         digester.addCallMethod("faces-config/managed-bean/managed-bean-scope", "setScope", 0);
198         digester.addObjectCreate("faces-config/managed-bean/managed-property", ManagedPropertyImpl.class);
199         digester.addSetNext("faces-config/managed-bean/managed-property", "addProperty");
200         digester.addCallMethod("faces-config/managed-bean/managed-property/property-name", "setPropertyName", 0);
201         digester.addCallMethod("faces-config/managed-bean/managed-property/property-class", "setPropertyClass", 0);
202         digester.addCallMethod("faces-config/managed-bean/managed-property/null-value", "setNullValue");
203         digester.addCallMethod("faces-config/managed-bean/managed-property/value", "setValue", 0);
204         digester.addObjectCreate("faces-config/managed-bean/managed-property/map-entries", MapEntriesImpl.class);
205         digester.addSetNext("faces-config/managed-bean/managed-property/map-entries", "setMapEntries");
206         digester.addCallMethod("faces-config/managed-bean/managed-property/map-entries/key-class", "setKeyClass", 0);
207         digester.addCallMethod("faces-config/managed-bean/managed-property/map-entries/value-class",
208                                "setValueClass", 0);
209         digester.addObjectCreate("faces-config/managed-bean/managed-property/map-entries/map-entry",
210                                  MapEntriesImpl.Entry.class);
211         digester.addSetNext("faces-config/managed-bean/managed-property/map-entries/map-entry", "addEntry");
212         digester.addCallMethod("faces-config/managed-bean/managed-property/map-entries/map-entry/key", "setKey", 0);
213         digester.addCallMethod("faces-config/managed-bean/managed-property/map-entries/map-entry/null-value",
214                                "setNullValue");
215         digester.addCallMethod("faces-config/managed-bean/managed-property/map-entries/map-entry/value", "setValue", 0);
216         digester.addObjectCreate("faces-config/managed-bean/managed-property/list-entries", ListEntriesImpl.class);
217         digester.addSetNext("faces-config/managed-bean/managed-property/list-entries", "setListEntries");
218         digester.addCallMethod("faces-config/managed-bean/managed-property/list-entries/value-class", "setValueClass",
219                                0);
220         digester.addObjectCreate("faces-config/managed-bean/managed-property/list-entries/null-value",
221                                  ListEntriesImpl.Entry.class);
222         digester.addSetNext("faces-config/managed-bean/managed-property/list-entries/null-value", "addEntry");
223         digester.addCallMethod("faces-config/managed-bean/managed-property/list-entries/null-value", "setNullValue");
224         digester.addObjectCreate("faces-config/managed-bean/managed-property/list-entries/value",
225                                  ListEntriesImpl.Entry.class);
226         digester.addSetNext("faces-config/managed-bean/managed-property/list-entries/value", "addEntry");
227         digester.addCallMethod("faces-config/managed-bean/managed-property/list-entries/value", "setValue", 0);
228         digester.addObjectCreate("faces-config/managed-bean/map-entries", MapEntriesImpl.class);
229         digester.addSetNext("faces-config/managed-bean/map-entries", "setMapEntries");
230         digester.addCallMethod("faces-config/managed-bean/map-entries/key-class", "setKeyClass", 0);
231         digester.addCallMethod("faces-config/managed-bean/map-entries/value-class", "setValueClass", 0);
232         digester.addObjectCreate("faces-config/managed-bean/map-entries/map-entry", MapEntriesImpl.Entry.class);
233         digester.addSetNext("faces-config/managed-bean/map-entries/map-entry", "addEntry");
234         digester.addCallMethod("faces-config/managed-bean/map-entries/map-entry/key", "setKey", 0);
235         digester.addCallMethod("faces-config/managed-bean/map-entries/map-entry/null-value", "setNullValue");
236         digester.addCallMethod("faces-config/managed-bean/map-entries/map-entry/value", "setValue", 0);
237         digester.addObjectCreate("faces-config/managed-bean/list-entries", ListEntriesImpl.class);
238         digester.addSetNext("faces-config/managed-bean/list-entries", "setListEntries");
239         digester.addCallMethod("faces-config/managed-bean/list-entries/value-class", "setValueClass", 0);
240         digester.addObjectCreate("faces-config/managed-bean/list-entries/null-value", ListEntriesImpl.Entry.class);
241         digester.addSetNext("faces-config/managed-bean/list-entries/null-value", "addEntry");
242         digester.addCallMethod("faces-config/managed-bean/list-entries/null-value", "setNullValue");
243         digester.addObjectCreate("faces-config/managed-bean/list-entries/value", ListEntriesImpl.Entry.class);
244         digester.addSetNext("faces-config/managed-bean/list-entries/value", "addEntry");
245         digester.addCallMethod("faces-config/managed-bean/list-entries/value", "setValue", 0);
246 
247         digester.addObjectCreate("faces-config/navigation-rule", NavigationRuleImpl.class);
248         digester.addSetNext("faces-config/navigation-rule", "addNavigationRule");
249         digester.addCallMethod("faces-config/navigation-rule/from-view-id", "setFromViewId", 0);
250         digester.addObjectCreate("faces-config/navigation-rule/navigation-case", NavigationCaseImpl.class);
251         digester.addSetNext("faces-config/navigation-rule/navigation-case", "addNavigationCase");
252         digester.addCallMethod("faces-config/navigation-rule/navigation-case/from-action", "setFromAction", 0);
253         digester.addCallMethod("faces-config/navigation-rule/navigation-case/from-outcome", "setFromOutcome", 0);
254         digester.addCallMethod("faces-config/navigation-rule/navigation-case/if", "setIf", 0);
255         digester.addCallMethod("faces-config/navigation-rule/navigation-case/to-view-id", "setToViewId", 0);
256         digester.addObjectCreate("faces-config/navigation-rule/navigation-case/redirect", RedirectImpl.class);
257         digester.addSetProperties("faces-config/navigation-rule/navigation-case/redirect", "include-view-params",
258                                   "includeViewParams");
259         digester.addSetNext("faces-config/navigation-rule/navigation-case/redirect", "setRedirect");
260         digester.addObjectCreate("faces-config/navigation-rule/navigation-case/redirect/view-param", 
261             ViewParamImpl.class);
262         digester.addSetNext("faces-config/navigation-rule/navigation-case/redirect/view-param", "addViewParam");
263         digester.addCallMethod("faces-config/navigation-rule/navigation-case/redirect/view-param/name", "setName",0);
264         digester.addCallMethod("faces-config/navigation-rule/navigation-case/redirect/view-param/value", "setValue",0);
265 
266         digester.addObjectCreate("faces-config/navigation-rule/navigation-case/redirect/redirect-param", 
267             ViewParamImpl.class);
268         digester.addSetNext("faces-config/navigation-rule/navigation-case/redirect/redirect-param", 
269             "addViewParam");
270         digester.addCallMethod("faces-config/navigation-rule/navigation-case/redirect/redirect-param/name", 
271             "setName",0);
272         digester.addCallMethod("faces-config/navigation-rule/navigation-case/redirect/redirect-param/value", 
273             "setValue",0);
274 
275         digester.addObjectCreate("faces-config/render-kit", RenderKitImpl.class);
276         digester.addSetNext("faces-config/render-kit", "addRenderKit");
277         digester.addCallMethod("faces-config/render-kit/render-kit-id", "setId", 0);
278         //digester.addCallMethod("faces-config/render-kit/render-kit-class", "setRenderKitClass", 0);
279         digester.addCallMethod("faces-config/render-kit/render-kit-class", "addRenderKitClass", 0);
280         digester.addObjectCreate("faces-config/render-kit/renderer", RendererImpl.class);
281         digester.addSetNext("faces-config/render-kit/renderer", "addRenderer");
282         digester.addCallMethod("faces-config/render-kit/renderer/component-family", "setComponentFamily", 0);
283         digester.addCallMethod("faces-config/render-kit/renderer/renderer-type", "setRendererType", 0);
284         digester.addCallMethod("faces-config/render-kit/renderer/renderer-class", "setRendererClass", 0);
285         digester.addObjectCreate("faces-config/render-kit/client-behavior-renderer", ClientBehaviorRendererImpl.class);
286         digester.addSetNext("faces-config/render-kit/client-behavior-renderer", "addClientBehaviorRenderer");
287         digester.addCallMethod("faces-config/render-kit/client-behavior-renderer/client-behavior-renderer-type",
288                                "setRendererType", 0);
289         digester.addCallMethod("faces-config/render-kit/client-behavior-renderer/client-behavior-renderer-class",
290                                "setRendererClass", 0);
291         
292         // 2.0 behavior start
293         digester.addObjectCreate("faces-config/behavior", BehaviorImpl.class);
294         digester.addSetNext("faces-config/behavior", "addBehavior");
295         digester.addCallMethod("faces-config/behavior/behavior-id", "setBehaviorId", 0);
296         digester.addCallMethod("faces-config/behavior/behavior-class", "setBehaviorClass", 0);
297         digester.addObjectCreate("faces-config/behavior/attribute", AttributeImpl.class);
298         digester.addSetNext("faces-config/behavior/attribute", "addAttribute");
299         digester.addCallMethod("faces-config/behavior/attribute/description", "addDescription", 0);
300         digester.addCallMethod("faces-config/behavior/attribute/display-name", "addDisplayName", 0);
301         digester.addCallMethod("faces-config/behavior/attribute/icon", "addIcon", 0);
302         digester.addCallMethod("faces-config/behavior/attribute/attribute-name", "setAttributeName", 0);
303         digester.addCallMethod("faces-config/behavior/attribute/attribute-class", "setAttributeClass", 0);
304         digester.addCallMethod("faces-config/behavior/attribute/default-value", "setDefaultValue", 0);
305         digester.addCallMethod("faces-config/behavior/attribute/suggested-value", "setSuggestedValue", 0);
306         digester.addCallMethod("faces-config/behavior/attribute/attribute-extension", "addAttributeExtension", 0);
307         digester.addObjectCreate("faces-config/behavior/property", PropertyImpl.class);
308         digester.addSetNext("faces-config/behavior/property", "addProperty");
309         digester.addCallMethod("faces-config/behavior/property/description", "addDescription", 0);
310         digester.addCallMethod("faces-config/behavior/property/display-name", "addDisplayName", 0);
311         digester.addCallMethod("faces-config/behavior/property/icon", "addIcon", 0);
312         digester.addCallMethod("faces-config/behavior/property/property-name", "setPropertyName", 0);
313         digester.addCallMethod("faces-config/behavior/property/property-class", "setPropertyClass", 0);
314         digester.addCallMethod("faces-config/behavior/property/default-value", "setDefaultValue", 0);
315         digester.addCallMethod("faces-config/behavior/property/suggested-value", "setSuggestedValue", 0);
316         digester.addCallMethod("faces-config/behavior/property/property-extension", "addPropertyExtension", 0);
317         // 2.0 behavior end
318         
319         digester.addCallMethod("faces-config/lifecycle/phase-listener", "addLifecyclePhaseListener", 0);
320 
321         digester.addCallMethod("faces-config/validator", "addValidator", 2);
322         digester.addCallParam("faces-config/validator/validator-id", 0);
323         digester.addCallParam("faces-config/validator/validator-class", 1);
324         
325         // 2.1 facelets-processing start
326         digester.addObjectCreate("faces-config/faces-config-extension", FacesConfigExtensionImpl.class);
327         digester.addSetNext("faces-config/faces-config-extension", "addFacesConfigExtension");
328         digester.addObjectCreate("faces-config/faces-config-extension/facelets-processing", 
329             FaceletsProcessingImpl.class);
330         digester.addSetNext("faces-config/faces-config-extension/facelets-processing", "addFaceletsProcessing");
331         digester.addCallMethod("faces-config/faces-config-extension/facelets-processing/file-extension",
332                                "setFileExtension", 0);
333         digester.addCallMethod("faces-config/faces-config-extension/facelets-processing/process-as", "setProcessAs", 0);
334         // 2.1 facelets-processing end
335 
336         //MyFaces specific facelets-processing instruction.
337         digester.addCallMethod("faces-config/faces-config-extension/facelets-processing/oam-compress-spaces", 
338                 "setOamCompressSpaces", 0);
339         addFacesFlowRules(externalContext);
340     }
341     
342     private void addNavigationRules(ExternalContext externalContext, String prefix, String method)
343     {
344         digester.addObjectCreate(prefix, NavigationRuleImpl.class);
345         digester.addSetNext(prefix, method);
346         digester.addCallMethod(prefix+"/from-view-id", "setFromViewId", 0);
347         addNavigationCases(externalContext, prefix+"/navigation-case", "addNavigationCase");
348     }
349     
350     private void addNavigationCases(ExternalContext externalContext, String prefix, String method)
351     {
352         digester.addObjectCreate(prefix, NavigationCaseImpl.class);
353         digester.addSetNext(prefix, method);
354         digester.addCallMethod(prefix+"/from-action", "setFromAction", 0);
355         digester.addCallMethod(prefix+"/from-outcome", "setFromOutcome", 0);
356         digester.addCallMethod(prefix+"/if", "setIf", 0);
357         digester.addCallMethod(prefix+"/to-view-id", "setToViewId", 0);
358         digester.addObjectCreate(prefix+"/redirect", RedirectImpl.class);
359         digester.addSetProperties(prefix+"/redirect", "include-view-params",
360                                   "includeViewParams");
361         digester.addSetNext(prefix+"/redirect", "setRedirect");
362         digester.addObjectCreate(prefix+"/redirect/view-param", ViewParamImpl.class);
363         digester.addSetNext(prefix+"/redirect/view-param", "addViewParam");
364         digester.addCallMethod(prefix+"/redirect/view-param/name", "setName",0);
365         digester.addCallMethod(prefix+"/redirect/view-param/value", "setValue",0);
366 
367         digester.addObjectCreate(prefix+"/redirect/redirect-param", ViewParamImpl.class);
368         digester.addSetNext(prefix+"/redirect/redirect-param", "addViewParam");
369         digester.addCallMethod(prefix+"/redirect/redirect-param/name", "setName",0);
370         digester.addCallMethod(prefix+"/redirect/redirect-param/value", "setValue",0);
371     }
372     
373     private void addFacesFlowRules(ExternalContext externalContext)
374     {
375         digester.addObjectCreate("faces-config/flow-definition", FacesFlowDefinitionImpl.class);
376         
377         digester.addSetNext("faces-config/flow-definition", "addFacesFlowDefinition");
378         digester.addSetProperties("faces-config/flow-definition", "id", "id");
379         
380         digester.addCallMethod("faces-config/flow-definition/start-node", "setStartNode", 0);
381         digester.addCallMethod("faces-config/flow-definition/initializer", "setInitializer", 0);
382         digester.addCallMethod("faces-config/flow-definition/finalizer", "setFinalizer", 0);
383         
384         digester.addObjectCreate("faces-config/flow-definition/view", FacesFlowViewImpl.class);
385         digester.addSetNext("faces-config/flow-definition/view", "addView");
386         digester.addSetProperties("faces-config/flow-definition/view", "id", "id");
387         digester.addCallMethod("faces-config/flow-definition/view/vdl-document", "setVdlDocument", 0);
388         
389         digester.addObjectCreate("faces-config/flow-definition/switch", FacesFlowSwitchImpl.class);
390         digester.addSetNext("faces-config/flow-definition/switch", "addSwitch");
391         digester.addSetProperties("faces-config/flow-definition/switch", "id", "id");
392         
393         digester.addObjectCreate("faces-config/flow-definition/switch/default-outcome", 
394             NavigationCaseImpl.class);
395         digester.addSetNext("faces-config/flow-definition/switch/default-outcome", 
396             "setDefaultOutcome");
397         digester.addCallMethod("faces-config/flow-definition/switch/default-outcome", 
398             "setFromOutcome", 0);
399         
400         addNavigationCases(externalContext, "faces-config/flow-definition/switch/case",
401             "addNavigationCase");
402         
403         digester.addObjectCreate("faces-config/flow-definition/flow-return", FacesFlowReturnImpl.class);
404         digester.addSetNext("faces-config/flow-definition/flow-return", "addReturn");
405         digester.addSetProperties("faces-config/flow-definition/flow-return", "id", "id");
406         digester.addObjectCreate("faces-config/flow-definition/flow-return/from-outcome", 
407             NavigationCaseImpl.class);
408         digester.addSetNext("faces-config/flow-definition/flow-return/from-outcome", 
409             "setNavigationCase");
410         digester.addCallMethod("faces-config/flow-definition/flow-return/from-outcome", 
411             "setFromOutcome", 0);
412         
413         addNavigationRules(externalContext, "faces-config/flow-definition/navigation-rule", "addNavigationRule");
414         
415         digester.addObjectCreate("faces-config/flow-definition/flow-call", FacesFlowCallImpl.class);
416         digester.addSetNext("faces-config/flow-definition/flow-call", "addFlowCall");
417         digester.addSetProperties("faces-config/flow-definition/flow-call", "id", "id");
418         digester.addObjectCreate("faces-config/flow-definition/flow-call/flow-reference", FacesFlowReferenceImpl.class);
419         digester.addSetNext("faces-config/flow-definition/flow-call/flow-reference", "setFlowReference");        
420         digester.addCallMethod("faces-config/flow-definition/flow-call/flow-reference/flow-document-id", 
421                 "setFlowDocumentId", 0);
422         digester.addCallMethod("faces-config/flow-definition/flow-call/flow-reference/flow-id", "setFlowId", 0);
423         
424         digester.addObjectCreate("faces-config/flow-definition/flow-call/outbound-parameter", 
425             FacesFlowParameterImpl.class);
426         digester.addSetNext("faces-config/flow-definition/flow-call/outbound-parameter", 
427             "addOutboundParameter");
428         digester.addCallMethod("faces-config/flow-definition/flow-call/outbound-parameter/name", "setName", 0);
429         digester.addCallMethod("faces-config/flow-definition/flow-call/outbound-parameter/value", "setValue", 0);
430         
431         digester.addObjectCreate("faces-config/flow-definition/method-call", FacesFlowMethodCallImpl.class);
432         digester.addSetNext("faces-config/flow-definition/method-call", "addMethodCall");
433         digester.addSetProperties("faces-config/flow-definition/method-call", "id", "id");
434         digester.addCallMethod("faces-config/flow-definition/method-call/method", "setMethod", 0);
435         digester.addCallMethod("faces-config/flow-definition/method-call/default-outcome", 
436             "setDefaultOutcome", 0);
437         digester.addObjectCreate("faces-config/flow-definition/method-call/parameter", 
438             FacesFlowMethodParameterImpl.class);
439         digester.addSetNext("faces-config/flow-definition/method-call/parameter", "addParameter");
440         digester.addCallMethod("faces-config/flow-definition/method-call/parameter/class", "setClassName", 0);
441         digester.addCallMethod("faces-config/flow-definition/method-call/parameter/value", "setValue", 0);
442         
443         digester.addObjectCreate("faces-config/flow-definition/inbound-parameter", 
444             FacesFlowParameterImpl.class);
445         digester.addSetNext("faces-config/flow-definition/inbound-parameter", "addInboundParameter");
446         digester.addCallMethod("faces-config/flow-definition/inbound-parameter/name", "setName", 0);
447         digester.addCallMethod("faces-config/flow-definition/inbound-parameter/value", "setValue", 0);
448         
449         //View Pool config
450         digester.addObjectCreate("faces-config/faces-config-extension/view-pool-mapping", 
451             ViewPoolMappingImpl.class);
452         digester.addSetNext("faces-config/faces-config-extension/view-pool-mapping", 
453             "addViewPoolMapping");
454         digester.addCallMethod(
455                         "faces-config/faces-config-extension/view-pool-mapping/url-pattern", "setUrlPattern", 0);
456         digester.addObjectCreate("faces-config/faces-config-extension/view-pool-mapping/parameter", 
457             ViewPoolParameterImpl.class);
458         digester.addSetNext("faces-config/faces-config-extension/view-pool-mapping/parameter", "addParameter");
459         digester.addCallMethod("faces-config/faces-config-extension/view-pool-mapping/parameter/name", "setName", 0);
460         digester.addCallMethod("faces-config/faces-config-extension/view-pool-mapping/parameter/value", "setValue", 0);
461         
462         //Facelets Template Mapping config
463         digester.addObjectCreate("faces-config/faces-config-extension/facelets-template-mapping", 
464             FaceletsTemplateMappingImpl.class);
465         digester.addSetNext("faces-config/faces-config-extension/facelets-template-mapping", 
466             "addFaceletsTemplateMapping");
467         digester.addCallMethod(
468                         "faces-config/faces-config-extension/facelets-template-mapping/url-pattern", 
469                         "setUrlPattern", 0);
470     }
471 
472     private void postProcessFacesConfig(String systemId, FacesConfigImpl config)
473     {
474         for (org.apache.myfaces.config.element.Application application : config.getApplications())
475         {
476             for (org.apache.myfaces.config.element.LocaleConfig localeConfig : application.getLocaleConfig())
477             {
478                 if (!localeConfig.getSupportedLocales().contains(localeConfig.getDefaultLocale()))
479                 {
480                     localeConfig.getSupportedLocales().add(localeConfig.getDefaultLocale());
481                 }
482             }
483         }
484         
485         for (FacesFlowDefinition facesFlowDefinition : config.getFacesFlowDefinitions())
486         {
487             // JSF 2.2 section 11.4.3.1 says this: "... Flows are defined using the 
488             // <flow-definition> element. This element must have an id attribute which uniquely 
489             // identifies the flow within the scope of the Application Configuration Resource 
490             // file in which the element appears. To enable multiple flows with the same id to 
491             // exist in an application, the <faces-config><name> element is taken to 
492             // be the definingDocumentId of the flow. If no <name> element is specified, 
493             // the empty string is taken as the value for definingDocumentId. ..."
494             if (config.getName() != null)
495             {
496                 ((FacesFlowDefinitionImpl)facesFlowDefinition).setDefiningDocumentId(
497                     config.getName());
498             }
499             else
500             {
501                 ((FacesFlowDefinitionImpl)facesFlowDefinition).setDefiningDocumentId("");
502             }
503         }
504     }
505     
506     public FacesConfigImpl getFacesConfig(InputStream in, String systemId) throws IOException, SAXException
507     {
508         InputSource is = new InputSource(in);
509         is.setSystemId(systemId);
510 
511         // Fix for http://issues.apache.org/jira/browse/MYFACES-236
512         FacesConfigImpl config = (FacesConfigImpl) digester.parse(is);
513 
514         postProcessFacesConfig(systemId, config);
515 
516         return config;
517     }
518     
519     public FacesConfigImpl getFacesConfig(Reader r) throws IOException, SAXException
520     {
521         //InputSource is = new InputSource(in);
522         //is.setSystemId(systemId);
523 
524         // Fix for http://issues.apache.org/jira/browse/MYFACES-236
525         FacesConfigImpl config = (FacesConfigImpl) digester.parse(r);
526 
527         postProcessFacesConfig(null, config);
528 
529         return config;
530     }
531 
532 }