1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.application.jsp;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.myfaces.portlet.MyFacesGenericPortlet;
24 import org.apache.myfaces.portlet.PortletUtil;
25 import org.apache.myfaces.util.DebugUtils;
26 import org.apache.myfaces.shared_impl.webapp.webxml.ServletMapping;
27 import org.apache.myfaces.shared_impl.webapp.webxml.WebXml;
28
29 import javax.faces.FacesException;
30 import javax.faces.application.Application;
31 import javax.faces.application.ViewHandler;
32 import javax.faces.component.UIViewRoot;
33 import javax.faces.context.ExternalContext;
34 import javax.faces.context.FacesContext;
35 import javax.faces.render.RenderKitFactory;
36 import javax.portlet.PortletURL;
37 import javax.portlet.RenderResponse;
38 import javax.servlet.ServletResponse;
39 import javax.servlet.http.HttpServletRequest;
40 import javax.servlet.http.HttpServletResponse;
41 import javax.servlet.http.HttpSession;
42 import java.io.IOException;
43 import java.util.Iterator;
44 import java.util.List;
45 import java.util.Locale;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 public class JspViewHandlerImpl
82 extends ViewHandler {
83 private static final Log log = LogFactory.getLog(JspViewHandlerImpl.class);
84 public static final String FORM_STATE_MARKER = "<!--@@JSF_FORM_STATE_MARKER@@-->";
85 public static final int FORM_STATE_MARKER_LEN = FORM_STATE_MARKER.length();
86
87
88 public JspViewHandlerImpl() {
89 if (log.isTraceEnabled()) log.trace("New ViewHandler instance created");
90 }
91
92
93
94
95
96 public Locale calculateLocale(FacesContext facesContext) {
97 Iterator locales = facesContext.getExternalContext().getRequestLocales();
98 while (locales.hasNext()) {
99 Locale locale = (Locale) locales.next();
100 for (Iterator it = facesContext.getApplication().getSupportedLocales(); it.hasNext();) {
101 Locale supportLocale = (Locale) it.next();
102
103
104 if (locale.getLanguage().equals(supportLocale.getLanguage()) &&
105 (supportLocale.getCountry() == null ||
106 supportLocale.getCountry().length() == 0)) {
107 return supportLocale;
108 }
109 else if (supportLocale.equals(locale)) {
110 return supportLocale;
111 }
112 }
113 }
114
115 Locale defaultLocale = facesContext.getApplication().getDefaultLocale();
116 return defaultLocale != null ? defaultLocale : Locale.getDefault();
117 }
118
119 public String calculateRenderKitId(FacesContext facesContext) {
120 String renderKitId = facesContext.getApplication().getDefaultRenderKitId();
121 return (renderKitId != null) ? renderKitId : RenderKitFactory.HTML_BASIC_RENDER_KIT;
122
123 }
124
125
126
127
128
129
130
131
132
133 public UIViewRoot createView(FacesContext facesContext, String viewId) {
134 Application application = facesContext.getApplication();
135 ViewHandler applicationViewHandler = application.getViewHandler();
136
137 Locale currentLocale = null;
138 String currentRenderKitId = null;
139 UIViewRoot uiViewRoot = facesContext.getViewRoot();
140 if (uiViewRoot != null) {
141
142 currentLocale = uiViewRoot.getLocale();
143 currentRenderKitId = uiViewRoot.getRenderKitId();
144 }
145
146 uiViewRoot = (UIViewRoot) application.createComponent(UIViewRoot.COMPONENT_TYPE);
147
148
149
150
151
152
153 uiViewRoot.setViewId(viewId);
154
155 if (currentLocale != null) {
156
157 uiViewRoot.setLocale(currentLocale);
158 }
159 else {
160
161 uiViewRoot.setLocale(applicationViewHandler.calculateLocale(facesContext));
162 }
163
164 if (currentRenderKitId != null) {
165
166 uiViewRoot.setRenderKitId(currentRenderKitId);
167 }
168 else {
169
170 uiViewRoot.setRenderKitId(applicationViewHandler.calculateRenderKitId(facesContext));
171 }
172
173 if (log.isTraceEnabled()) log.trace("Created view " + viewId);
174 return uiViewRoot;
175 }
176
177 public String getActionURL(FacesContext facesContext, String viewId) {
178 if (PortletUtil.isRenderResponse(facesContext)) {
179 RenderResponse response = (RenderResponse) facesContext.getExternalContext().getResponse();
180 PortletURL url = response.createActionURL();
181 url.setParameter(MyFacesGenericPortlet.VIEW_ID, viewId);
182 return url.toString();
183 }
184
185 String path = getViewIdPath(facesContext, viewId);
186 if (path.length() > 0 && path.charAt(0) == '/') {
187 return facesContext.getExternalContext().getRequestContextPath() + path;
188 }
189 else {
190 return path;
191 }
192 }
193
194 public String getResourceURL(FacesContext facesContext, String path) {
195 if (path.length() > 0 && path.charAt(0) == '/') {
196 return facesContext.getExternalContext().getRequestContextPath() + path;
197 }
198 else {
199 return path;
200 }
201 }
202
203
204
205
206 public void renderView(FacesContext facesContext, UIViewRoot viewToRender)
207 throws IOException, FacesException {
208 if (viewToRender == null) {
209 log.fatal("viewToRender must not be null");
210 throw new NullPointerException("viewToRender must not be null");
211 }
212
213 ExternalContext externalContext = facesContext.getExternalContext();
214
215 String viewId = facesContext.getViewRoot().getViewId();
216
217 if (PortletUtil.isPortletRequest(facesContext)) {
218 externalContext.dispatch(viewId);
219 return;
220 }
221
222 ServletMapping servletMapping = getServletMapping(externalContext);
223
224 if (servletMapping != null && servletMapping.isExtensionMapping()) {
225 String defaultSuffix = externalContext.getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME);
226 String suffix = defaultSuffix != null ? defaultSuffix : ViewHandler.DEFAULT_SUFFIX;
227 DebugUtils.assertError(suffix.charAt(0) == '.',
228 log, "Default suffix must start with a dot!");
229 if (!viewId.endsWith(suffix)) {
230 int slashPos = viewId.lastIndexOf('/');
231 int extensionPos = viewId.lastIndexOf('.');
232 if (extensionPos == -1 || extensionPos <= slashPos) {
233 if (log.isTraceEnabled())
234 log.trace("Current viewId has no extension, appending default suffix " + suffix);
235 viewId = viewId + suffix;
236 }
237 else {
238 if (log.isTraceEnabled()) log.trace("Replacing extension of current viewId by suffix " + suffix);
239 viewId = viewId.substring(0, extensionPos) + suffix;
240 }
241 facesContext.getViewRoot().setViewId(viewId);
242 }
243 }
244
245 if (log.isTraceEnabled()) log.trace("Dispatching to " + viewId);
246
247
248 if (externalContext.getResponse() instanceof ServletResponse) {
249 ServletResponse response = (ServletResponse) externalContext.getResponse();
250 response.setLocale(viewToRender.getLocale());
251 }
252
253
254
255 externalContext.dispatch(viewId);
256
257
258 if (externalContext.getRequest() instanceof HttpServletRequest) {
259 HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
260 HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
261 HttpSession session = request.getSession(false);
262
263 if (session != null) {
264 session.setAttribute(ViewHandler.CHARACTER_ENCODING_KEY, response.getCharacterEncoding());
265 }
266 }
267
268 }
269
270
271
272
273
274 public UIViewRoot restoreView(FacesContext facesContext, String viewId) {
275 Application application = facesContext.getApplication();
276 ViewHandler applicationViewHandler = application.getViewHandler();
277 String renderKitId = applicationViewHandler.calculateRenderKitId(facesContext);
278 UIViewRoot viewRoot = application.getStateManager().restoreView(facesContext,
279 viewId,
280 renderKitId);
281 return viewRoot;
282 }
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318 public void writeState(FacesContext facesContext) throws IOException {
319 facesContext.getResponseWriter().write(FORM_STATE_MARKER);
320 }
321
322
323 protected String getViewIdPath(FacesContext facescontext, String viewId) {
324 if (viewId == null) {
325 log.error("ViewId must not be null");
326 throw new NullPointerException("ViewId must not be null");
327 }
328 if (!viewId.startsWith("/")) {
329 log.error("ViewId must start with '/' (viewId = " + viewId + ")");
330 throw new IllegalArgumentException("ViewId must start with '/' (viewId = " + viewId + ")");
331 }
332
333 if (PortletUtil.isPortletRequest(facescontext)) {
334 return viewId;
335 }
336
337 ServletMapping servletMapping = getServletMapping(facescontext.getExternalContext());
338
339 if (servletMapping != null) {
340 if (servletMapping.isExtensionMapping()) {
341
342 String urlpattern = servletMapping.getUrlPattern();
343 if (urlpattern.startsWith("*")) {
344 urlpattern = urlpattern.substring(1, urlpattern.length());
345 }
346 if (viewId.endsWith(urlpattern)) {
347 return viewId;
348 }
349 else {
350 int slashPos = viewId.lastIndexOf('/');
351 int extensionPos = viewId.lastIndexOf('.');
352
353 if (extensionPos == -1 || extensionPos <= slashPos) {
354 return viewId + urlpattern;
355 }
356 else {
357 return viewId.substring(0, extensionPos) + urlpattern;
358 }
359
360 }
361 }
362 else {
363
364 String urlpattern = servletMapping.getUrlPattern();
365 if (urlpattern.endsWith("/*")) {
366 urlpattern = urlpattern.substring(0, urlpattern.length() - 2);
367 }
368 return urlpattern + viewId;
369 }
370 }
371 else {
372 return viewId;
373 }
374 }
375
376 private static ServletMapping getServletMapping(ExternalContext externalContext) {
377 String servletPath = externalContext.getRequestServletPath();
378 String requestPathInfo = externalContext.getRequestPathInfo();
379
380 WebXml webxml = WebXml.getWebXml(externalContext);
381 List mappings = webxml.getFacesServletMappings();
382
383
384 if (requestPathInfo == null) {
385
386 for (int i = 0, size = mappings.size(); i < size; i++) {
387 ServletMapping servletMapping = (ServletMapping) mappings.get(i);
388 String urlpattern = servletMapping.getUrlPattern();
389 String extension = urlpattern.substring(1, urlpattern.length());
390 if (servletPath.endsWith(extension)) {
391 return servletMapping;
392 }
393 else if (servletPath.equals(urlpattern)) {
394
395 return servletMapping;
396 }
397 }
398 }
399 else {
400
401 for (int i = 0, size = mappings.size(); i < size; i++) {
402
403 ServletMapping servletMapping = (ServletMapping) mappings.get(i);
404 String urlpattern = servletMapping.getUrlPattern();
405 urlpattern = urlpattern.substring(0, urlpattern.length() - 2);
406
407
408
409 if (servletPath.equals(urlpattern)) {
410 return servletMapping;
411 }
412 }
413 }
414
415
416
417 if (mappings.size() > 0) {
418 return (ServletMapping) mappings.get(0);
419 }
420 else {
421 log.warn("no faces servlet mappings found");
422 return null;
423 }
424 }
425
426
427 }