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
63 import org.apache.myfaces.context.servlet.StartupServletExternalContextImpl;
64 import org.apache.myfaces.shared_impl.webapp.webxml.DelegatedFacesServlet;
65 import org.apache.myfaces.spi.FacesConfigResourceProvider;
66 import org.apache.myfaces.spi.FacesConfigResourceProviderFactory;
67
68
69
70
71
72
73
74
75
76
77
78
79 @HandlesTypes({
80 ApplicationScoped.class,
81 CustomScoped.class,
82 FacesBehavior.class,
83 FacesBehaviorRenderer.class,
84 FacesComponent.class,
85 FacesConverter.class,
86 FacesRenderer.class,
87 FacesValidator.class,
88 ListenerFor.class,
89 ListenersFor.class,
90 ManagedBean.class,
91 ManagedProperty.class,
92 NamedEvent.class,
93 NoneScoped.class,
94 ReferencedBean.class,
95 RequestScoped.class,
96 ResourceDependencies.class,
97 ResourceDependency.class,
98 SessionScoped.class,
99 ViewScoped.class,
100 UIComponent.class,
101 Converter.class,
102 Renderer.class,
103 Validator.class
104 })
105 public class MyFacesContainerInitializer implements ServletContainerInitializer
106 {
107
108
109
110
111
112
113 private static final String FACES_SERVLET_ADDED_ATTRIBUTE = "org.apache.myfaces.DYNAMICALLY_ADDED_FACES_SERVLET";
114
115 private static final String INITIALIZE_ALWAYS_STANDALONE = "org.apache.myfaces.INITIALIZE_ALWAYS_STANDALONE";
116 private static final String FACES_CONFIG_RESOURCE = "/WEB-INF/faces-config.xml";
117 private static final Logger log = Logger.getLogger(MyFacesContainerInitializer.class.getName());
118 private static final String[] FACES_SERVLET_MAPPINGS = { "/faces/*", "*.jsf", "*.faces" };
119 private static final String FACES_SERVLET_NAME = "FacesServlet";
120 private static final Class<? extends Servlet> FACES_SERVLET_CLASS = FacesServlet.class;
121 private static final Class<?> DELEGATED_FACES_SERVLET_CLASS = DelegatedFacesServlet.class;
122
123 public void onStartup(Set<Class<?>> clazzes, ServletContext servletContext) throws ServletException
124 {
125 boolean startDireclty = shouldStartupRegardless(servletContext);
126
127 if (startDireclty)
128 {
129
130
131
132 return;
133 }
134
135
136
137
138
139
140
141
142
143 if ((clazzes != null && !clazzes.isEmpty()) || isFacesConfigPresent(servletContext))
144 {
145
146 Map<String, ? extends ServletRegistration> servlets = servletContext.getServletRegistrations();
147 for (Map.Entry<String, ? extends ServletRegistration> servletEntry : servlets.entrySet())
148 {
149 String className = servletEntry.getValue().getClassName();
150 if (FACES_SERVLET_CLASS.getName().equals(className)
151 || isDelegatedFacesServlet(className))
152 {
153
154 return;
155 }
156 }
157
158
159 ServletRegistration.Dynamic servlet = servletContext.addServlet(FACES_SERVLET_NAME, FACES_SERVLET_CLASS);
160
161
162 String[] mappings = FACES_SERVLET_MAPPINGS;
163 Set<String> conflictMappings = servlet.addMapping(mappings);
164 if (conflictMappings != null && !conflictMappings.isEmpty())
165 {
166
167 Set<String> newMappings = new HashSet<String>(Arrays.asList(mappings));
168 newMappings.removeAll(conflictMappings);
169 mappings = newMappings.toArray(new String[newMappings.size()]);
170 servlet.addMapping(mappings);
171 }
172
173 if (mappings != null && mappings.length > 0)
174 {
175
176
177
178
179 servletContext.setAttribute(FACES_SERVLET_ADDED_ATTRIBUTE, Boolean.TRUE);
180
181
182 log.log(Level.INFO, "Added FacesServlet with mappings="
183 + Arrays.toString(mappings));
184 }
185
186 }
187 }
188
189
190
191
192
193
194 private boolean shouldStartupRegardless(ServletContext servletContext)
195 {
196 try
197 {
198 String standaloneStartup = servletContext.getInitParameter(INITIALIZE_ALWAYS_STANDALONE);
199
200
201 return "true".equalsIgnoreCase(standaloneStartup);
202 }
203 catch (Exception e)
204 {
205 return false;
206 }
207 }
208
209
210
211
212
213 private boolean isFacesConfigPresent(ServletContext servletContext)
214 {
215 try
216 {
217
218 if (servletContext.getResource(FACES_CONFIG_RESOURCE) != null)
219 {
220 return true;
221 }
222
223
224
225 String configFilesAttrValue = servletContext.getInitParameter(FacesServlet.CONFIG_FILES_ATTR);
226 if (configFilesAttrValue != null)
227 {
228 String[] configFiles = configFilesAttrValue.split(",");
229 for (String file : configFiles)
230 {
231 if (servletContext.getResource(file.trim()) != null)
232 {
233 return true;
234 }
235 }
236 }
237
238
239
240
241
242
243
244
245 ExternalContext externalContext = new StartupServletExternalContextImpl(servletContext, true);
246 FacesConfigResourceProviderFactory factory = FacesConfigResourceProviderFactory.
247 getFacesConfigResourceProviderFactory(externalContext);
248 FacesConfigResourceProvider provider = factory.createFacesConfigResourceProvider(externalContext);
249 Collection<URL> metaInfFacesConfigUrls = provider.getMetaInfConfigurationResources(externalContext);
250
251 if (metaInfFacesConfigUrls != null && !metaInfFacesConfigUrls.isEmpty())
252 {
253 return true;
254 }
255
256 return false;
257 }
258 catch (Exception e)
259 {
260 return false;
261 }
262 }
263
264
265
266
267
268
269 private boolean isDelegatedFacesServlet(String className)
270 {
271 if (className == null)
272 {
273
274
275
276 return false;
277 }
278 try
279 {
280 Class<?> clazz = Class.forName(className);
281 return DELEGATED_FACES_SERVLET_CLASS.isAssignableFrom(clazz);
282 }
283 catch (ClassNotFoundException cnfe)
284 {
285 return false;
286 }
287 }
288 }