KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > xml > fastinfoset > stax > StAXDocumentSerializer


1 /*
2  * Fast Infoset ver. 0.1 software ("Software")
3  *
4  * Copyright, 2004-2005 Sun Microsystems, Inc. All Rights Reserved.
5  *
6  * Software is licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License. You may
8  * obtain a copy of the License at:
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15  * License for the specific language governing permissions and limitations.
16  *
17  * Sun supports and benefits from the global community of open source
18  * developers, and thanks the community for its important contributions and
19  * open standards-based technology, which Sun has adopted into many of its
20  * products.
21  *
22  * Please note that portions of Software may be provided with notices and
23  * open source licenses from such communities and third parties that govern the
24  * use of those portions, and any licenses granted hereunder do not alter any
25  * rights and obligations you may have under such open source licenses,
26  * however, the disclaimer of warranty and limitation of liability provisions
27  * in this License will apply to all Software in this distribution.
28  *
29  * You acknowledge that the Software is not designed, licensed or intended
30  * for use in the design, construction, operation or maintenance of any nuclear
31  * facility.
32  *
33  * Apache License
34  * Version 2.0, January 2004
35  * http://www.apache.org/licenses/
36  *
37  */

38
39
40 package com.sun.xml.fastinfoset.stax;
41
42 import com.sun.xml.fastinfoset.Encoder;
43 import com.sun.xml.fastinfoset.EncodingConstants;
44 import java.io.IOException JavaDoc;
45 import java.io.OutputStream JavaDoc;
46 import java.util.EmptyStackException JavaDoc;
47 import java.util.Enumeration JavaDoc;
48 import java.util.Iterator JavaDoc;
49 import javax.xml.namespace.NamespaceContext JavaDoc;
50 import javax.xml.stream.XMLStreamException;
51 import javax.xml.stream.XMLStreamWriter;
52 import org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
53 import org.xml.sax.helpers.NamespaceSupport JavaDoc;
54 import com.sun.xml.fastinfoset.CommonResourceBundle;
55
56 public class StAXDocumentSerializer extends Encoder implements XMLStreamWriter {
57     protected StAXManager _manager;
58     
59     protected String JavaDoc _encoding;
60     /**
61      * Local name of current element.
62      */

63     protected String JavaDoc _currentLocalName;
64     
65     /**
66      * Namespace of current element.
67      */

68     protected String JavaDoc _currentUri;
69     
70     /**
71      * Prefix of current element.
72      */

73     protected String JavaDoc _currentPrefix;
74
75    /**
76      * This flag indicates when there is a pending start element event.
77      */

78     protected boolean _inStartElement = false;
79     
80     /**
81      * This flag indicates if the current element is empty.
82      */

83     protected boolean _isEmptyElement = false;
84
85     /**
86      * List of attributes qnames and values defined in the current element.
87      */

88     protected String JavaDoc[] _attributesArray = new String JavaDoc[4 * 16];
89     protected int _attributesArrayIndex = 0;
90     
91     /**
92      * Mapping between uris and prefixes.
93      */

94     protected NamespaceSupport JavaDoc _nsSupport = new NamespaceSupport JavaDoc();
95     
96     protected boolean[] _nsSupportContextStack = new boolean[32];
97     protected int _stackCount = -1;
98     
99     protected NamespaceContext JavaDoc _nsContext = new NamespaceContextImpl();
100
101     /**
102      * List of namespaces defined in the current element.
103      */

104     protected String JavaDoc[] _namespacesArray = new String JavaDoc[2 * 8];
105     protected int _namespacesArrayIndex = 0;
106     
107     public StAXDocumentSerializer() {
108     }
109     
110     public StAXDocumentSerializer(OutputStream JavaDoc outputStream) {
111         setOutputStream(outputStream);
112     }
113
114     public StAXDocumentSerializer(OutputStream JavaDoc outputStream, StAXManager manager) {
115         setOutputStream(outputStream);
116         _manager = manager;
117     }
118     
119     public void reset() {
120         super.reset();
121         
122         _attributesArrayIndex = 0;
123         _namespacesArrayIndex = 0;
124         _nsSupport.reset();
125         _stackCount = -1;
126                 
127         _currentUri = _currentPrefix = null;
128         _currentLocalName = null;
129         
130         _inStartElement = _isEmptyElement = false;
131     }
132     
133     // -- XMLStreamWriter Interface -------------------------------------------
134

135     public void writeStartDocument() throws XMLStreamException {
136         writeStartDocument("finf", "1.0");
137     }
138     
139     public void writeStartDocument(String JavaDoc version) throws XMLStreamException {
140         writeStartDocument("finf", version);
141     }
142     
143     public void writeStartDocument(String JavaDoc encoding, String JavaDoc version)
144         throws XMLStreamException
145     {
146         reset();
147         
148         try {
149             encodeHeader(false);
150             encodeInitialVocabulary();
151         } catch (IOException JavaDoc e) {
152             throw new XMLStreamException(e);
153         }
154     }
155     
156     public void writeEndDocument() throws XMLStreamException {
157         // Need to flush a pending empty element?
158
if (_inStartElement) {
159 // encodeTerminationAndCurrentElement();
160
}
161
162         try {
163             // TODO
164
// Use nsSupport to terminate all elements not terminated
165
// by writeEndElement
166

167             
168             encodeDocumentTermination();
169         }
170         catch (IOException JavaDoc e) {
171             throw new XMLStreamException(e);
172         }
173     }
174     
175     public void close() throws XMLStreamException {
176         reset();
177     }
178     
179     public void flush() throws XMLStreamException {
180         try {
181             _s.flush();
182         }
183         catch (IOException JavaDoc e) {
184             throw new XMLStreamException(e);
185         }
186     }
187     
188     public void writeStartElement(String JavaDoc localName)
189         throws XMLStreamException
190     {
191         // TODO is it necessary for FI to obtain the default namespace in scope?
192
writeStartElement("", localName, "");
193     }
194     
195     public void writeStartElement(String JavaDoc namespaceURI, String JavaDoc localName)
196         throws XMLStreamException
197     {
198         writeStartElement(getPrefix(namespaceURI), localName, namespaceURI);
199     }
200     
201     public void writeStartElement(String JavaDoc prefix, String JavaDoc localName,
202         String JavaDoc namespaceURI) throws XMLStreamException
203     {
204         encodeTerminationAndCurrentElement(false);
205               
206         _inStartElement = true;
207         _isEmptyElement = false;
208
209         _currentLocalName = localName;
210         _currentPrefix = prefix;
211         _currentUri = namespaceURI;
212
213         _stackCount++;
214         if (_stackCount == _nsSupportContextStack.length) {
215             boolean[] nsSupportContextStack = new boolean[_stackCount * 2];
216             System.arraycopy(_nsSupportContextStack, 0, nsSupportContextStack, 0, _nsSupportContextStack.length);
217             _nsSupportContextStack = nsSupportContextStack;
218         }
219         
220         _nsSupportContextStack[_stackCount] = false;
221         // _nsSupport.pushContext();
222
}
223     
224     public void writeEmptyElement(String JavaDoc localName)
225         throws XMLStreamException
226     {
227         writeEmptyElement("", localName, "");
228     }
229     
230     public void writeEmptyElement(String JavaDoc namespaceURI, String JavaDoc localName)
231         throws XMLStreamException
232     {
233         writeEmptyElement(getPrefix(namespaceURI), localName, namespaceURI);
234     }
235     
236     public void writeEmptyElement(String JavaDoc prefix, String JavaDoc localName,
237         String JavaDoc namespaceURI) throws XMLStreamException
238     {
239         encodeTerminationAndCurrentElement(false);
240         
241         _isEmptyElement = _inStartElement = true;
242         
243         _currentLocalName = localName;
244         _currentPrefix = prefix;
245         _currentUri = namespaceURI;
246         
247         _stackCount++;
248         if (_stackCount == _nsSupportContextStack.length) {
249             boolean[] nsSupportContextStack = new boolean[_stackCount * 2];
250             System.arraycopy(_nsSupportContextStack, 0, nsSupportContextStack, 0, _nsSupportContextStack.length);
251             _nsSupportContextStack = nsSupportContextStack;
252         }
253         
254         _nsSupportContextStack[_stackCount] = false;
255         //_nsSupport.pushContext();
256
}
257         
258     public void writeEndElement() throws XMLStreamException {
259         if (_inStartElement) {
260             encodeTerminationAndCurrentElement(false);
261         }
262             
263         try {
264             encodeElementTermination();
265             if (_nsSupportContextStack[_stackCount--] == true) {
266                 _nsSupport.popContext();
267             }
268         }
269         catch (IOException JavaDoc e) {
270             throw new XMLStreamException(e);
271         }
272         catch (EmptyStackException JavaDoc e) {
273             throw new XMLStreamException(e);
274         }
275     }
276
277     
278     public void writeAttribute(String JavaDoc localName, String JavaDoc value)
279         throws XMLStreamException
280     {
281         writeAttribute("", "", localName, value);
282     }
283     
284     public void writeAttribute(String JavaDoc namespaceURI, String JavaDoc localName,
285         String JavaDoc value) throws XMLStreamException
286     {
287         String JavaDoc prefix = "";
288         
289         // Find prefix for attribute, ignoring default namespace
290
if (namespaceURI.length() > 0) {
291             prefix = _nsSupport.getPrefix(namespaceURI);
292
293             // Undeclared prefix or ignorable default ns?
294
if (prefix == null || prefix.length() == 0) {
295                 // Workaround for BUG in SAX NamespaceSupport helper
296
// which incorrectly defines namespace declaration URI
297
if (namespaceURI == EncodingConstants.XMLNS_NAMESPACE_NAME ||
298                         namespaceURI.equals(EncodingConstants.XMLNS_NAMESPACE_NAME)) {
299                     // TODO
300
// Need to check carefully the rule for the writing of
301
// namespaces in StAX. Is it safe to ignore such
302
// attributes, as declarations will be made using the
303
// writeNamespace method
304
return;
305                 }
306                 throw new XMLStreamException(CommonResourceBundle.getInstance().getString("message.URIUnbound", new Object JavaDoc[]{namespaceURI}));
307             }
308         }
309         writeAttribute(prefix, namespaceURI, localName, value);
310     }
311         
312     public void writeAttribute(String JavaDoc prefix, String JavaDoc namespaceURI,
313         String JavaDoc localName, String JavaDoc value) throws XMLStreamException
314     {
315         if (!_inStartElement) {
316             throw new IllegalStateException JavaDoc(CommonResourceBundle.getInstance().getString("message.attributeWritingNotAllowed"));
317         }
318
319         // TODO
320
// Need to check carefully the rule for the writing of
321
// namespaces in StAX. Is it safe to ignore such
322
// attributes, as declarations will be made using the
323
// writeNamespace method
324
if (namespaceURI == EncodingConstants.XMLNS_NAMESPACE_NAME ||
325                 namespaceURI.equals(EncodingConstants.XMLNS_NAMESPACE_NAME)) {
326             return;
327         }
328
329         if (_attributesArrayIndex == _attributesArray.length) {
330             final String JavaDoc[] attributesArray = new String JavaDoc[_attributesArrayIndex * 2];
331             System.arraycopy(_attributesArray, 0, attributesArray, 0, _attributesArrayIndex);
332             _attributesArray = attributesArray;
333         }
334         
335         _attributesArray[_attributesArrayIndex++] = namespaceURI;
336         _attributesArray[_attributesArrayIndex++] = prefix;
337         _attributesArray[_attributesArrayIndex++] = localName;
338         _attributesArray[_attributesArrayIndex++] = value;
339     }
340     
341     public void writeNamespace(String JavaDoc prefix, String JavaDoc namespaceURI)
342         throws XMLStreamException
343     {
344         if (prefix == null || prefix.length() == 0 || prefix.equals(EncodingConstants.XMLNS_NAMESPACE_PREFIX)) {
345             writeDefaultNamespace(namespaceURI);
346         }
347         else {
348             if (!_inStartElement) {
349                 throw new IllegalStateException JavaDoc(CommonResourceBundle.getInstance().getString("message.attributeWritingNotAllowed"));
350             }
351             
352             if (_namespacesArrayIndex == _namespacesArray.length) {
353                 final String JavaDoc[] namespacesArray = new String JavaDoc[_namespacesArrayIndex * 2];
354                 System.arraycopy(_namespacesArray, 0, namespacesArray, 0, _namespacesArrayIndex);
355                 _namespacesArray = namespacesArray;
356             }
357             
358             _namespacesArray[_namespacesArrayIndex++] = prefix;
359             _namespacesArray[_namespacesArrayIndex++] = namespaceURI;
360         }
361     }
362     
363     public void writeDefaultNamespace(String JavaDoc namespaceURI)
364         throws XMLStreamException
365     {
366         if (!_inStartElement) {
367             throw new IllegalStateException JavaDoc(CommonResourceBundle.getInstance().getString("message.attributeWritingNotAllowed"));
368         }
369         
370         if (_namespacesArrayIndex == _namespacesArray.length) {
371             final String JavaDoc[] namespacesArray = new String JavaDoc[_namespacesArrayIndex * 2];
372             System.arraycopy(_namespacesArray, 0, namespacesArray, 0, _namespacesArrayIndex);
373             _namespacesArray = namespacesArray;
374         }
375
376         _namespacesArray[_namespacesArrayIndex++] = "";
377         _namespacesArray[_namespacesArrayIndex++] = namespaceURI;
378     }
379     
380     public void writeComment(String JavaDoc data) throws XMLStreamException {
381         try {
382             encodeTerminationAndCurrentElement(true);
383
384             // TODO: avoid array copy here
385
encodeComment(data.toCharArray(), 0, data.length());
386         }
387         catch (IOException JavaDoc e) {
388             throw new XMLStreamException(e);
389         }
390     }
391     
392     public void writeProcessingInstruction(String JavaDoc target)
393         throws XMLStreamException
394     {
395         writeProcessingInstruction(target, "");
396     }
397     
398     public void writeProcessingInstruction(String JavaDoc target, String JavaDoc data)
399         throws XMLStreamException
400     {
401         try {
402             encodeTerminationAndCurrentElement(true);
403
404             encodeProcessingInstruction(target, data);
405         }
406         catch (IOException JavaDoc e) {
407             throw new XMLStreamException(e);
408         }
409     }
410     
411     public void writeCData(String JavaDoc data) throws XMLStreamException {
412         throw new UnsupportedOperationException JavaDoc(CommonResourceBundle.getInstance().getString("message.notImplemented"));
413    }
414     
415     public void writeDTD(String JavaDoc dtd) throws XMLStreamException {
416         throw new UnsupportedOperationException JavaDoc(CommonResourceBundle.getInstance().getString("message.notImplemented"));
417     }
418     
419     public void writeEntityRef(String JavaDoc name) throws XMLStreamException {
420         throw new UnsupportedOperationException JavaDoc(CommonResourceBundle.getInstance().getString("message.notImplemented"));
421     }
422         
423     public void writeCharacters(String JavaDoc text) throws XMLStreamException {
424          try {
425             final int length = text.length();
426             if (length == 0) {
427                 return;
428             } else if (length < _charBuffer.length) {
429                 encodeTerminationAndCurrentElement(true);
430                 
431                 text.getChars(0, length, _charBuffer, 0);
432                 encodeCharacters(_charBuffer, 0, length);
433             } else {
434                 encodeTerminationAndCurrentElement(true);
435                 
436                 final char ch[] = text.toCharArray();
437                 encodeCharactersNoClone(ch, 0, length);
438             }
439         }
440         catch (IOException JavaDoc e) {
441             throw new XMLStreamException(e);
442         }
443     }
444     
445     public void writeCharacters(char[] text, int start, int len)
446         throws XMLStreamException
447     {
448          try {
449             if (len == 0) {
450                 return;
451             }
452
453             encodeTerminationAndCurrentElement(true);
454
455             encodeCharacters(text, start, len);
456         }
457         catch (IOException JavaDoc e) {
458             throw new XMLStreamException(e);
459         }
460     }
461
462     public String JavaDoc getPrefix(String JavaDoc uri) throws XMLStreamException {
463         return _nsSupport.getPrefix(uri);
464     }
465     
466     public void setPrefix(String JavaDoc prefix, String JavaDoc uri)
467         throws XMLStreamException
468     {
469         if (_stackCount > -1 && _nsSupportContextStack[_stackCount] == false) {
470             _nsSupportContextStack[_stackCount] = true;
471             _nsSupport.pushContext();
472         }
473         
474         _nsSupport.declarePrefix(prefix, uri);
475     }
476     
477     public void setDefaultNamespace(String JavaDoc uri) throws XMLStreamException {
478         setPrefix("", uri);
479     }
480     
481     /**
482      * Sets the current namespace context for prefix and uri bindings.
483      * This context becomes the root namespace context for writing and
484      * will replace the current root namespace context. Subsequent calls
485      * to setPrefix and setDefaultNamespace will bind namespaces using
486      * the context passed to the method as the root context for resolving
487      * namespaces. This method may only be called once at the start of
488      * the document. It does not cause the namespaces to be declared.
489      * If a namespace URI to prefix mapping is found in the namespace
490      * context it is treated as declared and the prefix may be used
491      * by the StreamWriter.
492      * @param context the namespace context to use for this writer, may not be null
493      * @throws XMLStreamException
494      */

495     public void setNamespaceContext(NamespaceContext JavaDoc context)
496         throws XMLStreamException
497     {
498         throw new UnsupportedOperationException JavaDoc("setNamespaceContext");
499     }
500     
501     public NamespaceContext JavaDoc getNamespaceContext() {
502         return _nsContext;
503     }
504     
505     public Object JavaDoc getProperty(java.lang.String JavaDoc name)
506         throws IllegalArgumentException JavaDoc
507     {
508         if (_manager != null) {
509             return _manager.getProperty(name);
510         }
511         return null;
512     }
513
514     public void setManager(StAXManager manager) {
515         _manager = manager;
516     }
517     
518     public void setEncoding(String JavaDoc encoding) {
519         _encoding = encoding;
520     }
521     
522     protected class NamespaceContextImpl implements NamespaceContext JavaDoc {
523         public final String JavaDoc getNamespaceURI(String JavaDoc prefix) {
524             return _nsSupport.getURI(prefix);
525         }
526   
527         public final String JavaDoc getPrefix(String JavaDoc namespaceURI) {
528             return _nsSupport.getPrefix(namespaceURI);
529         }
530
531         public final Iterator JavaDoc getPrefixes(String JavaDoc namespaceURI) {
532             final Enumeration JavaDoc e = _nsSupport.getPrefixes(namespaceURI);
533             
534             return new Iterator JavaDoc() {
535                     public boolean hasNext() {
536                         return e.hasMoreElements();
537                     }
538
539                     public Object JavaDoc next() {
540                         return e.nextElement();
541                     }
542
543                     public void remove() {
544                         throw new UnsupportedOperationException JavaDoc();
545                     }
546                 };
547         }
548     }
549
550     public void writeOctets(byte[] b, int start, int len)
551         throws XMLStreamException
552     {
553          try {
554             if (len == 0) {
555                 return;
556             }
557
558             encodeTerminationAndCurrentElement(true);
559
560             encodeCIIOctetAlgorithmData(EncodingAlgorithmIndexes.BASE64, b, start, len);
561         }
562         catch (IOException JavaDoc e) {
563             throw new XMLStreamException(e);
564         }
565     }
566     
567     protected void encodeTerminationAndCurrentElement(boolean terminateAfter) throws XMLStreamException {
568         try {
569             encodeTermination();
570             
571             if (_inStartElement) {
572
573                 _b = EncodingConstants.ELEMENT;
574                 if (_attributesArrayIndex > 0) {
575                     _b |= EncodingConstants.ELEMENT_ATTRIBUTE_FLAG;
576                 }
577
578                 // Encode namespace decls associated with this element
579
if (_namespacesArrayIndex > 0) {
580                     write(_b | EncodingConstants.ELEMENT_NAMESPACES_FLAG);
581                     for (int i = 0; i < _namespacesArrayIndex;) {
582                         encodeNamespaceAttribute(_namespacesArray[i++], _namespacesArray[i++]);
583                     }
584                     _namespacesArrayIndex = 0;
585                     
586                     write(EncodingConstants.TERMINATOR);
587
588                     _b = 0;
589                 }
590
591                 // Encode element and its attributes
592
encodeElementQualifiedNameOnThirdBit(_currentUri, _currentPrefix, _currentLocalName);
593
594                 for (int i = 0; i < _attributesArrayIndex;) {
595                     encodeAttributeQualifiedNameOnSecondBit(
596                             _attributesArray[i++], _attributesArray[i++], _attributesArray[i++]);
597
598                     final String JavaDoc value = _attributesArray[i];
599                     _attributesArray[i++] = null;
600                     final boolean addToTable = (value.length() < attributeValueSizeConstraint) ? true : false;
601                     encodeNonIdentifyingStringOnFirstBit(value, _v.attributeValue, addToTable);
602                     
603                     _b = EncodingConstants.TERMINATOR;
604                     _terminate = true;
605                 }
606                 _attributesArrayIndex = 0;
607                 _inStartElement = false;
608
609                 if (_isEmptyElement) {
610                     encodeElementTermination();
611                     if (_nsSupportContextStack[_stackCount--] == true) {
612                         _nsSupport.popContext();
613                     }
614                     
615                     _isEmptyElement = false;
616                 }
617                 
618                 if (terminateAfter) {
619                     encodeTermination();
620                 }
621             }
622         } catch (IOException JavaDoc e) {
623             throw new XMLStreamException(e);
624         }
625     }
626 }
Popular Tags