1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.shared.view;
20
21 import java.beans.BeanInfo;
22 import java.io.IOException;
23 import java.io.StringWriter;
24 import java.io.Writer;
25 import java.util.logging.Level;
26 import java.util.logging.Logger;
27
28 import javax.faces.FactoryFinder;
29 import javax.faces.application.Resource;
30 import javax.faces.application.StateManager;
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.context.ResponseWriter;
36 import javax.faces.render.RenderKit;
37 import javax.faces.render.RenderKitFactory;
38 import javax.faces.view.StateManagementStrategy;
39 import javax.faces.view.ViewDeclarationLanguage;
40 import javax.faces.view.ViewMetadata;
41 import javax.servlet.ServletResponse;
42 import javax.servlet.ServletResponseWrapper;
43 import javax.servlet.http.HttpServletResponse;
44
45 import org.apache.myfaces.shared.application.DefaultViewHandlerSupport;
46 import org.apache.myfaces.shared.application.ViewHandlerSupport;
47 import org.apache.myfaces.shared.config.MyfacesConfig;
48 import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
49
50
51 public abstract class JspViewDeclarationLanguageBase extends ViewDeclarationLanguageBase
52 {
53 private static final Logger log = Logger.getLogger(JspViewDeclarationLanguageBase.class.getName());
54
55 private static final String FORM_STATE_MARKER = "<!--@@JSF_FORM_STATE_MARKER@@-->";
56 private static final String AFTER_VIEW_TAG_CONTENT_PARAM = JspViewDeclarationLanguageBase.class
57 + ".AFTER_VIEW_TAG_CONTENT";
58 private static final int FORM_STATE_MARKER_LEN = FORM_STATE_MARKER.length();
59
60 private ViewHandlerSupport _cachedViewHandlerSupport;
61
62 @Override
63 public String getId()
64 {
65 return ViewDeclarationLanguage.JSP_VIEW_DECLARATION_LANGUAGE_ID;
66 }
67
68 @Override
69 public void buildView(FacesContext context, UIViewRoot view) throws IOException
70 {
71
72 setViewBuilt(context, view);
73
74 if (context.getPartialViewContext().isPartialRequest())
75 {
76
77 Object origResponse = context.getExternalContext().getResponse();
78 ResponseSwitch responseSwitch = getResponseSwitch(origResponse);
79 if (responseSwitch == null)
80 {
81
82 responseSwitch = createResponseSwitch(origResponse);
83 if (responseSwitch != null)
84 {
85
86 context.getExternalContext().setResponse(responseSwitch);
87 }
88 }
89 if (responseSwitch != null)
90 {
91
92 responseSwitch.setEnabled(false);
93 }
94 }
95 }
96
97
98
99
100 @Override
101 public BeanInfo getComponentMetadata(FacesContext context, Resource componentResource)
102 {
103 throw new UnsupportedOperationException();
104 }
105
106
107
108 @Override
109 public Resource getScriptComponentResource(FacesContext context, Resource componentResource)
110 {
111 throw new UnsupportedOperationException();
112 }
113
114
115
116 @Override
117 public void renderView(FacesContext context, UIViewRoot view) throws IOException
118 {
119
120
121 checkNull(context, "context");
122 checkNull(view, "view");
123
124
125 if (!view.isRendered())
126 {
127 if (log.isLoggable(Level.FINEST))
128 {
129 log.finest("View is not rendered");
130 }
131 return;
132 }
133
134
135
136
137
138
139 if (!isViewBuilt(context, view))
140 {
141 buildView(context, view);
142 }
143
144 ExternalContext externalContext = context.getExternalContext();
145
146 String viewId = context.getViewRoot().getViewId();
147
148 if (log.isLoggable(Level.FINEST))
149 {
150 log.finest("Rendering JSP view: " + viewId);
151 }
152
153
154
155 if(null != externalContext.getSession(false))
156 {
157 externalContext.getSessionMap().put(ViewHandler.CHARACTER_ENCODING_KEY,
158 externalContext.getResponseCharacterEncoding());
159 }
160
161
162 RenderKitFactory renderFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
163 RenderKit renderKit = renderFactory.getRenderKit(context, view.getRenderKitId());
164
165 ResponseWriter responseWriter = context.getResponseWriter();
166 if (responseWriter == null)
167 {
168 responseWriter = renderKit.createResponseWriter(externalContext.getResponseOutputWriter(),
169 null, externalContext.getRequestCharacterEncoding());
170 context.setResponseWriter(responseWriter);
171 }
172
173
174 Object response = context.getExternalContext().getResponse();
175 ResponseSwitch responseSwitch = getResponseSwitch(response);
176 if (responseSwitch != null)
177 {
178 responseSwitch.setEnabled(true);
179 }
180
181 ResponseWriter oldResponseWriter = responseWriter;
182 StringWriter stateAwareWriter = null;
183
184 StateManager stateManager = context.getApplication().getStateManager();
185 boolean viewStateAlreadyEncoded = isViewStateAlreadyEncoded(context);
186
187 if (!viewStateAlreadyEncoded)
188 {
189
190 stateAwareWriter = new StringWriter();
191
192
193
194
195 responseWriter = oldResponseWriter.cloneWithWriter(stateAwareWriter);
196 context.setResponseWriter(responseWriter);
197 }
198
199 try
200 {
201 if (!actuallyRenderView(context, view))
202 {
203 return;
204 }
205 }
206 finally
207 {
208 if(oldResponseWriter != null)
209 {
210 context.setResponseWriter(oldResponseWriter);
211 }
212 }
213
214 if (!viewStateAlreadyEncoded)
215 {
216
217 flushBufferToWriter(stateAwareWriter.getBuffer(), externalContext.getResponseOutputWriter());
218 }
219 else
220 {
221 stateManager.saveView(context);
222 }
223
224
225 if (responseSwitch != null)
226 {
227 responseSwitch.setEnabled(false);
228 }
229
230
231
232 ViewResponseWrapper afterViewTagResponse = (ViewResponseWrapper) externalContext.getRequestMap()
233 .get(AFTER_VIEW_TAG_CONTENT_PARAM);
234 externalContext.getRequestMap().remove(AFTER_VIEW_TAG_CONTENT_PARAM);
235
236
237 if (afterViewTagResponse != null)
238 {
239 afterViewTagResponse.flushToWriter(externalContext.getResponseOutputWriter(),
240 externalContext.getResponseCharacterEncoding());
241 }
242
243
244 context.getResponseWriter().flush();
245 }
246
247
248
249 @Override
250 public ViewMetadata getViewMetadata(FacesContext context, String viewId)
251 {
252
253
254
255 checkNull(context, "context");
256
257
258
259
260 return null;
261 }
262
263 protected boolean isViewStateAlreadyEncoded(FacesContext context)
264 {
265 if (MyfacesConfig.getCurrentInstance(context.getExternalContext()).isMyfacesImplAvailable())
266 {
267
268 StateManager stateManager = context.getApplication().getStateManager();
269 return !context.getApplication().getStateManager().isSavingStateInClient(context);
270 }
271 else
272 {
273 return false;
274 }
275 }
276
277 protected void setAfterViewTagResponseWrapper(ExternalContext ec, ViewResponseWrapper wrapper)
278 {
279 ec.getRequestMap().put(AFTER_VIEW_TAG_CONTENT_PARAM, wrapper);
280 }
281
282 protected void flushBufferToWriter(StringBuffer buff, Writer writer) throws IOException
283 {
284 FacesContext facesContext = FacesContext.getCurrentInstance();
285 StateManager stateManager = facesContext.getApplication().getStateManager();
286
287 StringWriter stateWriter = new StringWriter();
288 ResponseWriter realWriter = facesContext.getResponseWriter();
289 facesContext.setResponseWriter(realWriter.cloneWithWriter(stateWriter));
290
291 Object serializedView = stateManager.saveView(facesContext);
292
293 stateManager.writeState(facesContext, serializedView);
294 facesContext.setResponseWriter(realWriter);
295
296 String state = stateWriter.getBuffer().toString();
297
298 ExternalContext extContext = facesContext.getExternalContext();
299 if (JavascriptUtils.isJavascriptAllowed(extContext)
300 && MyfacesConfig.getCurrentInstance(extContext).isViewStateJavascript())
301 {
302
303 writePartialBuffer(buff, 0, buff.length(), writer);
304 writer.write(state);
305 }
306 else
307 {
308
309 int lastFormMarkerPos = 0;
310 int formMarkerPos = 0;
311
312 while ((formMarkerPos = buff.indexOf(JspViewDeclarationLanguageBase.FORM_STATE_MARKER, formMarkerPos)) > -1)
313 {
314
315 writePartialBuffer(buff, lastFormMarkerPos, formMarkerPos, writer);
316
317 writer.write(state);
318 formMarkerPos += JspViewDeclarationLanguageBase.FORM_STATE_MARKER_LEN;
319 lastFormMarkerPos = formMarkerPos;
320 }
321
322
323 if (lastFormMarkerPos < buff.length())
324 {
325 writePartialBuffer(buff, lastFormMarkerPos, buff.length(), writer);
326 }
327 }
328 }
329
330 protected void writePartialBuffer(StringBuffer contentBuffer, int beginIndex,
331 int endIndex, Writer writer) throws IOException
332 {
333 int index = beginIndex;
334 int bufferSize = 2048;
335 char[] bufToWrite = new char[bufferSize];
336
337 while (index < endIndex)
338 {
339 int maxSize = Math.min(bufferSize, endIndex - index);
340
341 contentBuffer.getChars(index, index + maxSize, bufToWrite, 0);
342 writer.write(bufToWrite, 0, maxSize);
343
344 index += bufferSize;
345 }
346 }
347
348
349
350
351
352
353 protected boolean actuallyRenderView(FacesContext facesContext, UIViewRoot viewToRender)
354 throws IOException
355 {
356
357 ResponseWriter responseWriter = facesContext.getResponseWriter();
358
359
360
361 responseWriter.startDocument();
362
363
364 viewToRender.encodeAll(facesContext);
365
366
367 responseWriter.endDocument();
368
369 responseWriter.flush();
370
371
372 return true;
373 }
374
375 @Override
376 public StateManagementStrategy getStateManagementStrategy(FacesContext context, String viewId)
377 {
378 return null;
379 }
380
381 @Override
382 protected String calculateViewId(FacesContext context, String viewId)
383 {
384 if (_cachedViewHandlerSupport == null)
385 {
386 _cachedViewHandlerSupport = new DefaultViewHandlerSupport();
387 }
388
389 return _cachedViewHandlerSupport.calculateViewId(context, viewId);
390 }
391
392
393
394
395
396
397
398
399
400
401
402
403 protected boolean isViewBuilt(FacesContext facesContext, UIViewRoot view)
404 {
405 return Boolean.TRUE.equals(facesContext.getAttributes().get(view));
406 }
407
408
409
410
411
412
413
414
415 protected void setViewBuilt(FacesContext facesContext, UIViewRoot view)
416 {
417 facesContext.getAttributes().put(view, Boolean.TRUE);
418 }
419
420
421
422
423
424
425 private static ResponseSwitch getResponseSwitch(Object response)
426 {
427
428 while (response != null)
429 {
430 if (response instanceof ResponseSwitch)
431 {
432
433 return (ResponseSwitch) response;
434 }
435 if (response instanceof ServletResponseWrapper)
436 {
437
438 response = ((ServletResponseWrapper) response).getResponse();
439 }
440
441 break;
442 }
443 return null;
444 }
445
446
447
448
449
450
451
452 private static ResponseSwitch createResponseSwitch(Object response)
453 {
454 if (response instanceof HttpServletResponse)
455 {
456 return new HttpServletResponseSwitch((HttpServletResponse) response);
457 }
458 else if (response instanceof ServletResponse)
459 {
460 return new ServletResponseSwitch((ServletResponse) response);
461 }
462 return null;
463 }
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506 }