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 throw new FacesException("Standard faces config " + STANDARD_FACES_CONFIG_RESOURCE + " not found");
128 if (log.isLoggable(Level.INFO))
129 log.info("Reading standard config " + STANDARD_FACES_CONFIG_RESOURCE);
130
131 FacesConfig facesConfig = getUnmarshaller(ectx).getFacesConfig(stream, STANDARD_FACES_CONFIG_RESOURCE);
132 stream.close();
133 return facesConfig;
134 }
135 catch (IOException e)
136 {
137 throw new FacesException(e);
138 }
139 catch (SAXException e)
140 {
141 throw new FacesException(e);
142 }
143 }
144
145 @Override
146 public FacesConfig getAnnotationsFacesConfig(ExternalContext ectx, boolean metadataComplete)
147 {
148 return getAnnotationConfigurator().createFacesConfig(ectx, metadataComplete);
149 }
150
151
152
153
154 @Override
155 public FacesConfig getMetaInfServicesFacesConfig(ExternalContext ectx)
156 {
157 try
158 {
159 org.apache.myfaces.config.impl.digester.elements.FacesConfig facesConfig
160 = new org.apache.myfaces.config.impl.digester.elements.FacesConfig();
161 org.apache.myfaces.config.impl.digester.elements.Factory factory
162 = new org.apache.myfaces.config.impl.digester.elements.Factory();
163
164 facesConfig.addFactory(factory);
165
166 for (String factoryName : FACTORY_NAMES)
167 {
168 List<String> classList = ServiceProviderFinderFactory.getServiceProviderFinder(ectx)
169 .getServiceProviderList(factoryName);
170
171 for (String className : classList)
172 {
173 if (log.isLoggable(Level.INFO))
174 {
175 log.info("Found " + factoryName + " factory implementation: " + className);
176 }
177
178 if (factoryName.equals(FactoryFinder.APPLICATION_FACTORY))
179 {
180 factory.addApplicationFactory(className);
181 }
182 else if(factoryName.equals(FactoryFinder.EXCEPTION_HANDLER_FACTORY))
183 {
184 factory.addExceptionHandlerFactory(className);
185 }
186 else if (factoryName.equals(FactoryFinder.EXTERNAL_CONTEXT_FACTORY))
187 {
188 factory.addExternalContextFactory(className);
189 }
190 else if (factoryName.equals(FactoryFinder.FACES_CONTEXT_FACTORY))
191 {
192 factory.addFacesContextFactory(className);
193 }
194 else if (factoryName.equals(FactoryFinder.LIFECYCLE_FACTORY))
195 {
196 factory.addLifecycleFactory(className);
197 }
198 else if (factoryName.equals(FactoryFinder.RENDER_KIT_FACTORY))
199 {
200 factory.addRenderkitFactory(className);
201 }
202 else if(factoryName.equals(FactoryFinder.TAG_HANDLER_DELEGATE_FACTORY))
203 {
204 factory.addTagHandlerDelegateFactory(className);
205 }
206 else if (factoryName.equals(FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY))
207 {
208 factory.addPartialViewContextFactory(className);
209 }
210 else if(factoryName.equals(FactoryFinder.VISIT_CONTEXT_FACTORY))
211 {
212 factory.addVisitContextFactory(className);
213 }
214 else if(factoryName.equals(FactoryFinder.VIEW_DECLARATION_LANGUAGE_FACTORY))
215 {
216 factory.addViewDeclarationLanguageFactory(className);
217 }
218
219 else
220 {
221 throw new IllegalStateException("Unexpected factory name " + factoryName);
222 }
223 }
224 }
225 return facesConfig;
226 }
227 catch (Throwable e)
228 {
229 throw new FacesException(e);
230 }
231 }
232
233
234
235
236 @Override
237 public List<FacesConfig> getClassloaderFacesConfig(ExternalContext ectx)
238 {
239 List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
240 try
241 {
242 FacesConfigResourceProvider provider = FacesConfigResourceProviderFactory.
243 getFacesConfigResourceProviderFactory(ectx).createFacesConfigResourceProvider(ectx);
244
245 Collection<URL> facesConfigs = provider.getMetaInfConfigurationResources(ectx);
246
247 for (URL url : facesConfigs)
248 {
249 if (MyfacesConfig.getCurrentInstance(ectx).isValidateXML())
250 {
251 validateFacesConfig(ectx, url);
252 }
253 InputStream stream = null;
254 try
255 {
256 stream = openStreamWithoutCache(url);
257 if (log.isLoggable(Level.INFO))
258 {
259 log.info("Reading config : " + url.toExternalForm());
260 }
261 appConfigResources.add(getUnmarshaller(ectx).getFacesConfig(stream, url.toExternalForm()));
262
263 }
264 finally
265 {
266 if (stream != null)
267 {
268 stream.close();
269 }
270 }
271 }
272 }
273 catch (Throwable e)
274 {
275 throw new FacesException(e);
276 }
277 return appConfigResources;
278 }
279
280 @Override
281 public List<FacesConfig> getContextSpecifiedFacesConfig(ExternalContext ectx)
282 {
283 List<FacesConfig> appConfigResources = new ArrayList<FacesConfig>();
284 try
285 {
286 for (String systemId : getConfigFilesList(ectx))
287 {
288 if (MyfacesConfig.getCurrentInstance(ectx).isValidateXML())
289 {
290 URL url = ectx.getResource(systemId);
291 if (url != null)
292 {
293 validateFacesConfig(ectx, url);
294 }
295 }
296 InputStream stream = ectx.getResourceAsStream(systemId);
297 if (stream == null)
298 {
299 log.severe("Faces config resource " + systemId + " not found");
300 continue;
301 }
302
303 if (log.isLoggable(Level.INFO))
304 {
305 log.info("Reading config " + systemId);
306 }
307 appConfigResources.add(getUnmarshaller(ectx).getFacesConfig(stream, systemId));
308
309 stream.close();
310 }
311 }
312 catch (Throwable e)
313 {
314 throw new FacesException(e);
315 }
316 return appConfigResources;
317 }
318
319 @Override
320 public FacesConfig getWebAppFacesConfig(ExternalContext ectx)
321 {
322 try
323 {
324 FacesConfig webAppConfig = null;
325
326 if (MyfacesConfig.getCurrentInstance(ectx).isValidateXML())
327 {
328 URL url = ectx.getResource(DEFAULT_FACES_CONFIG);
329 if (url != null)
330 {
331 validateFacesConfig(ectx, url);
332 }
333 }
334 InputStream stream = ectx.getResourceAsStream(DEFAULT_FACES_CONFIG);
335 if (stream != null)
336 {
337 if (log.isLoggable(Level.INFO))
338 log.info("Reading config /WEB-INF/faces-config.xml");
339 webAppConfig = getUnmarshaller(ectx).getFacesConfig(stream, DEFAULT_FACES_CONFIG);
340
341 stream.close();
342 }
343 return webAppConfig;
344 }
345 catch (IOException e)
346 {
347 throw new FacesException(e);
348 }
349 catch (SAXException e)
350 {
351 throw new FacesException(e);
352 }
353
354 }
355
356 private InputStream openStreamWithoutCache(URL url) throws IOException
357 {
358 URLConnection connection = url.openConnection();
359 connection.setUseCaches(false);
360 return connection.getInputStream();
361 }
362
363 private List<String> getConfigFilesList(ExternalContext ectx) {
364 String configFiles = ectx.getInitParameter(FacesServlet.CONFIG_FILES_ATTR);
365 List<String> configFilesList = new ArrayList<String>();
366 if (configFiles != null)
367 {
368 StringTokenizer st = new StringTokenizer(configFiles, ",", false);
369 while (st.hasMoreTokens())
370 {
371 String systemId = st.nextToken().trim();
372
373 if (DEFAULT_FACES_CONFIG.equals(systemId))
374 {
375 if (log.isLoggable(Level.WARNING))
376 {
377 log.warning(DEFAULT_FACES_CONFIG + " has been specified in the " + FacesServlet.CONFIG_FILES_ATTR
378 + " context parameter of "
379 + "the deployment descriptor. This will automatically be removed, "
380 + "if we wouldn't do this, it would be loaded twice. See JSF spec 1.1, 10.3.2");
381 }
382 }
383 else
384 {
385 configFilesList.add(systemId);
386 }
387 }
388 }
389 return configFilesList;
390 }
391
392 private void validateFacesConfig(ExternalContext ectx, URL url) throws IOException, SAXException
393 {
394 String version = ConfigFilesXmlValidationUtils.getFacesConfigVersion(url);
395 if ("1.2".equals(version) || "2.0".equals(version))
396 {
397 ConfigFilesXmlValidationUtils.validateFacesConfigFile(url, ectx, version);
398 }
399 }
400
401 }