1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.shared.application;
20
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.Map;
26
27 import javax.faces.context.ExternalContext;
28 import javax.faces.context.FacesContext;
29 import javax.faces.webapp.FacesServlet;
30 import javax.servlet.ServletContext;
31 import javax.servlet.ServletRegistration;
32 import org.apache.myfaces.shared.config.MyfacesConfig;
33 import org.apache.myfaces.shared.util.ClassUtils;
34 import org.apache.myfaces.shared.util.ExternalContextUtils;
35 import org.apache.myfaces.shared.webapp.webxml.DelegatedFacesServlet;
36
37 public class FacesServletMappingUtils
38 {
39 private static final String FACES_SERVLET_REGISTRATION = "org.apache.myfaces.FACES_SERVLET_REGISTRATION";
40 private static final String SERVLET_REGISTRATIONS = "org.apache.myfaces.SERVLET_REGISTRATIONS";
41
42 private static final String CURRENT_REQUEST_FACES_SERVLET = "org.apache.myfaces.CURRENT_FACES_SERVLET_MAPPING";
43
44
45
46
47 public static class ServletRegistrationInfo
48 {
49 private String className;
50 private String[] mappings;
51 private boolean facesServlet;
52 private ServletRegistration registration;
53
54 public ServletRegistrationInfo(ServletRegistration registration, boolean facesServlet)
55 {
56 this.className = registration.getClassName();
57 this.facesServlet = facesServlet;
58 this.registration = registration;
59
60 Collection<String> mappingsCollection = registration.getMappings();
61 mappings = mappingsCollection.toArray(new String[mappingsCollection.size()]);
62 if (mappings == null)
63 {
64 mappings = new String[]{ };
65 }
66 }
67
68 public String getClassName()
69 {
70 return className;
71 }
72
73 public String[] getMappings()
74 {
75 return mappings;
76 }
77
78 public boolean isFacesServlet()
79 {
80 return facesServlet;
81 }
82
83 public ServletRegistration getRegistration()
84 {
85 return registration;
86 }
87 }
88
89 public static FacesServletMapping getCurrentRequestFacesServletMapping(FacesContext context)
90 {
91 Map<Object, Object> attributes = context.getAttributes();
92
93
94 FacesServletMapping mapping = (FacesServletMapping) attributes.get(CURRENT_REQUEST_FACES_SERVLET);
95 if (mapping == null)
96 {
97 ExternalContext externalContext = context.getExternalContext();
98 mapping = calculateFacesServletMapping(
99 context,
100 externalContext.getRequestServletPath(),
101 externalContext.getRequestPathInfo(),
102 true);
103
104 attributes.put(CURRENT_REQUEST_FACES_SERVLET, mapping);
105 }
106 return mapping;
107 }
108
109 public static List<ServletRegistrationInfo> getServletRegistrations(FacesContext facesContext,
110 ServletContext servletContext, boolean cache)
111 {
112 Map<String, Object> applicationMap = facesContext.getExternalContext().getApplicationMap();
113
114 List<ServletRegistrationInfo> infos =
115 (List<ServletRegistrationInfo>) applicationMap.get(SERVLET_REGISTRATIONS);
116 if (infos == null)
117 {
118 infos = new ArrayList<>();
119
120 Map<String, ? extends ServletRegistration> registrations = servletContext.getServletRegistrations();
121 if (registrations != null)
122 {
123 for (ServletRegistration servletRegistration : registrations.values())
124 {
125 ServletRegistrationInfo info = new ServletRegistrationInfo(servletRegistration,
126 isFacesServlet(facesContext, servletRegistration.getClassName()));
127
128 infos.add(info);
129 }
130 }
131
132 infos = Collections.unmodifiableList(infos);
133 if (cache)
134 {
135 applicationMap.put(SERVLET_REGISTRATIONS, infos);
136 }
137 }
138
139 return infos;
140 }
141
142 public static ServletRegistrationInfo getFacesServletRegistration(FacesContext facesContext,
143 ServletContext servletContext, boolean cache)
144 {
145 Map<String, Object> applicationMap = facesContext.getExternalContext().getApplicationMap();
146
147 ServletRegistrationInfo facesServletRegistration = (ServletRegistrationInfo)
148 applicationMap.get(FACES_SERVLET_REGISTRATION);
149 if (facesServletRegistration == null)
150 {
151 for (ServletRegistrationInfo info : getServletRegistrations(facesContext, servletContext, cache))
152 {
153 if (info.isFacesServlet())
154 {
155 facesServletRegistration = info;
156 break;
157 }
158 }
159
160 if (facesServletRegistration != null && cache)
161 {
162 applicationMap.put(FACES_SERVLET_REGISTRATION, facesServletRegistration);
163 }
164 }
165
166 return facesServletRegistration;
167 }
168
169 public static boolean isFacesServlet(FacesContext facesContext, String servletClassName)
170 {
171
172 if (FacesServlet.class.getName().equals(servletClassName))
173 {
174 return true;
175 }
176
177 Class servletClass = ClassUtils.simpleClassForName(servletClassName, false);
178 if (servletClass != null)
179 {
180 MyfacesConfig config = MyfacesConfig.getCurrentInstance(facesContext.getExternalContext());
181
182 return FacesServlet.class.isAssignableFrom(servletClass)
183 || DelegatedFacesServlet.class.isAssignableFrom(servletClass)
184 || servletClass.getName().equals(config.getDelegateFacesServlet());
185 }
186 return false;
187 }
188
189
190
191
192
193 public static FacesServletMapping calculateFacesServletMapping(
194 FacesContext facesContext, String servletPath, String pathInfo, boolean allowExactMapping)
195 {
196 if (ExternalContextUtils.isPortlet(facesContext.getExternalContext()))
197 {
198 return calculateFacesServletMapping(servletPath, pathInfo);
199 }
200 else
201 {
202 Object context = facesContext.getExternalContext().getContext();
203 if (context instanceof ServletContext)
204 {
205 if (pathInfo != null)
206 {
207
208
209
210
211
212
213 return createMappingFromServletRegistration(facesContext,
214 (ServletContext)context, servletPath, pathInfo, allowExactMapping);
215 }
216 else
217 {
218
219
220
221
222
223 String extension = extractExtensionFromUrl(servletPath);
224 if (extension != null)
225 {
226 return FacesServletMapping.createExtensionMapping(extension);
227 }
228 else
229 {
230
231
232 return createMappingFromServletRegistration(facesContext,
233 (ServletContext)context, servletPath, pathInfo, allowExactMapping);
234 }
235 }
236 }
237 else
238 {
239 return calculateFacesServletMapping(servletPath, pathInfo);
240 }
241 }
242 }
243
244 private static FacesServletMapping createMappingFromServletRegistration(FacesContext facesContext,
245 ServletContext servletContext, String servletPath, String pathInfo, boolean allowExactMatch)
246 {
247 try
248 {
249 List<ServletRegistrationInfo> servletRegistrations =
250 getServletRegistrations(facesContext, servletContext, true);
251 if (servletRegistrations != null)
252 {
253 FacesServletMapping facesExtensionMapping = null;
254 FacesServletMapping facesPrefixMapping = null;
255 FacesServletMapping facesExactMapping = null;
256
257 for (ServletRegistrationInfo servletRegistration : servletRegistrations)
258 {
259 try
260 {
261 if (servletRegistration.isFacesServlet())
262 {
263 for (String mapping : servletRegistration.getMappings())
264 {
265 if (isExtensionMapping(mapping))
266 {
267 facesExtensionMapping = FacesServletMapping.createExtensionMapping(
268 extractExtension(mapping));
269 }
270 else if (isPrefixMapping(mapping))
271 {
272 facesPrefixMapping = FacesServletMapping.createPrefixMapping(
273 extractPrefix(mapping));
274 }
275 else if (allowExactMatch && mapping.startsWith("/") && mapping.equals(servletPath))
276 {
277 facesExactMapping = FacesServletMapping.createExactMapping(servletPath);
278 }
279 }
280 }
281 else
282 {
283
284
285
286 for (String mapping : servletRegistration.getMappings())
287 {
288 if (mapping.startsWith("/") && mapping.endsWith("/*"))
289 {
290 mapping = mapping.substring(0, mapping.length()-2);
291 }
292 if (mapping.equals(servletPath))
293 {
294 return FacesServletMapping.createPrefixMapping(mapping);
295 }
296 }
297 }
298 }
299 catch (Exception ex)
300 {
301
302 }
303 }
304
305
306 if (allowExactMatch && facesExactMapping != null)
307 {
308 return facesExactMapping;
309 }
310 else if (facesPrefixMapping != null)
311 {
312 return facesPrefixMapping;
313 }
314 else if (facesExtensionMapping != null)
315 {
316 return facesExtensionMapping;
317 }
318 else
319 {
320 return FacesServletMapping.createPrefixMapping(servletPath);
321 }
322 }
323 else
324 {
325 return FacesServletMapping.createPrefixMapping(servletPath);
326 }
327 }
328 catch(Exception ex)
329 {
330 return FacesServletMapping.createPrefixMapping(servletPath);
331 }
332 }
333
334
335
336
337
338
339
340
341
342
343 private static FacesServletMapping calculateFacesServletMapping(String servletPath, String pathInfo)
344 {
345 if (pathInfo != null)
346 {
347
348
349
350
351
352
353 return FacesServletMapping.createPrefixMapping(servletPath);
354 }
355 else
356 {
357
358
359
360
361
362 String extension = extractExtensionFromUrl(servletPath);
363 if (extension != null)
364 {
365 return FacesServletMapping.createExtensionMapping(extension);
366 }
367 else
368 {
369
370
371 return FacesServletMapping.createExactMapping(servletPath);
372 }
373 }
374 }
375
376 public static FacesServletMapping getExactMapping(FacesContext facesContext, String prefixedExactMappingViewId)
377 {
378 if (!ExternalContextUtils.isPortlet(facesContext.getExternalContext()))
379 {
380 Object context = facesContext.getExternalContext().getContext();
381 if (context instanceof ServletContext)
382 {
383 ServletRegistrationInfo facesServletRegistration =
384 getFacesServletRegistration(facesContext, (ServletContext) context, true);
385 if (facesServletRegistration != null)
386 {
387 for (String mapping : facesServletRegistration.getMappings())
388 {
389 if (!mapping.contains("*") && prefixedExactMappingViewId.equals(mapping))
390 {
391 return FacesServletMapping.createExactMapping(prefixedExactMappingViewId);
392 }
393 }
394 }
395 }
396 }
397
398 return null;
399 }
400
401
402 public static FacesServletMapping getGenericPrefixOrSuffixMapping(FacesContext facesContext)
403 {
404 if (!ExternalContextUtils.isPortlet(facesContext.getExternalContext()))
405 {
406 Object context = facesContext.getExternalContext().getContext();
407 if (context instanceof ServletContext)
408 {
409 ServletRegistrationInfo facesServletRegistration =
410 getFacesServletRegistration(facesContext, (ServletContext) context, true);
411 if (facesServletRegistration != null)
412 {
413 for (String mapping : facesServletRegistration.getMappings())
414 {
415 if (isExtensionMapping(mapping))
416 {
417 String extension = extractExtension(mapping);
418 return FacesServletMapping.createExtensionMapping(extension);
419 }
420 else if (isPrefixMapping(mapping))
421 {
422 String prefix = extractPrefix(mapping);
423 return FacesServletMapping.createPrefixMapping(prefix);
424 }
425 }
426 }
427 }
428 }
429
430 return null;
431 }
432
433
434
435 private static String extractExtensionFromUrl(String url)
436 {
437 int slashPos = url.lastIndexOf('/');
438 int extensionPos = url.lastIndexOf('.');
439 if (extensionPos > -1 && extensionPos > slashPos)
440 {
441 return url.substring(extensionPos);
442 }
443
444 return null;
445 }
446
447 private static boolean isExtensionMapping(String mapping)
448 {
449 return mapping.startsWith("*.");
450 }
451
452 private static String extractExtension(String mapping)
453 {
454 return mapping.substring(1);
455 }
456
457 private static boolean isPrefixMapping(String mapping)
458 {
459 return mapping.startsWith("/") && mapping.endsWith("/*");
460 }
461
462 private static String extractPrefix(String mapping)
463 {
464 return mapping.substring(0, mapping.length() - 2);
465 }
466 }