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