1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.shared.renderkit.html;
20
21 import java.io.IOException;
22 import java.io.Writer;
23 import java.nio.charset.Charset;
24 import java.util.logging.Level;
25 import java.util.logging.Logger;
26
27 import javax.faces.FacesException;
28 import javax.faces.component.UIComponent;
29 import javax.faces.context.ResponseWriter;
30
31 import org.apache.myfaces.shared.renderkit.ContentTypeUtils;
32 import org.apache.myfaces.shared.renderkit.RendererUtils;
33 import org.apache.myfaces.shared.renderkit.html.util.UnicodeEncoder;
34 import org.apache.myfaces.shared.util.CommentUtils;
35 import org.apache.myfaces.shared.util.StreamCharBuffer;
36
37
38
39
40
41
42 public class HtmlResponseWriterImpl
43 extends ResponseWriter
44 {
45
46 private static final Logger log = Logger.getLogger(HtmlResponseWriterImpl.class.getName());
47
48 private static final String DEFAULT_CONTENT_TYPE = "text/html";
49 private static final String DEFAULT_CHARACTER_ENCODING = "ISO-8859-1";
50 private static final String UTF8 = "UTF-8";
51
52 private static final String APPLICATION_XML_CONTENT_TYPE = "application/xml";
53 private static final String TEXT_XML_CONTENT_TYPE = "text/xml";
54
55
56
57
58
59
60
61 private Writer _outputWriter;
62
63
64
65
66 private Writer _currentWriter;
67
68
69
70
71 private StreamCharBuffer _buffer;
72
73 private String _contentType;
74
75 private String _writerContentTypeMode;
76
77
78
79
80 private boolean _isXhtmlContentType;
81
82
83
84
85
86 private boolean _useStraightXml;
87
88 private String _characterEncoding;
89 private boolean _wrapScriptContentWithXmlCommentTag;
90 private boolean _isUTF8;
91
92 private String _startElementName;
93 private Boolean _isInsideScript;
94 private Boolean _isStyle;
95 private Boolean _isTextArea;
96 private UIComponent _startElementUIComponent;
97 private boolean _startTagOpen;
98
99 private boolean _cdataOpen;
100
101 private static final String CDATA_START = "<![CDATA[ \n";
102 private static final String CDATA_START_NO_LINE_RETURN = "<![CDATA[";
103 private static final String COMMENT_START = "<!--\n";
104 private static final String CDATA_COMMENT_START = "//<![CDATA[ \n";
105 private static final String CDATA_COMMENT_END = "\n//]]>";
106 private static final String CDATA_END = "\n]]>";
107 private static final String CDATA_END_NO_LINE_RETURN = "]]>";
108 private static final String COMMENT_COMMENT_END = "\n//-->";
109 private static final String COMMENT_END = "\n-->";
110
111 static private final String[][] EMPTY_ELEMENT_ARR = new String[256][];
112
113 static private final String[] A_NAMES = new String[]
114 {
115 "area",
116 };
117
118 static private final String[] B_NAMES = new String[]
119 {
120 "br",
121 "base",
122 "basefont",
123 };
124
125 static private final String[] C_NAMES = new String[]
126 {
127 "col",
128 };
129
130 static private final String[] E_NAMES = new String[]
131 {
132 "embed",
133 };
134
135 static private final String[] F_NAMES = new String[]
136 {
137 "frame",
138 };
139
140 static private final String[] H_NAMES = new String[]
141 {
142 "hr",
143 };
144
145 static private final String[] I_NAMES = new String[]
146 {
147 "img",
148 "input",
149 "isindex",
150 };
151
152 static private final String[] L_NAMES = new String[]
153 {
154 "link",
155 };
156
157 static private final String[] M_NAMES = new String[]
158 {
159 "meta",
160 };
161
162 static private final String[] P_NAMES = new String[]
163 {
164 "param",
165 };
166
167 static
168 {
169 EMPTY_ELEMENT_ARR['a'] = A_NAMES;
170 EMPTY_ELEMENT_ARR['A'] = A_NAMES;
171 EMPTY_ELEMENT_ARR['b'] = B_NAMES;
172 EMPTY_ELEMENT_ARR['B'] = B_NAMES;
173 EMPTY_ELEMENT_ARR['c'] = C_NAMES;
174 EMPTY_ELEMENT_ARR['C'] = C_NAMES;
175 EMPTY_ELEMENT_ARR['e'] = E_NAMES;
176 EMPTY_ELEMENT_ARR['E'] = E_NAMES;
177 EMPTY_ELEMENT_ARR['f'] = F_NAMES;
178 EMPTY_ELEMENT_ARR['F'] = F_NAMES;
179 EMPTY_ELEMENT_ARR['h'] = H_NAMES;
180 EMPTY_ELEMENT_ARR['H'] = H_NAMES;
181 EMPTY_ELEMENT_ARR['i'] = I_NAMES;
182 EMPTY_ELEMENT_ARR['I'] = I_NAMES;
183 EMPTY_ELEMENT_ARR['l'] = L_NAMES;
184 EMPTY_ELEMENT_ARR['L'] = L_NAMES;
185 EMPTY_ELEMENT_ARR['m'] = M_NAMES;
186 EMPTY_ELEMENT_ARR['M'] = M_NAMES;
187 EMPTY_ELEMENT_ARR['p'] = P_NAMES;
188 EMPTY_ELEMENT_ARR['P'] = P_NAMES;
189 }
190
191 public HtmlResponseWriterImpl(Writer writer, String contentType, String characterEncoding)
192 {
193 this(writer,contentType,characterEncoding,true);
194 }
195
196 public HtmlResponseWriterImpl(Writer writer, String contentType, String characterEncoding,
197 boolean wrapScriptContentWithXmlCommentTag)
198 {
199 this(writer,contentType, characterEncoding, wrapScriptContentWithXmlCommentTag,
200 contentType != null && HtmlRendererUtils.isXHTMLContentType(contentType) ?
201 ContentTypeUtils.XHTML_CONTENT_TYPE : ContentTypeUtils.HTML_CONTENT_TYPE);
202 }
203
204 public HtmlResponseWriterImpl(Writer writer, String contentType, String characterEncoding,
205 boolean wrapScriptContentWithXmlCommentTag, String writerContentTypeMode)
206 throws FacesException
207 {
208 _outputWriter = writer;
209
210 _currentWriter = _outputWriter;
211 _wrapScriptContentWithXmlCommentTag = wrapScriptContentWithXmlCommentTag;
212
213 _contentType = contentType;
214 if (_contentType == null)
215 {
216 if (log.isLoggable(Level.FINE))
217 {
218 log.fine("No content type given, using default content type " + DEFAULT_CONTENT_TYPE);
219 }
220 _contentType = DEFAULT_CONTENT_TYPE;
221 }
222 _writerContentTypeMode = writerContentTypeMode;
223 _isXhtmlContentType = writerContentTypeMode.indexOf(ContentTypeUtils.XHTML_CONTENT_TYPE) != -1;
224
225 _useStraightXml = _isXhtmlContentType && (_contentType.indexOf(APPLICATION_XML_CONTENT_TYPE) != -1 ||
226 _contentType.indexOf(TEXT_XML_CONTENT_TYPE) != -1);
227
228 if (characterEncoding == null)
229 {
230 if (log.isLoggable(Level.FINE))
231 {
232 log.fine("No character encoding given, using default character encoding " +
233 DEFAULT_CHARACTER_ENCODING);
234 }
235 _characterEncoding = DEFAULT_CHARACTER_ENCODING;
236 }
237 else
238 {
239
240 _characterEncoding = characterEncoding.toUpperCase();
241
242
243 if (!Charset.isSupported(_characterEncoding))
244 {
245 throw new IllegalArgumentException("Encoding "+_characterEncoding
246 +" not supported by HtmlResponseWriterImpl");
247 }
248 }
249 _isUTF8 = UTF8.equals(_characterEncoding);
250 }
251
252 public static boolean supportsContentType(String contentType)
253 {
254 String[] supportedContentTypes = HtmlRendererUtils.getSupportedContentTypes();
255
256 for (int i = 0; i < supportedContentTypes.length; i++)
257 {
258 String supportedContentType = supportedContentTypes[i];
259
260 if(supportedContentType.indexOf(contentType)!=-1)
261 {
262 return true;
263 }
264 }
265 return false;
266 }
267
268 public String getContentType()
269 {
270 return _contentType;
271 }
272
273 public String getWriterContentTypeMode()
274 {
275 return _writerContentTypeMode;
276 }
277
278 public String getCharacterEncoding()
279 {
280 return _characterEncoding;
281 }
282
283 public void flush() throws IOException
284 {
285
286
287
288 closeStartTagIfNecessary();
289 }
290
291 public void startDocument()
292 {
293
294 }
295
296 public void endDocument() throws IOException
297 {
298 _currentWriter.flush();
299 }
300
301 public void startElement(String name, UIComponent uiComponent) throws IOException
302 {
303 if (name == null)
304 {
305 throw new NullPointerException("elementName name must not be null");
306 }
307
308 closeStartTagIfNecessary();
309 _currentWriter.write('<');
310 _currentWriter.write(name);
311
312 resetStartedElement();
313
314 _startElementName = name;
315 _startElementUIComponent = uiComponent;
316 _startTagOpen = true;
317
318
319
320
321 if(isScript(name))
322 {
323
324 _isInsideScript = Boolean.TRUE;
325 _isStyle = Boolean.FALSE;
326 _isTextArea = Boolean.FALSE;
327 }
328 else if (isStyle(name))
329 {
330 _isInsideScript = Boolean.FALSE;
331 _isStyle = Boolean.TRUE;
332 _isTextArea = Boolean.FALSE;
333 }
334 }
335
336 @Override
337 public void startCDATA() throws IOException
338 {
339 if (!_cdataOpen)
340 {
341 write(CDATA_START_NO_LINE_RETURN);
342 _cdataOpen = true;
343 }
344 }
345
346 @Override
347 public void endCDATA() throws IOException
348 {
349 if (_cdataOpen)
350 {
351 write(CDATA_END_NO_LINE_RETURN);
352 _cdataOpen = false;
353 }
354 }
355
356 private void closeStartTagIfNecessary() throws IOException
357 {
358 if (_startTagOpen)
359 {
360 if (!_useStraightXml && isEmptyElement(_startElementName))
361 {
362 _currentWriter.write(" />");
363
364
365 resetStartedElement();
366 }
367 else
368 {
369 _currentWriter.write('>');
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386 if (isScript(_startElementName) && (_isXhtmlContentType || _wrapScriptContentWithXmlCommentTag))
387 {
388
389
390 getInternalBuffer(true);
391 _currentWriter = getInternalBuffer().getWriter();
392 }
393 if (isStyle(_startElementName) && _isXhtmlContentType)
394 {
395
396
397 getInternalBuffer(true);
398 _currentWriter = getInternalBuffer().getWriter();
399 }
400 }
401 _startTagOpen = false;
402 }
403 }
404
405 private boolean isEmptyElement(String elem)
406 {
407
408
409
410
411
412
413
414 String[] array = EMPTY_ELEMENT_ARR[elem.charAt(0)];
415 if (array != null)
416 {
417 for (int i = array.length - 1; i >= 0; i--)
418 {
419 if (elem.equalsIgnoreCase(array[i]))
420 {
421 return true;
422 }
423 }
424 }
425 return false;
426 }
427
428 private void resetStartedElement()
429 {
430 _startElementName = null;
431 _startElementUIComponent = null;
432 _isStyle = null;
433 _isTextArea = null;
434 }
435
436 public void endElement(String name) throws IOException
437 {
438 if (name == null)
439 {
440 throw new NullPointerException("elementName name must not be null");
441 }
442
443 if (log.isLoggable(Level.WARNING))
444 {
445 if (_startElementName != null &&
446 !name.equals(_startElementName))
447 {
448 log.warning("HTML nesting warning on closing " + name + ": element " + _startElementName +
449 (_startElementUIComponent==null?"":(" rendered by component : "+
450 RendererUtils.getPathToComponent(_startElementUIComponent)))+" not explicitly closed");
451 }
452 }
453
454 if(_startTagOpen)
455 {
456
457
458
459 closeStartTagIfNecessary();
460
461
462 if(_startElementName!=null)
463 {
464 if (isScript() && (_isXhtmlContentType || _wrapScriptContentWithXmlCommentTag))
465 {
466 writeScriptContent();
467 _currentWriter = _outputWriter;
468 }
469 else if (isStyle() && _isXhtmlContentType)
470 {
471 writeStyleContent();
472 _currentWriter = _outputWriter;
473 }
474
475
476 writeEndTag(name);
477 }
478 }
479 else
480 {
481 if (!_useStraightXml && isEmptyElement(name))
482 {
483
484
485
486
487
488
489
490 }
491 else
492 {
493 if (isScript() && (_isXhtmlContentType || _wrapScriptContentWithXmlCommentTag))
494 {
495 writeScriptContent();
496 _currentWriter = _outputWriter;
497 }
498 else if (isStyle() && _isXhtmlContentType)
499 {
500 writeStyleContent();
501 _currentWriter = _outputWriter;
502 }
503 writeEndTag(name);
504 }
505 }
506
507 resetStartedElement();
508 }
509
510
511
512 private void writeStyleContent() throws IOException
513 {
514 String content = getInternalBuffer().toString();
515
516 if(_isXhtmlContentType)
517 {
518
519
520
521
522
523
524
525 String trimmedContent = content.trim();
526 if (trimmedContent.startsWith(CommentUtils.CDATA_SIMPLE_START) && trimmedContent.endsWith(
527 CommentUtils.CDATA_SIMPLE_END))
528 {
529 _outputWriter.write(content);
530 return;
531 }
532 else if (CommentUtils.isStartMatchWithCommentedCDATA(trimmedContent) &&
533 CommentUtils.isEndMatchWithCommentedCDATA(trimmedContent))
534 {
535 _outputWriter.write(content);
536 return;
537 }
538 else if (trimmedContent.startsWith(CommentUtils.COMMENT_SIMPLE_START) &&
539 trimmedContent.endsWith(CommentUtils.COMMENT_SIMPLE_END))
540 {
541
542 _outputWriter.write(CDATA_START);
543 _outputWriter.write(trimmedContent.substring(4,trimmedContent.length()-3));
544 _outputWriter.write(CDATA_END);
545 return;
546 }
547 else
548 {
549 _outputWriter.write(CDATA_START);
550 _outputWriter.write(content);
551 _outputWriter.write(CDATA_END);
552 return;
553 }
554 }
555
556
557
558 _outputWriter.write(content);
559 }
560
561 private void writeScriptContent() throws IOException
562 {
563 String content = getInternalBuffer().toString();
564 String trimmedContent = null;
565
566 if(_isXhtmlContentType)
567 {
568 trimmedContent = content.trim();
569
570 if ( trimmedContent.startsWith(CommentUtils.COMMENT_SIMPLE_START) &&
571 CommentUtils.isEndMatchtWithInlineCommentedXmlCommentTag(trimmedContent))
572 {
573
574
575 if (_cdataOpen)
576 {
577 _outputWriter.write("//\n");
578 }
579 else
580 {
581 _outputWriter.write(CDATA_COMMENT_START);
582 }
583
584 _outputWriter.write(trimmedContent.substring(4));
585
586 if (_cdataOpen)
587 {
588 _outputWriter.write("\n");
589 }
590 else
591 {
592 _outputWriter.write(CDATA_COMMENT_END);
593 }
594
595 return;
596 }
597 else if (CommentUtils.isStartMatchWithCommentedCDATA(trimmedContent) &&
598 CommentUtils.isEndMatchWithCommentedCDATA(trimmedContent))
599 {
600 _outputWriter.write(content);
601 return;
602 }
603 else if (CommentUtils.isStartMatchWithInlineCommentedCDATA(trimmedContent) &&
604 CommentUtils.isEndMatchWithInlineCommentedCDATA(trimmedContent))
605 {
606 _outputWriter.write(content);
607 return;
608 }
609 else
610 {
611
612
613 if (_cdataOpen)
614 {
615 _outputWriter.write("//\n");
616 }
617 else
618 {
619 _outputWriter.write(CDATA_COMMENT_START);
620 }
621
622 _outputWriter.write(content);
623
624 if (_cdataOpen)
625 {
626 _outputWriter.write("\n");
627 }
628 else
629 {
630 _outputWriter.write(CDATA_COMMENT_END);
631 }
632
633 return;
634 }
635 }
636 else
637 {
638 if (_wrapScriptContentWithXmlCommentTag)
639 {
640 trimmedContent = content.trim();
641
642 if ( trimmedContent.startsWith(CommentUtils.COMMENT_SIMPLE_START) &&
643 CommentUtils.isEndMatchtWithInlineCommentedXmlCommentTag(trimmedContent))
644 {
645 _outputWriter.write(content);
646 return;
647 }
648 else if (CommentUtils.isStartMatchWithCommentedCDATA(trimmedContent) &&
649 CommentUtils.isEndMatchWithCommentedCDATA(trimmedContent))
650 {
651 _outputWriter.write(content);
652 return;
653 }
654 else if (CommentUtils.isStartMatchWithInlineCommentedCDATA(trimmedContent) &&
655 CommentUtils.isEndMatchWithInlineCommentedCDATA(trimmedContent))
656 {
657 _outputWriter.write(content);
658 return;
659 }
660 else
661 {
662 _outputWriter.write(COMMENT_START);
663 _outputWriter.write(content);
664 _outputWriter.write(COMMENT_COMMENT_END);
665 return;
666 }
667 }
668 }
669
670
671 _outputWriter.write(content);
672 }
673
674
675 private void writeEndTag(String name)
676 throws IOException
677 {
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697 if (isScript(name))
698 {
699
700 _isInsideScript = Boolean.FALSE;
701 }
702 else if (isStyle(name))
703 {
704 _isStyle = Boolean.FALSE;
705 }
706
707 _currentWriter.write("</");
708 _currentWriter.write(name);
709 _currentWriter.write('>');
710 }
711
712 public void writeAttribute(String name, Object value, String componentPropertyName) throws IOException
713 {
714 if (name == null)
715 {
716 throw new NullPointerException("attributeName name must not be null");
717 }
718 if (!_startTagOpen)
719 {
720 throw new IllegalStateException("Must be called before the start element is closed (attribute '"
721 + name + "')");
722 }
723
724 if (value instanceof Boolean)
725 {
726 if (((Boolean)value).booleanValue())
727 {
728
729 _currentWriter.write(' ');
730 _currentWriter.write(name);
731 _currentWriter.write("=\"");
732 _currentWriter.write(name);
733 _currentWriter.write('"');
734 }
735 }
736 else
737 {
738 String strValue = (value==null)?"":value.toString();
739 _currentWriter.write(' ');
740 _currentWriter.write(name);
741 _currentWriter.write("=\"");
742 org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encode(_currentWriter,
743 strValue, false, false, !_isUTF8);
744 _currentWriter.write('"');
745 }
746 }
747
748 public void writeURIAttribute(String name, Object value, String componentPropertyName) throws IOException
749 {
750 if (name == null)
751 {
752 throw new NullPointerException("attributeName name must not be null");
753 }
754 if (!_startTagOpen)
755 {
756 throw new IllegalStateException("Must be called before the start element is closed (attribute '"
757 + name + "')");
758 }
759
760 String strValue = value.toString();
761 _currentWriter.write(' ');
762 _currentWriter.write(name);
763 _currentWriter.write("=\"");
764 if (strValue.toLowerCase().startsWith("javascript:"))
765 {
766 org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encode(_currentWriter,
767 strValue, false, false, !_isUTF8);
768 }
769 else
770 {
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799 org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encodeURIAtributte(_currentWriter,
800 strValue, _characterEncoding);
801 }
802 _currentWriter.write('"');
803 }
804
805 public void writeComment(Object value) throws IOException
806 {
807 if (value == null)
808 {
809 throw new NullPointerException("comment name must not be null");
810 }
811
812 closeStartTagIfNecessary();
813 _currentWriter.write("<!--");
814 _currentWriter.write(value.toString());
815 _currentWriter.write("-->");
816 }
817
818 public void writeText(Object value, String componentPropertyName) throws IOException
819 {
820 if (value == null)
821 {
822 throw new NullPointerException("Text must not be null.");
823 }
824
825 closeStartTagIfNecessary();
826
827 String strValue = value.toString();
828
829 if (isScriptOrStyle())
830 {
831
832 if (_isUTF8)
833 {
834 _currentWriter.write(strValue);
835 }
836 else
837 {
838 UnicodeEncoder.encode(_currentWriter, strValue);
839 }
840 }
841 else
842 {
843 org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encode(_currentWriter,
844 strValue, false, false, !_isUTF8);
845 }
846 }
847
848 public void writeText(char cbuf[], int off, int len) throws IOException
849 {
850 if (cbuf == null)
851 {
852 throw new NullPointerException("cbuf name must not be null");
853 }
854 if (cbuf.length < off + len)
855 {
856 throw new IndexOutOfBoundsException((off + len) + " > " + cbuf.length);
857 }
858
859 closeStartTagIfNecessary();
860
861 if (isScriptOrStyle())
862 {
863 String strValue = new String(cbuf, off, len);
864
865 if (_isUTF8)
866 {
867 _currentWriter.write(strValue);
868 }
869 else
870 {
871 UnicodeEncoder.encode(_currentWriter, strValue);
872 }
873 }
874 else if (isTextarea())
875 {
876
877 org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encode(
878 cbuf, off, len, false, false, !_isUTF8, _currentWriter);
879 }
880 else
881 {
882
883 org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encode(
884 cbuf, off, len, true, true, !_isUTF8, _currentWriter);
885 }
886 }
887
888 private boolean isScriptOrStyle()
889 {
890
891
892 return (_isStyle != null && _isStyle.booleanValue()) ||
893 (_isInsideScript != null && _isInsideScript.booleanValue());
894 }
895
896
897
898
899
900
901 private boolean isScript(String element)
902 {
903 return (HTML.SCRIPT_ELEM.equalsIgnoreCase(element));
904 }
905
906 private boolean isScript()
907 {
908 return (_isInsideScript != null && _isInsideScript.booleanValue());
909 }
910
911 private boolean isStyle(String element)
912 {
913 return (HTML.STYLE_ELEM.equalsIgnoreCase(element));
914 }
915
916 private boolean isStyle()
917 {
918 return (_isStyle != null && _isStyle.booleanValue());
919 }
920
921 private boolean isTextarea()
922 {
923 initializeStartedTagInfo();
924
925 return _isTextArea != null && _isTextArea.booleanValue();
926 }
927
928 private void initializeStartedTagInfo()
929 {
930 if(_startElementName != null)
931 {
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946 if(_isTextArea == null)
947 {
948 if(_startElementName.equalsIgnoreCase(HTML.TEXTAREA_ELEM))
949 {
950 _isTextArea = Boolean.TRUE;
951 }
952 else
953 {
954 _isTextArea = Boolean.FALSE;
955 }
956 }
957 }
958 }
959
960 public ResponseWriter cloneWithWriter(Writer writer)
961 {
962 HtmlResponseWriterImpl newWriter
963 = new HtmlResponseWriterImpl(writer, getContentType(), getCharacterEncoding(),
964 _wrapScriptContentWithXmlCommentTag, _writerContentTypeMode);
965
966
967 return newWriter;
968 }
969
970
971
972
973 public void close() throws IOException
974 {
975 closeStartTagIfNecessary();
976 _currentWriter.close();
977 }
978
979 public void write(char cbuf[], int off, int len) throws IOException
980 {
981 closeStartTagIfNecessary();
982
983 if (_isUTF8)
984 {
985 _currentWriter.write(cbuf, off, len);
986 }
987 else
988 {
989 UnicodeEncoder.encode(_currentWriter, cbuf, off, len);
990 }
991 }
992
993 public void write(int c) throws IOException
994 {
995 closeStartTagIfNecessary();
996 _currentWriter.write(c);
997 }
998
999 public void write(char cbuf[]) throws IOException
1000 {
1001 closeStartTagIfNecessary();
1002
1003 if (_isUTF8)
1004 {
1005 _currentWriter.write(cbuf);
1006 }
1007 else
1008 {
1009 UnicodeEncoder.encode(_currentWriter, cbuf, 0, cbuf.length);
1010 }
1011 }
1012
1013 public void write(String str) throws IOException
1014 {
1015 closeStartTagIfNecessary();
1016
1017
1018 if (str != null && str.length() > 0)
1019 {
1020
1021 if (_isUTF8)
1022 {
1023 _currentWriter.write(str);
1024 }
1025 else
1026 {
1027 UnicodeEncoder.encode(_currentWriter, str);
1028 }
1029 }
1030 }
1031
1032 public void write(String str, int off, int len) throws IOException
1033 {
1034 closeStartTagIfNecessary();
1035
1036 if (_isUTF8)
1037 {
1038 _currentWriter.write(str, off, len);
1039 }
1040 else
1041 {
1042 UnicodeEncoder.encode(_currentWriter, str, off, len);
1043 }
1044 }
1045
1046
1047
1048
1049
1050
1051 public void writeText(Object object, UIComponent component, String string) throws IOException
1052 {
1053 writeText(object,string);
1054 }
1055
1056 protected StreamCharBuffer getInternalBuffer()
1057 {
1058 return getInternalBuffer(false);
1059 }
1060
1061 protected StreamCharBuffer getInternalBuffer(boolean reset)
1062 {
1063 if (_buffer == null)
1064 {
1065 _buffer = new StreamCharBuffer(256, 100);
1066 }
1067 else if (reset)
1068 {
1069 _buffer.reset();
1070 }
1071 return _buffer;
1072 }
1073 }