1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.config;
20
21 import org.apache.myfaces.config.annotation.AnnotationConfigurator;
22 import org.apache.myfaces.config.element.FacesConfig;
23 import org.apache.myfaces.config.impl.digester.DigesterFacesConfigUnmarshallerImpl;
24 import org.apache.myfaces.shared.config.MyfacesConfig;
25 import org.apache.myfaces.shared.util.ClassUtils;
26 import org.apache.myfaces.spi.FacesConfigResourceProvider;
27 import org.apache.myfaces.spi.FacesConfigResourceProviderFactory;
28 import org.apache.myfaces.spi.FacesConfigurationProvider;
29 import org.apache.myfaces.spi.ServiceProviderFinderFactory;
30 import org.xml.sax.SAXException;
31
32 import javax.faces.FacesException;
33 import javax.faces.FactoryFinder;
34 import javax.faces.context.ExternalContext;
35 import javax.faces.webapp.FacesServlet;
36 import java.io.IOException;
37 import java.io.InputStream;
38 import java.net.URL;
39 import java.net.URLConnection;
40 import java.util.ArrayList;
41 import java.util.Collection;
42 import java.util.HashSet;
43 import java.util.List;
44 import java.util.Set;
45 import java.util.StringTokenizer;
46 import java.util.logging.Level;
47 import java.util.logging.Logger;
48
49
50
51
52
53
54 public class DefaultFacesConfigurationProvider extends FacesConfigurationProvider
55 {
56
57 private static final String STANDARD_FACES_CONFIG_RESOURCE = "META-INF/standard-faces-config.xml";
58
59
60
61 private static final String DEFAULT_FACES_CONFIG = "/WEB-INF/faces-config.xml";
62
63 private static final Set<String> FACTORY_NAMES = new HashSet<String>();
64 {
65 FACTORY_NAMES.add(FactoryFinder.APPLICATION_FACTORY);
66 FACTORY_NAMES.add(FactoryFinder.EXCEPTION_HANDLER_FACTORY);
67 FACTORY_NAMES.add(FactoryFinder.EXTERNAL_CONTEXT_FACTORY);
68 FACTORY_NAMES.add(FactoryFinder.FACES_CONTEXT_FACTORY);
69 FACTORY_NAMES.add(FactoryFinder.LIFECYCLE_FACTORY);
70 FACTORY_NAMES.add(FactoryFinder.RENDER_KIT_FACTORY);
71 FACTORY_NAMES.add(FactoryFinder.TAG_HANDLER_DELEGATE_FACTORY);
72 FACTORY_NAMES.add(FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY);
73 FACTORY_NAMES.add(FactoryFinder.VISIT_CONTEXT_FACTORY);
74 FACTORY_NAMES.add(FactoryFinder.VIEW_DECLARATION_LANGUAGE_FACTORY);
75 }
76
77 private static final Logger log = Logger.getLogger(DefaultFacesConfigurationProvider.class.getName());
78
79 private FacesConfigUnmarshaller<? extends FacesConfig> _unmarshaller;
80
81 private AnnotationConfigurator _annotationConfigurator;
82
83 protected void setUnmarshaller(ExternalContext ectx, FacesConfigUnmarshaller<? extends FacesConfig> unmarshaller)
84 {
85 _unmarshaller = unmarshaller;
86 }
87
88 @SuppressWarnings("unchecked")
89 protected FacesConfigUnmarshaller<? extends FacesConfig> getUnmarshaller(ExternalContext ectx)
90 {
91 if (_unmarshaller == null)
92 {
93 _unmarshaller = new DigesterFacesConfigUnmarshallerImpl(ectx);
94 }
95 return _unmarshaller;
96 }
97
98 protected void setAnnotationConfigurator(AnnotationConfigurator configurator)
99 {
100 _annotationConfigurator = configurator;
101 }
102
103 protected AnnotationConfigurator getAnnotationConfigurator()
104 {
105 if (_annotationConfigurator == null)
106 {
107 _annotationConfigurator = new AnnotationConfigurator();
108 }
109 return _annotationConfigurator;
110 }
111
112 @Override
113 public FacesConfig getStandardFacesConfig(ExternalContext ectx)
114 {
115 try
116 {
117 if (MyfacesConfig.getCurrentInstance(ectx).isValidateXML())
118 {
119 URL url = ClassUtils.getResource(STANDARD_FACES_CONFIG_RESOURCE);
120 if (url != null)
121 {
122 validateFacesConfig(ectx, url);
123 }
124 }
125 InputStream stream = ClassUtils.getResourceAsStream(STANDARD_FACES_CONFIG_RESOURCE);
126 if (stream == null)
127 {
128 throw new FacesException("Standard faces config " + STANDARD_FACES_CONFIG_RESOURCE + " not found");
129 }
130 if (log.isLoggable(Level.INFO))
131 {
132 log.info("Reading standard config " + STANDARD_FACES_CONFIG_RESOURCE);
133 }
134
135 FacesConfig facesConfig = getUnmarshaller(ectx).getFacesConfig(stream, STANDARD_FACES_CONFIG_RESOURCE);
136 stream.close();
137 return facesConfig;
138 }
139 catch (IOException e)
140 {
141 throw new FacesException(e);
142 }
143 catch (SAXException e)
144 {
145 throw new FacesException(e);
146 }
147 }
148
149 @Override
150 public FacesConfig getAnnotationsFacesConfig(ExternalContext ectx, boolean metadataComplete)
151 {
152 return getAnnotationConfigurator().createFacesConfig(ectx, metadataComplete);
153 }
154
155
156
157
158 @Override
159 public FacesConfig getMetaInfServicesFacesConfig(ExternalContext ectx)
160 {
161 try
162 {
163 org.apache.myfaces.config.impl.digester.elements.FacesConfig facesConfig
164 = new org.apache.myfaces.config.impl.digester.elements.FacesConfig();
165 org.apache.myfaces.config.impl.digester.elements.Factory factory
166 = new org.apache.myfaces.config.impl.digester.elements.Factory();
167
168 facesConfig.addFactory(factory);
169
170 for (String factoryName : FACTORY_NAMES)
171 {
172 List<String> classList = ServiceProviderFinderFactory.getServiceProviderFinder(ectx)
173 .getServiceProviderList(factoryName);
174
175 for (String className : classList)
176 {
177 if (log.isLoggable(Level.INFO))
178 {
179 log.info("Found " + factoryName + " factory implementation: " + className);
180 }
181
182 if (factoryName.equals(FactoryFinder.APPLICATION_FACTORY))
183 {
184 factory.addApplicationFactory(className);
185 }
186 else if(factoryName.equals(FactoryFinder.EXCEPTION_HANDLER_FACTORY))
187 {
188 factory.addExceptionHandlerFactory(className);
189 }
190 else if (factoryName.equals(FactoryFinder.EXTERNAL_CONTEXT_FACTORY))
191 {
192 factory.addExternalContextFactory(className);
193 }
194 else if (factoryName.equals(FactoryFinder.FACES_CONTEXT_FACTORY))
195 {
196 factory.addFacesContextFactory(className);
197 }
198 else if (factoryName.equals(FactoryFinder.LIFECYCLE_FACTORY))
199 {
200 factory.addLifecycleFactory(className);
201 }
202 else if (factoryName.equals(FactoryFinder.RENDER_KIT_FACTORY))
203 {
204 factory.addRenderkitFactory(className);
205 }
206 else if(factoryName.equals(FactoryFinder.TAG_HANDLER_DELEGATE_FACTORY))
207 {
208 factory.addTagHandlerDelegateFactory(className);
209 }
210 else if (factoryName.equals(FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY))
211 {
212 factory.addPartialViewContextFactory(className);
213 }
214 else if(factoryName.equals(FactoryFinder.VISIT_CONTEXT_FACTORY))
215 {
216 factory.addVisitContextFactory(className);
217 }
218 else if(factoryName.equals(FactoryFinder.VIEW_DECLARATION_LANGUAGE_FACTORY))
219 {
220 factory.addViewDeclarationLanguageFactory(className);
221 }
222
223 else
224 {
225 throw new IllegalStateException("Unexpected factory name " + factoryName);
226 }
227 }
228 }
229 return facesConfig;
230 }
231 catch (Throwable e)
232 {
233 throw new FacesException(e);
234 }
235 }
236
237
238
239
240 @Override
241 public List<FacesConfig> getClassloaderFacesConfig(ExternalContext ectx)
242 {
243 List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
244 try
245 {
246 FacesConfigResourceProvider provider = FacesConfigResourceProviderFactory.
247 getFacesConfigResourceProviderFactory(ectx).createFacesConfigResourceProvider(ectx);
248
249 Collection<URL> facesConfigs = provider.getMetaInfConfigurationResources(ectx);
250
251 for (URL url : facesConfigs)
252 {
253 if (MyfacesConfig.getCurrentInstance(ectx).isValidateXML())
254 {
255 validateFacesConfig(ectx, url);
256 }
257 InputStream stream = null;
258 try
259 {
260 stream = openStreamWithoutCache(url);
261 if (log.isLoggable(Level.INFO))
262 {
263 log.info("Reading config : " + url.toExternalForm());
264 }
265 appConfigResources.add(getUnmarshaller(ectx).getFacesConfig(stream, url.toExternalForm()));
266
267 }
268 finally
269 {
270 if (stream != null)
271 {
272 stream.close();
273 }
274 }
275 }
276 }
277 catch (Throwable e)
278 {
279 throw new FacesException(e);
280 }
281 return appConfigResources;
282 }
283
284 @Override
285 public List<FacesConfig> getContextSpecifiedFacesConfig(ExternalContext ectx)
286 {
287 List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
288 try
289 {
290 for (String systemId : getConfigFilesList(ectx))
291 {
292 if (MyfacesConfig.getCurrentInstance(ectx).isValidateXML())
293 {
294 URL url = ectx.getResource(systemId);
295 if (url != null)
296 {
297 validateFacesConfig(ectx, url);
298 }
299 }
300 InputStream stream = ectx.getResourceAsStream(systemId);
301 if (stream == null)
302 {
303 log.severe("Faces config resource " + systemId + " not found");
304 continue;
305 }
306
307 if (log.isLoggable(Level.INFO))
308 {
309 log.info("Reading config " + systemId);
310 }
311 appConfigResources.add(getUnmarshaller(ectx).getFacesConfig(stream, systemId));
312
313 stream.close();
314 }
315 }
316 catch (Throwable e)
317 {
318 throw new FacesException(e);
319 }
320 return appConfigResources;
321 }
322
323 @Override
324 public FacesConfig getWebAppFacesConfig(ExternalContext ectx)
325 {
326 try
327 {
328 FacesConfig webAppConfig = null;
329
330 if (MyfacesConfig.getCurrentInstance(ectx).isValidateXML())
331 {
332 URL url = ectx.getResource(DEFAULT_FACES_CONFIG);
333 if (url != null)
334 {
335 validateFacesConfig(ectx, url);
336 }
337 }
338 InputStream stream = ectx.getResourceAsStream(DEFAULT_FACES_CONFIG);
339 if (stream != null)
340 {
341 if (log.isLoggable(Level.INFO))
342 {
343 log.info("Reading config /WEB-INF/faces-config.xml");
344 }
345 webAppConfig = getUnmarshaller(ectx).getFacesConfig(stream, DEFAULT_FACES_CONFIG);
346
347 stream.close();
348 }
349 return webAppConfig;
350 }
351 catch (IOException e)
352 {
353 throw new FacesException(e);
354 }
355 catch (SAXException e)
356 {
357 throw new FacesException(e);
358 }
359
360 }
361
362 private InputStream openStreamWithoutCache(URL url) throws IOException
363 {
364 URLConnection connection = url.openConnection();
365 connection.setUseCaches(false);
366 return connection.getInputStream();
367 }
368
369 private List<String> getConfigFilesList(ExternalContext ectx)
370 {
371 String configFiles = ectx.getInitParameter(FacesServlet.CONFIG_FILES_ATTR);
372 List<String> configFilesList = new ArrayList<String>();
373 if (configFiles != null)
374 {
375 StringTokenizer st = new StringTokenizer(configFiles, ",", false);
376 while (st.hasMoreTokens())
377 {
378 String systemId = st.nextToken().trim();
379
380 if (DEFAULT_FACES_CONFIG.equals(systemId))
381 {
382 if (log.isLoggable(Level.WARNING))
383 {
384 log.warning(DEFAULT_FACES_CONFIG + " has been specified in the "
385 + FacesServlet.CONFIG_FILES_ATTR
386 + " context parameter of "
387 + "the deployment descriptor. This will automatically be removed, "
388 + "if we wouldn't do this, it would be loaded twice. See JSF spec 1.1, 10.3.2");
389 }
390 }
391 else
392 {
393 configFilesList.add(systemId);
394 }
395 }
396 }
397 return configFilesList;
398 }
399
400 private void validateFacesConfig(ExternalContext ectx, URL url) throws IOException, SAXException
401 {
402 String version = ConfigFilesXmlValidationUtils.getFacesConfigVersion(url);
403 if ("1.2".equals(version) || "2.0".equals(version) || "2.1".equals(version))
404 {
405 ConfigFilesXmlValidationUtils.validateFacesConfigFile(url, ectx, version);
406 }
407 }
408
409 }