KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javolution > xml > stream > XMLStreamWriterImpl


1 /*
2  * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
3  * Copyright (C) 2006 - Javolution (http://javolution.org/)
4  * All rights reserved.
5  *
6  * Permission to use, copy, modify, and distribute this software is
7  * freely granted, provided that this notice is preserved.
8  */

9 package javolution.xml.stream;
10
11 import java.io.IOException JavaDoc;
12 import java.io.OutputStream JavaDoc;
13 import java.io.OutputStreamWriter JavaDoc;
14 import java.io.UnsupportedEncodingException JavaDoc;
15 import java.io.Writer JavaDoc;
16
17 import javolution.context.ObjectFactory;
18 import javolution.io.UTF8StreamWriter;
19 import javolution.lang.Reusable;
20 import javolution.text.CharArray;
21 import javolution.text.TextBuilder;
22 import j2me.lang.CharSequence;
23 import j2me.lang.IllegalStateException;
24 import j2mex.realtime.MemoryArea;
25
26 /**
27  * <p> This class represents a {@link javolution.lang.Reusable reusable}
28  * implementation of {@link XMLStreamWriter}.</p>
29  *
30  * @author <a HREF="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
31  * @version 4.0, September 4, 2006
32  */

33 public final class XMLStreamWriterImpl implements XMLStreamWriter, Reusable {
34
35     /**
36      * Holds the length of intermediate buffer.
37      */

38     private static final int BUFFER_LENGTH = 2048;
39
40     /**
41      * Holds the current nesting level.
42      */

43     private int _nesting = 0;
44
45     /**
46      * Holds the element qualified name (indexed per nesting level)
47      */

48     private TextBuilder[] _qNames = new TextBuilder[16];
49
50     /**
51      * Indicates if the current element is open.
52      */

53     private boolean _isElementOpen;
54
55     /**
56      * Indicates if the current element is an empty element.
57      */

58     private boolean _isEmptyElement;
59
60     /**
61      * Holds intermediate buffer.
62      */

63     private final char[] _buffer = new char[BUFFER_LENGTH];
64
65     /**
66      * Holds the namespace stack.
67      */

68     private final NamespacesImpl _namespaces = new NamespacesImpl();
69
70     /**
71      * Holds the buffer current index.
72      */

73     private int _index;
74
75     /**
76      * Holds repairing namespace property.
77      */

78     private boolean _isRepairingNamespaces;
79
80     /**
81      * Holds repairing prefix property.
82      */

83     private String JavaDoc _repairingPrefix = "ns";
84
85     /**
86      * Holds indentation property.
87      */

88     private String JavaDoc _indentation;
89
90     /**
91      * Holds current indentation level.
92      */

93     private int _indentationLevel;
94
95     /**
96      * Holds automatic empty elements property.
97      */

98     private boolean _automaticEmptyElements;
99
100     /**
101      * Holds counter for automatic namespace generation.
102      */

103     private int _autoNSCount;
104
105     /**
106      * Holds recycling factory if any.
107      */

108     ObjectFactory _objectFactory;
109
110     ////////////////////////
111
// Temporary Settings //
112
////////////////////////
113

114     /**
115      * Holds the writer destination (<code>null</code> when unused).
116      */

117     private Writer JavaDoc _writer;
118
119     /**
120      * Holds the encoding (<code>null</code> if N/A).
121      */

122     private String JavaDoc _encoding;
123
124     /**
125      * Holds the defautl writer for output streams.
126      */

127     private final UTF8StreamWriter _utf8StreamWriter = new UTF8StreamWriter();
128
129     /**
130      * Default constructor.
131      */

132     public XMLStreamWriterImpl() {
133         for (int i = 0; i < _qNames.length;) {
134             _qNames[i++] = new TextBuilder();
135         }
136     }
137
138     /**
139      * Sets the output stream destination for this XML stream writer
140      * (UTF-8 encoding).
141      *
142      * @param out the output source with utf-8 encoding.
143      */

144     public void setOutput(OutputStream JavaDoc out) throws XMLStreamException {
145         _utf8StreamWriter.setOutput(out);
146         _encoding = "UTF-8";
147         setOutput(_utf8StreamWriter);
148     }
149
150     /**
151      * Sets the output stream destination and encoding for this XML stream
152      * writer.
153      *
154      * @param out the output source.
155      * @param encoding the associated encoding.
156      * @throws XMLStreamException if the specified encoding is not supported.
157      */

158     public void setOutput(OutputStream JavaDoc out, String JavaDoc encoding)
159             throws XMLStreamException {
160         if (encoding.equals("UTF-8") || encoding.equals("utf-8")
161                 || encoding.equals("ASCII")) {
162             setOutput(out); // Default encoding.
163
}
164         try {
165             _encoding = encoding;
166             setOutput(new OutputStreamWriter JavaDoc(out, encoding));
167         } catch (UnsupportedEncodingException JavaDoc e) {
168             throw new XMLStreamException(e);
169         }
170     }
171
172     /**
173      * Sets the writer output destination for this XML stream writer.
174      *
175      * @param writer the output destination writer.
176      * @see javolution.io.UTF8StreamWriter
177      * @see javolution.io.UTF8ByteBufferWriter
178      * @see javolution.io.AppendableWriter
179      */

180     public void setOutput(Writer JavaDoc writer) throws XMLStreamException {
181         if (_writer != null)
182             throw new IllegalStateException JavaDoc("Writer not closed or reset");
183         _writer = writer;
184     }
185
186     /**
187      * Requires this writer to create a new prefix when a namespace has none
188      * (default <code>false</code>).
189      *
190      * @param isRepairingNamespaces <code>true</code> if namespaces
191      * are repaired; <code>false</code> otherwise.
192      */

193     public void setRepairingNamespaces(boolean isRepairingNamespaces) {
194         _isRepairingNamespaces = isRepairingNamespaces;
195     }
196
197     /**
198      * Specifies the prefix to be append by a trailing part
199      * (a sequence number) in order to make it unique to be usable as
200      * a temporary non-colliding prefix when repairing namespaces
201      * (default <code>"ns"</code>).
202      *
203      * @param repairingPrefix the prefix root.
204      */

205     public void setRepairingPrefix(String JavaDoc repairingPrefix) {
206         _repairingPrefix = repairingPrefix;
207     }
208
209     /**
210      * Specifies the indentation string; non-null indentation
211      * forces the writer to write elements into separate lines
212      * (default <code>null</code>).
213      *
214      * @param indentation the indentation string.
215      */

216     public void setIndentation(String JavaDoc indentation) {
217         _indentation = indentation;
218     }
219
220     /**
221      * Requires this writer to automatically output empty elements when a
222      * start element is immediately followed by matching end element
223      * (default <code>false</code>).
224      *
225      * @param automaticEmptyElements <code>true</code> if start element
226      * immediately followed by end element results in an empty element
227      * beign written; <code>false</code> otherwise.
228      */

229     public void setAutomaticEmptyElements(boolean automaticEmptyElements) {
230         _automaticEmptyElements = automaticEmptyElements;
231     }
232
233     // Implements reusable.
234
public void reset() {
235         _automaticEmptyElements = false;
236         _autoNSCount = 0;
237         _encoding = null;
238         _indentation = null;
239         _indentationLevel = 0;
240         _index = 0;
241         _isElementOpen = false;
242         _isEmptyElement = false;
243         _isRepairingNamespaces = false;
244         _namespaces.reset();
245         _nesting = 0;
246         _objectFactory = null;
247         _repairingPrefix = "ns";
248         _utf8StreamWriter.reset();
249         _writer = null;
250     }
251
252     // Implements XMLStreamWriter interface.
253
public void writeStartElement(CharSequence JavaDoc localName)
254             throws XMLStreamException {
255         if (localName == null)
256             throw new XMLStreamException("Local name cannot be null");
257         writeNewElement(null, localName, null);
258     }
259
260     // Implements XMLStreamWriter interface.
261
public void writeStartElement(CharSequence JavaDoc namespaceURI,
262             CharSequence JavaDoc localName) throws XMLStreamException {
263         if (localName == null)
264             throw new XMLStreamException("Local name cannot be null");
265         if (namespaceURI == null)
266             throw new XMLStreamException("Namespace URI cannot be null");
267         writeNewElement(null, localName, namespaceURI);
268     }
269
270     // Implements XMLStreamWriter interface.
271
public void writeStartElement(CharSequence JavaDoc prefix, CharSequence JavaDoc localName,
272             CharSequence JavaDoc namespaceURI) throws XMLStreamException {
273         if (localName == null)
274             throw new XMLStreamException("Local name cannot be null");
275         if (namespaceURI == null)
276             throw new XMLStreamException("Namespace URI cannot be null");
277         if (prefix == null)
278             throw new XMLStreamException("Prefix cannot be null");
279         writeNewElement(prefix, localName, namespaceURI);
280     }
281
282     // Implements XMLStreamWriter interface.
283
public void writeEmptyElement(CharSequence JavaDoc localName)
284             throws XMLStreamException {
285         writeStartElement(localName);
286         _isEmptyElement = true;
287     }
288
289     // Implements XMLStreamWriter interface.
290
public void writeEmptyElement(CharSequence JavaDoc namespaceURI,
291             CharSequence JavaDoc localName) throws XMLStreamException {
292         writeStartElement(namespaceURI, localName);
293         _isEmptyElement = true;
294     }
295
296     // Implements XMLStreamWriter interface.
297
public void writeEmptyElement(CharSequence JavaDoc prefix, CharSequence JavaDoc localName,
298             CharSequence JavaDoc namespaceURI) throws XMLStreamException {
299         writeStartElement(prefix, localName, namespaceURI);
300         _isEmptyElement = true;
301     }
302
303     // Implements XMLStreamWriter interface.
304
public void writeEndElement() throws XMLStreamException {
305         if (_isElementOpen) { // Empty element.
306
if (_automaticEmptyElements) {
307                 _isEmptyElement = true; // Closes as if empty element.
308
closeOpenTag();
309                 return;
310             }
311             closeOpenTag();
312         }
313         if ((_indentation != null) && (_indentationLevel != _nesting - 1)) {
314                  // Do not indent if no change in indentation level
315
// to avoid interfering with text only elements.
316
write('\n');
317              for (int i = 1; i < _nesting; i++) {
318                   writeStr(_indentation);
319              }
320         }
321         
322         write('<');
323         write('/');
324         writeTB(_qNames[_nesting--]);
325         write('>');
326         _namespaces.pop();
327     }
328
329     // Implements XMLStreamWriter interface.
330
public void writeEndDocument() throws XMLStreamException {
331         if (_isElementOpen)
332             closeOpenTag();
333         while (_nesting > 0) { // Implicits closing of all elements.
334
writeEndElement();
335         }
336     }
337
338     // Implements XMLStreamWriter interface.
339
public void close() throws XMLStreamException {
340         if (_writer != null) {
341             if (_nesting != 0) { // Closes all elements.
342
writeEndDocument();
343             }
344             flush();
345         }
346         if (_objectFactory != null) {
347             _objectFactory.recycle(this); // Implicit reset.
348
} else {
349             reset(); // Explicit reset.
350
}
351     }
352
353     // Implements XMLStreamWriter interface.
354
public void flush() throws XMLStreamException {
355         flushBuffer();
356         try {
357             _writer.flush();
358         } catch (IOException JavaDoc e) {
359             throw new XMLStreamException(e);
360         }
361     }
362
363     // Implements XMLStreamWriter interface.
364
public void writeAttribute(CharSequence JavaDoc localName, CharSequence JavaDoc value)
365             throws XMLStreamException {
366         if (localName == null)
367             throw new XMLStreamException("Local name cannot be null");
368         if (value == null)
369             throw new XMLStreamException("Value cannot be null");
370         writeAttributeOrNamespace(null, null, localName, value);
371     }
372
373     // Implements XMLStreamWriter interface.
374
public void writeAttribute(CharSequence JavaDoc namespaceURI,
375             CharSequence JavaDoc localName, CharSequence JavaDoc value)
376             throws XMLStreamException {
377         if (localName == null)
378             throw new XMLStreamException("Local name cannot be null");
379         if (value == null)
380             throw new XMLStreamException("Value cannot be null");
381         if (namespaceURI == null)
382             throw new XMLStreamException("Namespace URI cannot be null");
383         writeAttributeOrNamespace(null, namespaceURI, localName, value);
384     }
385
386     // Implements XMLStreamWriter interface.
387
public void writeAttribute(CharSequence JavaDoc prefix, CharSequence JavaDoc namespaceURI,
388             CharSequence JavaDoc localName, CharSequence JavaDoc value)
389             throws XMLStreamException {
390         if (localName == null)
391             throw new XMLStreamException("Local name cannot be null");
392         if (value == null)
393             throw new XMLStreamException("Value cannot be null");
394         if (namespaceURI == null)
395             throw new XMLStreamException("Namespace URI cannot be null");
396         if (prefix == null)
397             throw new XMLStreamException("Prefix cannot be null");
398         writeAttributeOrNamespace(prefix, namespaceURI, localName, value);
399     }
400
401     // Implements XMLStreamWriter interface.
402
public void writeNamespace(CharSequence JavaDoc prefix, CharSequence JavaDoc namespaceURI)
403             throws XMLStreamException {
404         if ((prefix == null) || (prefix.length() == 0)
405                 || _namespaces._xmlns.equals(prefix)) {
406             prefix = _namespaces._defaultNsPrefix;
407         }
408         if (!_isElementOpen) // Check now as the actual writting is queued.
409
throw new IllegalStateException JavaDoc("No open start element");
410         _namespaces.setPrefix(prefix,
411                 (namespaceURI == null) ? _namespaces._nullNsURI : namespaceURI,
412                 true);
413     }
414
415     // Implements XMLStreamWriter interface.
416
public void writeDefaultNamespace(CharSequence JavaDoc namespaceURI)
417             throws XMLStreamException {
418         writeNamespace(_namespaces._defaultNsPrefix, namespaceURI);
419     }
420
421     // Implements XMLStreamWriter interface.
422
public void writeComment(CharSequence JavaDoc data) throws XMLStreamException {
423         if (_isElementOpen)
424             closeOpenTag();
425         writeStr("<!--");
426         if (data != null) { // null values allowed.
427
write(data);
428         }
429         writeStr("-->");
430     }
431
432     // Implements XMLStreamWriter interface.
433
public void writeProcessingInstruction(CharSequence JavaDoc target)
434             throws XMLStreamException {
435         writeProcessingInstruction(target, _noChar);
436     }
437
438     private final CharArray _noChar = new CharArray("");
439
440     // Implements XMLStreamWriter interface.
441
public void writeProcessingInstruction(CharSequence JavaDoc target,
442             CharSequence JavaDoc data) throws XMLStreamException {
443         if (target == null)
444             throw new XMLStreamException("Target cannot be null");
445         if (data == null)
446             throw new XMLStreamException("Data cannot be null");
447         if (_isElementOpen)
448             closeOpenTag();
449         writeStr("<?");
450         write(target);
451         write(' ');
452         write(data);
453         write(" ?>");
454     }
455
456     // Implements XMLStreamWriter interface.
457
public void writeCData(CharSequence JavaDoc data) throws XMLStreamException {
458         if (data == null)
459             throw new XMLStreamException("Data cannot be null");
460         if (_isElementOpen)
461             closeOpenTag();
462         writeStr("<![CDATA[");
463         write(data);
464         writeStr("]]>");
465     }
466
467     // Implements XMLStreamWriter interface.
468
public void writeDTD(CharSequence JavaDoc dtd) throws XMLStreamException {
469         if (dtd == null)
470             throw new XMLStreamException("DTD cannot be null");
471         if (_nesting > 0)
472             throw new XMLStreamException(
473                     "DOCTYPE declaration (DTD) when not in document root (prolog)");
474         write(dtd);
475     }
476
477     // Implements XMLStreamWriter interface.
478
public void writeEntityRef(CharSequence JavaDoc name) throws XMLStreamException {
479         write('&');
480         write(name);
481         write(';');
482     }
483
484     // Implements XMLStreamWriter interface.
485
public void writeStartDocument() throws XMLStreamException {
486         writeStartDocument(null, null);
487     }
488
489     // Implements XMLStreamWriter interface.
490
public void writeStartDocument(CharSequence JavaDoc version)
491             throws XMLStreamException {
492         writeStartDocument(null, version);
493     }
494
495     // Implements XMLStreamWriter interface.
496
public void writeStartDocument(CharSequence JavaDoc encoding, CharSequence JavaDoc version)
497             throws XMLStreamException {
498         if (_nesting > 0)
499             throw new XMLStreamException("Not in document root");
500         writeStr("<?xml version=\"");
501         if (version != null) {
502             write(version);
503             write('"');
504         } else { // Default to 1.0
505
writeStr("1.0\"");
506         }
507         if (encoding != null) {
508             writeStr(" encoding=\"");
509             write(encoding);
510             write('"');
511         } else if (_encoding != null) { // Use init encoding (if any).
512
writeStr(" encoding=\"");
513             writeStr(_encoding);
514             write('"');
515         }
516         writeStr(" ?>");
517     }
518
519     // Implements XMLStreamWriter interface.
520
public void writeCharacters(CharSequence JavaDoc text) throws XMLStreamException {
521         if (_isElementOpen)
522             closeOpenTag();
523         if (text == null)
524             return;
525         writeEsc(text);
526     }
527
528     // Implements XMLStreamWriter interface.
529
public void writeCharacters(char[] text, int start, int length)
530             throws XMLStreamException {
531         for (int i = start, end = start + length; i < end;) {
532             writeEsc(text[i++]);
533         }
534     }
535
536     // Implements XMLStreamWriter interface.
537
public CharSequence JavaDoc getPrefix(CharSequence JavaDoc uri) throws XMLStreamException {
538         return _namespaces.getPrefix(uri);
539     }
540
541     // Implements XMLStreamWriter interface.
542
public void setPrefix(CharSequence JavaDoc prefix, CharSequence JavaDoc uri)
543             throws XMLStreamException {
544         _namespaces.setPrefix(prefix, (uri == null) ? _namespaces._nullNsURI
545                 : uri, false);
546     }
547
548     // Implements XMLStreamWriter interface.
549
public void setDefaultNamespace(CharSequence JavaDoc uri) throws XMLStreamException {
550         setPrefix(_namespaces._defaultNsPrefix, uri);
551     }
552
553     // Implements XMLStreamWriter interface.
554
public Object JavaDoc getProperty(String JavaDoc name) throws IllegalArgumentException JavaDoc {
555         if (name.equals(XMLOutputFactory.IS_REPAIRING_NAMESPACES)) {
556             return new Boolean JavaDoc(_isRepairingNamespaces);
557         } else if (name.equals(XMLOutputFactory.REPAIRING_PREFIX)) {
558             return _repairingPrefix;
559         } else if (name.equals(XMLOutputFactory.AUTOMATIC_EMPTY_ELEMENTS)) {
560             return new Boolean JavaDoc(_automaticEmptyElements);
561         } else if (name.equals(XMLOutputFactory.INDENTATION)) {
562             return _indentation;
563         } else {
564             throw new IllegalArgumentException JavaDoc("Property: " + name
565                     + " not supported");
566         }
567     }
568
569     // Writes a new start or empty element.
570
private void writeNewElement(CharSequence JavaDoc prefix, CharSequence JavaDoc localName,
571             CharSequence JavaDoc namespaceURI) throws XMLStreamException {
572
573         // Close any open element and gets ready to write a new one.
574
if (_isElementOpen)
575             closeOpenTag();
576         if (_indentation != null) {
577             write('\n');
578             _indentationLevel = _nesting;
579             for (int i = 0; i < _indentationLevel; i++) {
580                 writeStr(_indentation);
581             }
582         }
583         write('<');
584         _isElementOpen = true;
585
586         // Enters a new local scope.
587
if (++_nesting >= _qNames.length)
588             resizeElemStack();
589         _namespaces.push();
590
591         // Constructs qName.
592
TextBuilder qName = _qNames[_nesting].clear();
593
594         // Writes prefix if any.
595
if ((namespaceURI != null)
596                 && (!_namespaces._defaultNamespace.equals(namespaceURI))) {
597             if (_isRepairingNamespaces) { // Repairs prefix.
598
prefix = getRepairedPrefix(prefix, namespaceURI);
599             } else if (prefix == null) { // Retrieves prefix.
600
prefix = getPrefix(namespaceURI);
601                 if (prefix == null)
602                     throw new XMLStreamException("URI: " + namespaceURI
603                             + " not bound and repairing namespaces disabled");
604             }
605             if (prefix.length() > 0) {
606                 qName.append(prefix);
607                 qName.append(':');
608             }
609         }
610         qName.append(localName);
611         writeTB(qName);
612     }
613
614     // Writes a new attribute.
615
private void writeAttributeOrNamespace(CharSequence JavaDoc prefix,
616             CharSequence JavaDoc namespaceURI, CharSequence JavaDoc localName,
617             CharSequence JavaDoc value) throws XMLStreamException {
618         if (!_isElementOpen)
619             throw new IllegalStateException JavaDoc("No open start element");
620         write(' ');
621
622         // Writes prefix if any.
623
if ((namespaceURI != null)
624                 && (!_namespaces._defaultNamespace.equals(namespaceURI))) {
625             if (_isRepairingNamespaces) { // Repairs prefix if current prefix is not correct.
626
prefix = getRepairedPrefix(prefix, namespaceURI);
627             } else if (prefix == null) {
628                 prefix = getPrefix(namespaceURI);
629                 if (prefix == null)
630                     throw new XMLStreamException("URI: " + namespaceURI
631                             + " not bound and repairing namespaces disabled");
632             }
633             if (prefix.length() > 0) {
634                 write(prefix);
635                 write(':');
636             }
637         }
638
639         write(localName);
640         write('=');
641         write('"');
642         writeEsc(value);
643         write('"');
644     }
645
646     // Closes the current element (scope if empty element).
647
private void closeOpenTag() throws XMLStreamException {
648
649         // Writes namespaces now.
650
writeNamespaces();
651
652         // Closes the tag.
653
_isElementOpen = false;
654         if (_isEmptyElement) {
655             write('/');
656             write('>');
657             _nesting--;
658             _namespaces.pop();
659             _isEmptyElement = false;
660         } else {
661             write('>');
662         }
663     }
664
665     // Writes all namespaces, these include namespaces set but
666
// not written in outer scope.
667
private void writeNamespaces() throws XMLStreamException {
668         int i0 = (_nesting > 1) ? _namespaces._namespacesCount[_nesting - 2]
669                 : NamespacesImpl.NBR_PREDEFINED_NAMESPACES;
670         int i1 = _namespaces._namespacesCount[_nesting - 1];
671         int i2 = _namespaces._namespacesCount[_nesting];
672         for (int i = i0; i < i2; i++) {
673             if (((_isRepairingNamespaces && (i < i1) && !_namespaces._prefixesWritten[i]))
674                     || ((i >= i1) && _namespaces._prefixesWritten[i])) { // Write namespace.
675

676                 // In repairing mode, removes redondancy.
677
if (_isRepairingNamespaces) {
678                     CharArray prefix = _namespaces.getPrefix(
679                             _namespaces._namespaces[i], i);
680                     if (_namespaces._prefixes[i].equals(prefix))
681                         continue; // Not necessary.
682
} // Direct mode, just write them as requested (no check).
683

684                 // Writes namespace.
685
if (_namespaces._prefixes[i].length() == 0) { // Default namespace.
686
writeAttributeOrNamespace(null, null, _namespaces._xmlns,
687                             _namespaces._namespaces[i]);
688                 } else {
689                     writeAttributeOrNamespace(_namespaces._xmlns,
690                             _namespaces._xmlnsURI, _namespaces._prefixes[i],
691                             _namespaces._namespaces[i]);
692                 }
693             }
694         }
695     }
696
697     // Returns the prefix for the specified namespace.
698
private CharSequence JavaDoc getRepairedPrefix(CharSequence JavaDoc prefix,
699             CharSequence JavaDoc namespaceURI) throws XMLStreamException {
700         CharArray prefixForURI = _namespaces.getPrefix(namespaceURI);
701         if ((prefixForURI != null)
702                 && ((prefix == null) || prefixForURI.equals(prefix)))
703             return prefixForURI; // No repair needed.
704
if ((prefix == null) || (prefix.length() == 0)) { // Creates new prefix.
705
prefix = _autoPrefix.clear().append(_repairingPrefix).append(
706                     _autoNSCount++);
707         }
708         _namespaces.setPrefix(prefix, namespaceURI, true); // Map to namespace URI.
709
return prefix;
710     }
711
712     private final TextBuilder _autoPrefix = new TextBuilder();
713
714     // Resizes element stack (same memory area as the writer).
715
private void resizeElemStack() {
716         MemoryArea.getMemoryArea(this).executeInArea(new Runnable JavaDoc() {
717             public void run() {
718                 final int oldLength = _qNames.length;
719                 final int newLength = oldLength * 2;
720
721                 // Resizes elements qNames stack.
722
TextBuilder[] tmp = new TextBuilder[newLength];
723                 System.arraycopy(_qNames, 0, tmp, 0, oldLength);
724                 _qNames = tmp;
725                 for (int i = oldLength; i < newLength; i++) {
726                     _qNames[i] = new TextBuilder();
727                 }
728             }
729         });
730     }
731
732     // Writes methods.
733
//
734

735     private final void write(char c) throws XMLStreamException {
736         _buffer[_index++] = c;
737         if (_index == BUFFER_LENGTH) {
738             flushBuffer();
739         }
740     }
741
742     private final void writeEsc(char c) throws XMLStreamException {
743         if ((c >= '?')
744                 || ((c >= ' ') && (c != '<') && (c != '>') && (c != '"') && (c != '&'))) { // Most common case.
745
write(c);
746         } else {
747             writeEsc2(c);
748         }
749     }
750
751     private final void writeEsc2(char c) throws XMLStreamException {
752         switch (c) {
753         case '<':
754             writeStr("&lt;");
755             break;
756         case '>':
757             writeStr("&gt;");
758             break;
759         // case '\'': // Unnecessary due to exclusive use of "
760
// writeStr("&apos;");
761
// break;
762
case '"':
763             writeStr("&quot;");
764             break;
765         case '&':
766             writeStr("&amp;");
767             break;
768         default:
769             if (c >= ' ') {
770                 write(c);
771             } else {
772                 writeStr("&#");
773                 write((char) ('0' + c / 10));
774                 write((char) ('0' + c % 10));
775                 write(';');
776             }
777         }
778     }
779
780     private void write(Object JavaDoc obj) throws XMLStreamException {
781         if (obj instanceof String JavaDoc) {
782             writeStr((String JavaDoc) obj);
783         } else {
784             writeCsq((CharSequence JavaDoc) obj);
785         }
786     }
787
788     private void writeStr(String JavaDoc str) throws XMLStreamException {
789         int n = str.length();
790         if (_index + n < BUFFER_LENGTH) {
791             str.getChars(0, n, _buffer, _index);
792             _index += n;
793         } else {
794             writeStrImmediate(str);
795         }
796     }
797
798     private void writeStrImmediate(String JavaDoc str) throws XMLStreamException {
799         flushBuffer();
800         try {
801             _writer.write(str);
802         } catch (IOException JavaDoc e) {
803             throw new XMLStreamException(e);
804         }
805     }
806
807     private void writeCsq(CharSequence JavaDoc csq) throws XMLStreamException {
808         for (int i = 0, n = csq.length(); i < n;) {
809             // Inline write(char)
810
_buffer[_index++] = csq.charAt(i++);
811             if (_index == BUFFER_LENGTH) {
812                 flushBuffer();
813             }
814         }
815     }
816
817     private void writeTB(TextBuilder tb) throws XMLStreamException {
818         for (int i = 0, n = tb.length(); i < n;) {
819             // Inline write(char)
820
_buffer[_index++] = tb.charAt(i++);
821             if (_index == BUFFER_LENGTH) {
822                 flushBuffer();
823             }
824         }
825     }
826
827     private void writeEsc(Object JavaDoc obj) throws XMLStreamException {
828         if (obj instanceof String JavaDoc) {
829             writeEscStr((String JavaDoc) obj);
830         } else {
831             writeEscCsq((CharSequence JavaDoc) obj);
832         }
833     }
834
835     private void writeEscStr(String JavaDoc str) throws XMLStreamException {
836         for (int i = 0, n = str.length(); i < n;) {
837             // Inline writeEsc(char)
838
char c = str.charAt(i++);
839             if ((c >= '?')
840                     || ((c >= ' ') && (c != '<') && (c != '>') && (c != '"') && (c != '&'))) { // Most common case.
841
// Inline write(char)
842
_buffer[_index++] = c;
843                 if (_index == BUFFER_LENGTH) {
844                     flushBuffer();
845                 }
846             } else {
847                 writeEsc2(c);
848             }
849         }
850     }
851
852     private void writeEscCsq(CharSequence JavaDoc csq) throws XMLStreamException {
853         for (int i = 0, n = csq.length(); i < n;) {
854             // Inline writeEsc(char)
855
char c = csq.charAt(i++);
856             if ((c >= '?')
857                     || ((c >= ' ') && (c != '<') && (c != '>') && (c != '"') && (c != '&'))) { // Most common case.
858
// Inline write(char)
859
_buffer[_index++] = c;
860                 if (_index == BUFFER_LENGTH) {
861                     flushBuffer();
862                 }
863             } else {
864                 writeEsc2(c);
865             }
866         }
867     }
868
869     private void flushBuffer() throws XMLStreamException {
870         try {
871             _writer.write(_buffer, 0, _index);
872         } catch (IOException JavaDoc e) {
873             throw new XMLStreamException(e);
874         } finally {
875             _index = 0;
876         }
877     }
878
879 }
Popular Tags