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