1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.ee6;
20
21 import java.net.URL;
22 import java.util.Arrays;
23 import java.util.Collection;
24 import java.util.HashSet;
25 import java.util.Map;
26 import java.util.Set;
27 import java.util.logging.Level;
28 import java.util.logging.Logger;
29
30 import javax.faces.application.ResourceDependencies;
31 import javax.faces.application.ResourceDependency;
32 import javax.faces.bean.ApplicationScoped;
33 import javax.faces.bean.CustomScoped;
34 import javax.faces.bean.ManagedBean;
35 import javax.faces.bean.ManagedProperty;
36 import javax.faces.bean.NoneScoped;
37 import javax.faces.bean.ReferencedBean;
38 import javax.faces.bean.RequestScoped;
39 import javax.faces.bean.SessionScoped;
40 import javax.faces.bean.ViewScoped;
41 import javax.faces.component.FacesComponent;
42 import javax.faces.component.UIComponent;
43 import javax.faces.component.behavior.FacesBehavior;
44 import javax.faces.context.ExternalContext;
45 import javax.faces.convert.Converter;
46 import javax.faces.convert.FacesConverter;
47 import javax.faces.event.ListenerFor;
48 import javax.faces.event.ListenersFor;
49 import javax.faces.event.NamedEvent;
50 import javax.faces.render.FacesBehaviorRenderer;
51 import javax.faces.render.FacesRenderer;
52 import javax.faces.render.Renderer;
53 import javax.faces.validator.FacesValidator;
54 import javax.faces.validator.Validator;
55 import javax.faces.webapp.FacesServlet;
56 import javax.servlet.Servlet;
57 import javax.servlet.ServletContainerInitializer;
58 import javax.servlet.ServletContext;
59 import javax.servlet.ServletException;
60 import javax.servlet.ServletRegistration;
61 import javax.servlet.annotation.HandlesTypes;
62 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
63
64 import org.apache.myfaces.context.servlet.StartupServletExternalContextImpl;
65 import org.apache.myfaces.shared_impl.webapp.webxml.DelegatedFacesServlet;
66 import org.apache.myfaces.spi.FacesConfigResourceProvider;
67 import org.apache.myfaces.spi.FacesConfigResourceProviderFactory;
68
69
70
71
72
73
74
75
76
77
78
79
80 @HandlesTypes({
81 ApplicationScoped.class,
82 CustomScoped.class,
83 FacesBehavior.class,
84 FacesBehaviorRenderer.class,
85 FacesComponent.class,
86 FacesConverter.class,
87 FacesRenderer.class,
88 FacesValidator.class,
89 ListenerFor.class,
90 ListenersFor.class,
91 ManagedBean.class,
92 ManagedProperty.class,
93 NamedEvent.class,
94 NoneScoped.class,
95 ReferencedBean.class,
96 RequestScoped.class,
97 ResourceDependencies.class,
98 ResourceDependency.class,
99 SessionScoped.class,
100 ViewScoped.class,
101 UIComponent.class,
102 Converter.class,
103 Renderer.class,
104 Validator.class
105 })
106 public class MyFacesContainerInitializer implements ServletContainerInitializer
107 {
108
109
110
111
112
113
114 private static final String FACES_SERVLET_ADDED_ATTRIBUTE = "org.apache.myfaces.DYNAMICALLY_ADDED_FACES_SERVLET";
115
116
117
118
119
120
121 private static final String FACES_SERVLET_FOUND = "org.apache.myfaces.FACES_SERVLET_FOUND";
122
123 private static final String INITIALIZE_ALWAYS_STANDALONE = "org.apache.myfaces.INITIALIZE_ALWAYS_STANDALONE";
124
125
126
127
128
129
130 @JSFWebConfigParam(since="2.2.10", expectedValues = "true, false", defaultValue = "false",
131 tags = "performance")
132 private static final String INITIALIZE_SKIP_JAR_FACES_CONFIG_SCAN =
133 "org.apache.myfaces.INITIALIZE_SKIP_JAR_FACES_CONFIG_SCAN";
134
135 private static final String FACES_CONFIG_RESOURCE = "/WEB-INF/faces-config.xml";
136 private static final Logger log = Logger.getLogger(MyFacesContainerInitializer.class.getName());
137 private static final String[] FACES_SERVLET_MAPPINGS = { "/faces/*", "*.jsf", "*.faces" };
138 private static final String FACES_SERVLET_NAME = "FacesServlet";
139 private static final Class<? extends Servlet> FACES_SERVLET_CLASS = FacesServlet.class;
140 private static final Class<?> DELEGATED_FACES_SERVLET_CLASS = DelegatedFacesServlet.class;
141
142 public void onStartup(Set<Class<?>> clazzes, ServletContext servletContext) throws ServletException
143 {
144 boolean startDireclty = shouldStartupRegardless(servletContext);
145
146 if (startDireclty)
147 {
148
149
150
151 return;
152 }
153
154
155
156
157
158
159
160
161
162 if ((clazzes != null && !clazzes.isEmpty()) || isFacesConfigPresent(servletContext))
163 {
164
165 Map<String, ? extends ServletRegistration> servlets = servletContext.getServletRegistrations();
166 for (Map.Entry<String, ? extends ServletRegistration> servletEntry : servlets.entrySet())
167 {
168 String className = servletEntry.getValue().getClassName();
169 if (FACES_SERVLET_CLASS.getName().equals(className)
170 || isDelegatedFacesServlet(className))
171 {
172
173 servletContext.setAttribute(FACES_SERVLET_FOUND, Boolean.TRUE);
174 return;
175 }
176 }
177
178
179 ServletRegistration.Dynamic servlet = servletContext.addServlet(FACES_SERVLET_NAME, FACES_SERVLET_CLASS);
180
181
182 String[] mappings = FACES_SERVLET_MAPPINGS;
183 Set<String> conflictMappings = servlet.addMapping(mappings);
184 if (conflictMappings != null && !conflictMappings.isEmpty())
185 {
186
187 Set<String> newMappings = new HashSet<String>(Arrays.asList(mappings));
188 newMappings.removeAll(conflictMappings);
189 mappings = newMappings.toArray(new String[newMappings.size()]);
190 servlet.addMapping(mappings);
191 }
192
193 if (mappings != null && mappings.length > 0)
194 {
195
196
197
198
199 servletContext.setAttribute(FACES_SERVLET_ADDED_ATTRIBUTE, Boolean.TRUE);
200
201
202 log.log(Level.INFO, "Added FacesServlet with mappings="
203 + Arrays.toString(mappings));
204 }
205
206 }
207 }
208
209
210
211
212
213
214 private boolean shouldStartupRegardless(ServletContext servletContext)
215 {
216 try
217 {
218 String standaloneStartup = servletContext.getInitParameter(INITIALIZE_ALWAYS_STANDALONE);
219
220
221 return "true".equalsIgnoreCase(standaloneStartup);
222 }
223 catch (Exception e)
224 {
225 return false;
226 }
227 }
228
229
230
231
232
233
234 private boolean shouldSkipJarFacesConfigScan(ServletContext servletContext)
235 {
236 try
237 {
238 String skipJarScan = servletContext.getInitParameter(INITIALIZE_SKIP_JAR_FACES_CONFIG_SCAN);
239
240 if (skipJarScan == null)
241 {
242 skipJarScan = System.getProperty(INITIALIZE_SKIP_JAR_FACES_CONFIG_SCAN);
243 }
244 return "true".equalsIgnoreCase(skipJarScan);
245 }
246 catch (Exception e)
247 {
248 return false;
249 }
250 }
251
252
253
254
255
256 private boolean isFacesConfigPresent(ServletContext servletContext)
257 {
258 try
259 {
260
261 if (servletContext.getResource(FACES_CONFIG_RESOURCE) != null)
262 {
263 return true;
264 }
265
266
267
268 String configFilesAttrValue = servletContext.getInitParameter(FacesServlet.CONFIG_FILES_ATTR);
269 if (configFilesAttrValue != null)
270 {
271 String[] configFiles = configFilesAttrValue.split(",");
272 for (String file : configFiles)
273 {
274 if (servletContext.getResource(file.trim()) != null)
275 {
276 return true;
277 }
278 }
279 }
280
281
282
283
284
285
286
287
288
289 if (!shouldSkipJarFacesConfigScan(servletContext))
290 {
291 ExternalContext externalContext = new StartupServletExternalContextImpl(servletContext, true);
292 FacesConfigResourceProviderFactory factory = FacesConfigResourceProviderFactory.
293 getFacesConfigResourceProviderFactory(externalContext);
294 FacesConfigResourceProvider provider = factory.createFacesConfigResourceProvider(externalContext);
295 Collection<URL> metaInfFacesConfigUrls = provider.getMetaInfConfigurationResources(externalContext);
296
297 if (metaInfFacesConfigUrls != null && !metaInfFacesConfigUrls.isEmpty())
298 {
299 return true;
300 }
301 }
302 return false;
303 }
304 catch (Exception e)
305 {
306 return false;
307 }
308 }
309
310
311
312
313
314
315 private boolean isDelegatedFacesServlet(String className)
316 {
317 if (className == null)
318 {
319
320
321
322 return false;
323 }
324 try
325 {
326 Class<?> clazz = Class.forName(className);
327 return DELEGATED_FACES_SERVLET_CLASS.isAssignableFrom(clazz);
328 }
329 catch (ClassNotFoundException cnfe)
330 {
331 return false;
332 }
333 }
334 }