1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.application;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Locale;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.concurrent.ConcurrentHashMap;
32 import java.util.logging.Level;
33 import java.util.logging.Logger;
34
35 import javax.faces.FacesException;
36 import javax.faces.FactoryFinder;
37 import javax.faces.application.Application;
38 import javax.faces.application.StateManager;
39 import javax.faces.application.ViewHandler;
40 import javax.faces.component.UIViewParameter;
41 import javax.faces.component.UIViewRoot;
42 import javax.faces.context.ExternalContext;
43 import javax.faces.context.FacesContext;
44 import javax.faces.render.RenderKitFactory;
45 import javax.faces.render.ResponseStateManager;
46 import javax.faces.view.ViewDeclarationLanguage;
47 import javax.faces.view.ViewDeclarationLanguageFactory;
48 import javax.faces.view.ViewMetadata;
49 import javax.servlet.http.HttpServletResponse;
50
51 import org.apache.myfaces.application.viewstate.StateCacheUtils;
52 import org.apache.myfaces.shared.application.DefaultViewHandlerSupport;
53 import org.apache.myfaces.shared.application.InvalidViewIdException;
54 import org.apache.myfaces.shared.application.ViewHandlerSupport;
55 import org.apache.myfaces.view.facelets.StateWriter;
56
57
58
59
60
61
62 public class ViewHandlerImpl extends ViewHandler
63 {
64
65 private static final Logger log = Logger.getLogger(ViewHandlerImpl.class.getName());
66 public static final String FORM_STATE_MARKER = "<!--@@JSF_FORM_STATE_MARKER@@-->";
67 private ViewHandlerSupport _viewHandlerSupport;
68 private ViewDeclarationLanguageFactory _vdlFactory;
69
70 private Set<String> _protectedViewsSet;
71 private Set<String> _unmodifiableProtectedViewsSet;
72
73
74
75
76
77
78
79
80
81 public static ViewHandler getViewHandler(FacesContext facesContext)
82 {
83 return facesContext.getApplication().getViewHandler();
84 }
85
86 public ViewHandlerImpl()
87 {
88 _protectedViewsSet = Collections.newSetFromMap(new ConcurrentHashMap<String,Boolean>());
89 _unmodifiableProtectedViewsSet = Collections.unmodifiableSet(_protectedViewsSet);
90 _vdlFactory = (ViewDeclarationLanguageFactory)
91 FactoryFinder.getFactory(FactoryFinder.VIEW_DECLARATION_LANGUAGE_FACTORY);
92 if (log.isLoggable(Level.FINEST))
93 {
94 log.finest("New ViewHandler instance created");
95 }
96 }
97
98 @Override
99 public String deriveViewId(FacesContext context, String input)
100 {
101 if(input != null)
102 {
103 try
104 {
105 return getViewHandlerSupport(context).calculateAndCheckViewId(context, input);
106 }
107 catch (InvalidViewIdException e)
108 {
109 sendSourceNotFound(context, e.getMessage());
110 }
111 }
112 return input;
113 }
114
115 @Override
116 public String deriveLogicalViewId(FacesContext context, String rawViewId)
117 {
118 if(rawViewId != null)
119 {
120 try
121 {
122 return getViewHandlerSupport(context).calculateViewId(context, rawViewId);
123 }
124 catch (InvalidViewIdException e)
125 {
126 sendSourceNotFound(context, e.getMessage());
127 }
128 }
129 return rawViewId;
130 }
131
132 @Override
133 public String getBookmarkableURL(FacesContext context, String viewId,
134 Map<String, List<String>> parameters, boolean includeViewParams)
135 {
136 Map<String, List<String>> viewParameters;
137 if (includeViewParams)
138 {
139 viewParameters = getViewParameterList(context, viewId, parameters);
140 }
141 else
142 {
143 viewParameters = parameters;
144 }
145
146
147
148 String actionEncodedViewId = getViewHandler(context).getActionURL(context, viewId);
149
150 ExternalContext externalContext = context.getExternalContext();
151 String bookmarkEncodedURL = externalContext.encodeBookmarkableURL(actionEncodedViewId, viewParameters);
152 return externalContext.encodeActionURL(bookmarkEncodedURL);
153 }
154
155 @Override
156 public String getRedirectURL(FacesContext context, String viewId,
157 Map<String, List<String>> parameters, boolean includeViewParams)
158 {
159 Map<String, List<String>> viewParameters;
160 if (includeViewParams)
161 {
162 viewParameters = getViewParameterList(context, viewId, parameters);
163 }
164 else
165 {
166 viewParameters = parameters;
167 }
168
169
170
171 String actionEncodedViewId = getViewHandler(context).getActionURL(context, viewId);
172
173 ExternalContext externalContext = context.getExternalContext();
174 String redirectEncodedURL = externalContext.encodeRedirectURL(actionEncodedViewId, viewParameters);
175 return externalContext.encodeActionURL(redirectEncodedURL);
176 }
177
178 @Override
179 public ViewDeclarationLanguage getViewDeclarationLanguage(
180 FacesContext context, String viewId)
181 {
182
183 return _vdlFactory.getViewDeclarationLanguage(viewId);
184 }
185
186 @Override
187 public void initView(FacesContext context) throws FacesException
188 {
189 if(context.getExternalContext().getRequestCharacterEncoding() == null)
190 {
191 super.initView(context);
192 }
193 }
194
195
196
197
198
199 @Override
200 public Locale calculateLocale(FacesContext facesContext)
201 {
202 Application application = facesContext.getApplication();
203 for (Iterator<Locale> requestLocales = facesContext.getExternalContext().getRequestLocales(); requestLocales
204 .hasNext();)
205 {
206 Locale requestLocale = requestLocales.next();
207 for (Iterator<Locale> supportedLocales = application.getSupportedLocales(); supportedLocales.hasNext();)
208 {
209 Locale supportedLocale = supportedLocales.next();
210
211
212 if (requestLocale.getLanguage().equals(supportedLocale.getLanguage())
213 && (supportedLocale.getCountry() == null || supportedLocale.getCountry().length() == 0))
214 {
215 return supportedLocale;
216 }
217 else if (supportedLocale.equals(requestLocale))
218 {
219 return supportedLocale;
220 }
221 }
222 }
223
224 Locale defaultLocale = application.getDefaultLocale();
225 return defaultLocale != null ? defaultLocale : Locale.getDefault();
226 }
227
228 @Override
229 public String calculateRenderKitId(FacesContext facesContext)
230 {
231 Object renderKitId = facesContext.getExternalContext().getRequestMap().get(
232 ResponseStateManager.RENDER_KIT_ID_PARAM);
233 if (renderKitId == null)
234 {
235 renderKitId = facesContext.getApplication().getDefaultRenderKitId();
236 }
237 if (renderKitId == null)
238 {
239 renderKitId = RenderKitFactory.HTML_BASIC_RENDER_KIT;
240 }
241 return renderKitId.toString();
242 }
243
244 @Override
245 public UIViewRoot createView(FacesContext context, String viewId)
246 {
247 checkNull(context, "facesContext");
248 String calculatedViewId = getViewHandlerSupport(context).calculateViewId(context, viewId);
249
250
251
252
253
254
255 ViewDeclarationLanguage vdl = getViewDeclarationLanguage(context,calculatedViewId);
256 if (vdl == null)
257 {
258
259 sendSourceNotFound(context, viewId);
260 return null;
261 }
262 return vdl.createView(context,calculatedViewId);
263 }
264
265 @Override
266 public String getActionURL(FacesContext context, String viewId)
267 {
268 checkNull(context, "facesContext");
269 checkNull(viewId, "viewId");
270 return getViewHandlerSupport(context).calculateActionURL(context, viewId);
271 }
272
273 @Override
274 public String getResourceURL(FacesContext facesContext, String path)
275 {
276 checkNull(facesContext, "facesContext");
277 checkNull(path, "path");
278 if (path.length() > 0 && path.charAt(0) == '/')
279 {
280 String contextPath = facesContext.getExternalContext().getRequestContextPath();
281 if (contextPath == null)
282 {
283 return path;
284 }
285 else if (contextPath.length() == 1 && contextPath.charAt(0) == '/')
286 {
287
288
289 return path;
290 }
291 else
292 {
293 return contextPath + path;
294 }
295 }
296 return path;
297
298 }
299
300 @Override
301 public void renderView(FacesContext context, UIViewRoot viewToRender)
302 throws IOException, FacesException
303 {
304
305 checkNull(context, "context");
306 checkNull(viewToRender, "viewToRender");
307
308
309
310
311
312
313 getViewDeclarationLanguage(context,viewToRender.getViewId()).renderView(context, viewToRender);
314 }
315
316 @Override
317 public UIViewRoot restoreView(FacesContext context, String viewId)
318 {
319 checkNull(context, "context");
320
321 String calculatedViewId = getViewHandlerSupport(context).calculateViewId(context, viewId);
322
323
324
325
326
327
328 ViewDeclarationLanguage vdl = getViewDeclarationLanguage(context,calculatedViewId);
329 if (vdl == null)
330 {
331
332 sendSourceNotFound(context, viewId);
333 return null;
334
335 }
336 return vdl.restoreView(context, calculatedViewId);
337 }
338
339 @Override
340 public void writeState(FacesContext context) throws IOException
341 {
342 checkNull(context, "context");
343
344 if(context.getPartialViewContext().isAjaxRequest())
345 {
346 return;
347 }
348
349 ResponseStateManager responseStateManager = context.getRenderKit().getResponseStateManager();
350
351 setWritingState(context, responseStateManager);
352
353 StateManager stateManager = context.getApplication().getStateManager();
354
355
356
357
358
359
360
361
362 if (StateCacheUtils.isMyFacesResponseStateManager(responseStateManager))
363 {
364 if (StateCacheUtils.getMyFacesResponseStateManager(responseStateManager).
365 isWriteStateAfterRenderViewRequired(context))
366 {
367
368 context.getResponseWriter().write(FORM_STATE_MARKER);
369 }
370 else
371 {
372 stateManager.writeState(context, new Object[2]);
373 }
374 }
375 else
376 {
377
378 context.getResponseWriter().write(FORM_STATE_MARKER);
379 }
380 }
381
382 @Override
383 public void addProtectedView(String urlPattern)
384 {
385 _protectedViewsSet.add(urlPattern);
386 }
387
388 @Override
389 public boolean removeProtectedView(String urlPattern)
390 {
391 return _protectedViewsSet.remove(urlPattern);
392 }
393
394 @Override
395 public Set<String> getProtectedViewsUnmodifiable()
396 {
397 return _unmodifiableProtectedViewsSet;
398 }
399
400 private void setWritingState(FacesContext context, ResponseStateManager rsm)
401 {
402
403
404 StateWriter stateWriter = StateWriter.getCurrentInstance(context);
405 if (stateWriter != null)
406 {
407
408
409
410
411
412
413 if (StateCacheUtils.isMyFacesResponseStateManager(rsm))
414 {
415 if (StateCacheUtils.getMyFacesResponseStateManager(rsm).isWriteStateAfterRenderViewRequired(context))
416 {
417 stateWriter.writingState();
418 }
419 else
420 {
421 stateWriter.writingStateWithoutWrapper();
422 }
423 }
424 else
425 {
426 stateWriter.writingState();
427 }
428
429
430 }
431
432
433
434
435 }
436
437 private Map<String, List<String>> getViewParameterList(FacesContext context,
438 String viewId, Map<String, List<String>> parametersFromArg)
439 {
440 UIViewRoot viewRoot = context.getViewRoot();
441 String currentViewId = viewRoot.getViewId();
442 Collection<UIViewParameter> toViewParams = null;
443 Collection<UIViewParameter> currentViewParams = ViewMetadata.getViewParameters(viewRoot);
444
445 if (currentViewId.equals(viewId))
446 {
447 toViewParams = currentViewParams;
448 }
449 else
450 {
451 String calculatedViewId = getViewHandlerSupport(context).calculateViewId(context, viewId);
452
453
454
455
456 ViewDeclarationLanguage vdl = getViewDeclarationLanguage(context,calculatedViewId);
457 ViewMetadata viewMetadata = vdl.getViewMetadata(context, viewId);
458
459 if (viewMetadata != null)
460 {
461 UIViewRoot viewFromMetaData = viewMetadata.createMetadataView(context);
462 toViewParams = ViewMetadata.getViewParameters(viewFromMetaData);
463 }
464 }
465
466 if (toViewParams == null || toViewParams.isEmpty())
467 {
468 return parametersFromArg;
469 }
470
471
472
473
474
475
476
477 Map<String, List<String>> parameters = new HashMap<String, List<String>>();
478 parameters.putAll(parametersFromArg);
479
480 for (UIViewParameter viewParameter : toViewParams)
481 {
482 if (!parameters.containsKey(viewParameter.getName()))
483 {
484 String parameterValue = viewParameter.getStringValueFromModel(context);
485 if (parameterValue == null)
486 {
487 if(currentViewId.equals(viewId))
488 {
489 parameterValue = viewParameter.getStringValue(context);
490 }
491 else
492 {
493 if (viewParameter.getName() != null)
494 {
495 for (UIViewParameter curParam : currentViewParams)
496 {
497 if (viewParameter.getName().equals(curParam.getName()))
498 {
499 parameterValue = curParam.getStringValue(context);
500 break;
501 }
502 }
503 }
504 }
505 }
506
507 if (parameterValue != null)
508 {
509
510
511
512 List<String> parameterValueList = new ArrayList<String>();
513 parameterValueList.add(parameterValue);
514 parameters.put(viewParameter.getName(), parameterValueList);
515 }
516 }
517 }
518 return parameters;
519 }
520
521 private void checkNull(final Object o, final String param)
522 {
523 if (o == null)
524 {
525 throw new NullPointerException(param + " can not be null.");
526 }
527 }
528
529 private void sendSourceNotFound(FacesContext context, String message)
530 {
531 HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
532 try
533 {
534 context.responseComplete();
535 response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
536 }
537 catch (IOException ioe)
538 {
539 throw new FacesException(ioe);
540 }
541 }
542
543 public void setViewHandlerSupport(ViewHandlerSupport viewHandlerSupport)
544 {
545 _viewHandlerSupport = viewHandlerSupport;
546 }
547
548 protected ViewHandlerSupport getViewHandlerSupport()
549 {
550 return getViewHandlerSupport(FacesContext.getCurrentInstance());
551 }
552
553 protected ViewHandlerSupport getViewHandlerSupport(FacesContext context)
554 {
555 if (_viewHandlerSupport == null)
556 {
557 _viewHandlerSupport = new DefaultViewHandlerSupport(context);
558 }
559 return _viewHandlerSupport;
560 }
561 }