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