1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.context;
21
22 import java.io.IOException;
23 import java.io.Writer;
24 import java.util.ArrayList;
25 import java.util.List;
26
27 import javax.faces.component.UIComponent;
28 import javax.faces.context.PartialResponseWriter;
29 import javax.faces.context.ResponseWriter;
30
31 import org.apache.myfaces.util.CDataEndEscapeFilterWriter;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public class PartialResponseWriterImpl extends PartialResponseWriter
72 {
73
74 class StackEntry
75 {
76 ResponseWriter writer;
77 Writer _doubleBuffer;
78
79 StackEntry(ResponseWriter writer, Writer doubleBuffer)
80 {
81 this.writer = writer;
82 _doubleBuffer = doubleBuffer;
83 }
84
85 public ResponseWriter getWriter()
86 {
87 return writer;
88 }
89
90 public void setWriter(ResponseWriter writer)
91 {
92 this.writer = writer;
93 }
94
95 public Writer getDoubleBuffer()
96 {
97 return _doubleBuffer;
98 }
99
100 public void setDoubleBuffer(Writer doubleBuffer)
101 {
102 _doubleBuffer = doubleBuffer;
103 }
104 }
105
106 ResponseWriter _cdataDoubleBufferWriter = null;
107 Writer _doubleBuffer = null;
108 List<StackEntry> _nestingStack = new ArrayList<StackEntry>(4);
109
110 public PartialResponseWriterImpl(ResponseWriter writer)
111 {
112 super(writer);
113 }
114
115 @Override
116 public void startCDATA() throws IOException
117 {
118 if (!isDoubleBufferEnabled())
119 {
120 super.startCDATA();
121 }
122 else
123 {
124 _cdataDoubleBufferWriter.write("<![CDATA[");
125 }
126 openDoubleBuffer();
127 }
128
129 private void openDoubleBuffer()
130 {
131 _doubleBuffer = new CDataEndEscapeFilterWriter(_cdataDoubleBufferWriter == null ?
132 this.getWrapped() : _cdataDoubleBufferWriter );
133 _cdataDoubleBufferWriter = getWrapped().cloneWithWriter(_doubleBuffer);
134
135 StackEntry entry = new StackEntry(_cdataDoubleBufferWriter, _doubleBuffer);
136
137 _nestingStack.add(0, entry);
138 }
139
140 @Override
141 public void endCDATA() throws IOException
142 {
143 closeDoubleBuffer(false);
144 if (isDoubleBufferEnabled())
145 {
146 _cdataDoubleBufferWriter.write("]]>");
147 }
148 else
149 {
150 super.endCDATA();
151 }
152 }
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167 private void closeDoubleBuffer(boolean force) throws IOException
168 {
169 if (!isDoubleBufferEnabled())
170 {
171 return;
172 }
173
174
175
176
177
178 if (force)
179 {
180 while (!_nestingStack.isEmpty())
181 {
182 popAndEncodeCurrentStackEntry();
183
184 }
185 }
186 else
187 {
188 popAndEncodeCurrentStackEntry();
189 }
190 }
191
192 private void popAndEncodeCurrentStackEntry() throws IOException
193 {
194 StackEntry elem = _nestingStack.remove(0);
195 StackEntry parent = (_nestingStack.isEmpty()) ? null : _nestingStack.get(0);
196 if (parent != null)
197 {
198 _cdataDoubleBufferWriter = parent.getWriter();
199 _doubleBuffer = parent.getDoubleBuffer();
200 }
201 else
202 {
203 _cdataDoubleBufferWriter = null;
204 _doubleBuffer = null;
205 }
206 }
207
208
209
210 @Override
211 public void endInsert() throws IOException
212 {
213
214
215
216
217 closeDoubleBuffer(true);
218 super.endInsert();
219 }
220
221 @Override
222 public void endUpdate() throws IOException
223 {
224
225
226
227
228 closeDoubleBuffer(true);
229 super.endUpdate();
230 }
231
232 @Override
233 public void endExtension() throws IOException
234 {
235
236
237
238
239 closeDoubleBuffer(true);
240 super.endExtension();
241 }
242
243 @Override
244 public void endEval() throws IOException
245 {
246
247
248
249
250 closeDoubleBuffer(true);
251 super.endEval();
252 }
253
254 @Override
255 public void endError() throws IOException
256 {
257
258
259
260
261 closeDoubleBuffer(true);
262 super.endError();
263 }
264
265
266
267 @Override
268 public void endElement(String name) throws IOException
269 {
270 if (isDoubleBufferEnabled())
271 {
272 _cdataDoubleBufferWriter.endElement(name);
273 }
274 else
275 {
276 super.endElement(name);
277 }
278 }
279
280 @Override
281 public void writeComment(Object comment) throws IOException
282 {
283 if (isDoubleBufferEnabled())
284 {
285 _cdataDoubleBufferWriter.writeComment(comment);
286 }
287 else
288 {
289 super.writeComment(comment);
290 }
291 }
292
293 private boolean isDoubleBufferEnabled()
294 {
295 return !_nestingStack.isEmpty();
296 }
297
298 @Override
299 public void startElement(String name, UIComponent component) throws IOException
300 {
301 if (isDoubleBufferEnabled())
302 {
303 _cdataDoubleBufferWriter.startElement(name, component);
304 }
305 else
306 {
307 super.startElement(name, component);
308 }
309 }
310
311 @Override
312 public void writeText(Object text, String property) throws IOException
313 {
314 if (isDoubleBufferEnabled())
315 {
316 _cdataDoubleBufferWriter.writeText(text, property);
317 }
318 else
319 {
320 super.writeText(text, property);
321 }
322 }
323
324 @Override
325 public void writeText(char[] text, int off, int len) throws IOException
326 {
327 if (isDoubleBufferEnabled())
328 {
329 _cdataDoubleBufferWriter.writeText(text, off, len);
330 }
331 else
332 {
333 super.writeText(text, off, len);
334 }
335 }
336
337 @Override
338 public void write(char[] cbuf, int off, int len) throws IOException
339 {
340 if (isDoubleBufferEnabled())
341 {
342 _cdataDoubleBufferWriter.write(cbuf, off, len);
343 }
344 else
345 {
346 super.write(cbuf, off, len);
347 }
348 }
349
350 @Override
351 public ResponseWriter cloneWithWriter(Writer writer)
352 {
353 return super.cloneWithWriter(writer);
354 }
355
356 @Override
357 public void writeURIAttribute(String name, Object value, String property) throws IOException
358 {
359 if (isDoubleBufferEnabled())
360 {
361 _cdataDoubleBufferWriter.writeURIAttribute(name, value, property);
362 }
363 else
364 {
365 super.writeURIAttribute(name, value, property);
366 }
367 }
368
369 @Override
370 public void close() throws IOException
371 {
372
373
374
375
376
377 if (isDoubleBufferEnabled())
378 {
379
380
381 closeDoubleBuffer(true);
382
383 super.endCDATA();
384 }
385 super.close();
386 }
387
388 @Override
389 public void flush() throws IOException
390 {
391 if (isDoubleBufferEnabled())
392 {
393 _cdataDoubleBufferWriter.flush();
394 }
395 super.flush();
396 }
397
398 @Override
399 public void writeAttribute(String name, Object value, String property) throws IOException
400 {
401 if (isDoubleBufferEnabled())
402 {
403 _cdataDoubleBufferWriter.writeAttribute(name, value, property);
404 }
405 else
406 {
407 super.writeAttribute(name, value, property);
408 }
409 }
410
411 @Override
412 public void writeText(Object object, UIComponent component, String string) throws IOException
413 {
414 if (isDoubleBufferEnabled())
415 {
416 _cdataDoubleBufferWriter.writeText(object, component, string);
417 }
418 else
419 {
420 super.writeText(object, component, string);
421 }
422 }
423
424 @Override
425 public Writer append(char c) throws IOException
426 {
427 if (isDoubleBufferEnabled())
428 {
429 _cdataDoubleBufferWriter.append(c);
430 return this;
431 }
432 else
433 {
434 return super.append(c);
435 }
436 }
437
438 @Override
439 public Writer append(CharSequence csq, int start, int end) throws IOException
440 {
441 if (isDoubleBufferEnabled())
442 {
443 _cdataDoubleBufferWriter.append(csq, start, end);
444 return this;
445 }
446 else
447 {
448 return super.append(csq, start, end);
449 }
450 }
451
452 @Override
453 public Writer append(CharSequence csq) throws IOException
454 {
455 if (isDoubleBufferEnabled())
456 {
457 _cdataDoubleBufferWriter.append(csq);
458 return this;
459 }
460 else
461 {
462 return super.append(csq);
463 }
464 }
465
466 @Override
467 public void write(char[] cbuf) throws IOException
468 {
469 if (isDoubleBufferEnabled())
470 {
471 _cdataDoubleBufferWriter.write(cbuf);
472 }
473 else
474 {
475 super.write(cbuf);
476 }
477 }
478
479 @Override
480 public void write(int c) throws IOException
481 {
482 if (isDoubleBufferEnabled())
483 {
484 _cdataDoubleBufferWriter.write(c);
485 }
486 else
487 {
488 super.write(c);
489 }
490 }
491
492 @Override
493 public void write(String str, int off, int len) throws IOException
494 {
495 if (isDoubleBufferEnabled())
496 {
497 _cdataDoubleBufferWriter.write(str, off, len);
498 }
499 else
500 {
501 super.write(str, off, len);
502 }
503 }
504
505 @Override
506 public void write(String str) throws IOException
507 {
508 if (isDoubleBufferEnabled())
509 {
510 _cdataDoubleBufferWriter.write(str);
511 }
512 else
513 {
514 super.write(str);
515 }
516 }
517 }