KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xml > serialize > TextSerializer


1 /*
2  * Copyright 1999-2002,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17
18 // Sep 14, 2000:
19
// Fixed serializer to report IO exception directly, instead at
20
// the end of document processing.
21
// Reported by Patrick Higgins <phiggins@transzap.com>
22

23
24 package org.apache.xml.serialize;
25
26
27 import java.io.IOException JavaDoc;
28
29 import org.w3c.dom.Element JavaDoc;
30 import org.w3c.dom.Node JavaDoc;
31 import org.xml.sax.AttributeList JavaDoc;
32 import org.xml.sax.Attributes JavaDoc;
33 import org.xml.sax.SAXException JavaDoc;
34
35
36 /**
37  * Implements a text serializer supporting both DOM and SAX
38  * serializing. For usage instructions see {@link Serializer}.
39  * <p>
40  * If an output stream is used, the encoding is taken from the
41  * output format (defaults to <tt>UTF-8</tt>). If a writer is
42  * used, make sure the writer uses the same encoding (if applies)
43  * as specified in the output format.
44  * <p>
45  * The serializer supports both DOM and SAX. DOM serializing is done
46  * by calling {@link #serialize} and SAX serializing is done by firing
47  * SAX events and using the serializer as a document handler.
48  * <p>
49  * If an I/O exception occurs while serializing, the serializer
50  * will not throw an exception directly, but only throw it
51  * at the end of serializing (either DOM or SAX's {@link
52  * org.xml.sax.DocumentHandler#endDocument}.
53  *
54  *
55  * @version $Revision: 1.14 $ $Date: 2004/02/24 23:34:03 $
56  * @author <a HREF="mailto:arkin@intalio.com">Assaf Arkin</a>
57  * @see Serializer
58  */

59 public class TextSerializer
60     extends BaseMarkupSerializer
61 {
62
63
64     /**
65      * Constructs a new serializer. The serializer cannot be used without
66      * calling {@link #setOutputCharStream} or {@link #setOutputByteStream}
67      * first.
68      */

69     public TextSerializer()
70     {
71         super( new OutputFormat( Method.TEXT, null, false ) );
72     }
73
74
75     public void setOutputFormat( OutputFormat format )
76     {
77         super.setOutputFormat( format != null ? format : new OutputFormat( Method.TEXT, null, false ) );
78     }
79
80
81     //-----------------------------------------//
82
// SAX content handler serializing methods //
83
//-----------------------------------------//
84

85
86     public void startElement( String JavaDoc namespaceURI, String JavaDoc localName,
87                               String JavaDoc rawName, Attributes JavaDoc attrs )
88         throws SAXException JavaDoc
89     {
90         startElement( rawName == null ? localName : rawName, null );
91     }
92
93
94     public void endElement( String JavaDoc namespaceURI, String JavaDoc localName,
95                             String JavaDoc rawName )
96         throws SAXException JavaDoc
97     {
98         endElement( rawName == null ? localName : rawName );
99     }
100
101
102     //------------------------------------------//
103
// SAX document handler serializing methods //
104
//------------------------------000---------//
105

106
107     public void startElement( String JavaDoc tagName, AttributeList JavaDoc attrs )
108         throws SAXException JavaDoc
109     {
110         boolean preserveSpace;
111         ElementState state;
112
113         try {
114             state = getElementState();
115             if ( isDocumentState() ) {
116                 // If this is the root element handle it differently.
117
// If the first root element in the document, serialize
118
// the document's DOCTYPE. Space preserving defaults
119
// to that of the output format.
120
if ( ! _started )
121                     startDocument( tagName );
122             }
123             // For any other element, if first in parent, then
124
// use the parnet's space preserving.
125
preserveSpace = state.preserveSpace;
126
127             // Do not change the current element state yet.
128
// This only happens in endElement().
129

130             // Ignore all other attributes of the element, only printing
131
// its contents.
132

133             // Now it's time to enter a new element state
134
// with the tag name and space preserving.
135
// We still do not change the curent element state.
136
state = enterElementState( null, null, tagName, preserveSpace );
137         } catch ( IOException JavaDoc except ) {
138             throw new SAXException JavaDoc( except );
139         }
140     }
141
142
143     public void endElement( String JavaDoc tagName )
144         throws SAXException JavaDoc
145     {
146         try {
147             endElementIO( tagName );
148         } catch ( IOException JavaDoc except ) {
149             throw new SAXException JavaDoc( except );
150         }
151     }
152
153
154     public void endElementIO( String JavaDoc tagName )
155         throws IOException JavaDoc
156     {
157         ElementState state;
158
159         // Works much like content() with additions for closing
160
// an element. Note the different checks for the closed
161
// element's state and the parent element's state.
162
state = getElementState();
163         // Leave the element state and update that of the parent
164
// (if we're not root) to not empty and after element.
165
state = leaveElementState();
166         state.afterElement = true;
167         state.empty = false;
168         if ( isDocumentState() )
169             _printer.flush();
170     }
171
172
173     public void processingInstructionIO( String JavaDoc target, String JavaDoc code ) throws IOException JavaDoc
174     {
175     }
176
177
178     public void comment( String JavaDoc text )
179     {
180     }
181
182
183     public void comment( char[] chars, int start, int length )
184     {
185     }
186
187
188     public void characters( char[] chars, int start, int length )
189         throws SAXException JavaDoc
190     {
191         ElementState state;
192
193         try {
194             state = content();
195             state.doCData = state.inCData = false;
196             printText( chars, start, length, true, true );
197         } catch ( IOException JavaDoc except ) {
198             throw new SAXException JavaDoc( except );
199         }
200     }
201
202
203     protected void characters( String JavaDoc text, boolean unescaped )
204         throws IOException JavaDoc
205     {
206         ElementState state;
207
208         state = content();
209         state.doCData = state.inCData = false;
210         printText( text, true, true );
211     }
212
213
214     //------------------------------------------//
215
// Generic node serializing methods methods //
216
//------------------------------------------//
217

218
219     /**
220      * Called to serialize the document's DOCTYPE by the root element.
221      * <p>
222      * This method will check if it has not been called before ({@link #_started}),
223      * will serialize the document type declaration, and will serialize all
224      * pre-root comments and PIs that were accumulated in the document
225      * (see {@link #serializePreRoot}). Pre-root will be serialized even if
226      * this is not the first root element of the document.
227      */

228     protected void startDocument( String JavaDoc rootTagName )
229         throws IOException JavaDoc
230     {
231         // Required to stop processing the DTD, even though the DTD
232
// is not printed.
233
_printer.leaveDTD();
234
235         _started = true;
236         // Always serialize these, even if not te first root element.
237
serializePreRoot();
238     }
239
240
241     /**
242      * Called to serialize a DOM element. Equivalent to calling {@link
243      * #startElement}, {@link #endElement} and serializing everything
244      * inbetween, but better optimized.
245      */

246     protected void serializeElement( Element JavaDoc elem )
247         throws IOException JavaDoc
248     {
249         Node JavaDoc child;
250         ElementState state;
251         boolean preserveSpace;
252         String JavaDoc tagName;
253
254         tagName = elem.getTagName();
255         state = getElementState();
256         if ( isDocumentState() ) {
257             // If this is the root element handle it differently.
258
// If the first root element in the document, serialize
259
// the document's DOCTYPE. Space preserving defaults
260
// to that of the output format.
261
if ( ! _started )
262                 startDocument( tagName );
263         }
264         // For any other element, if first in parent, then
265
// use the parnet's space preserving.
266
preserveSpace = state.preserveSpace;
267
268         // Do not change the current element state yet.
269
// This only happens in endElement().
270

271         // Ignore all other attributes of the element, only printing
272
// its contents.
273

274         // If element has children, then serialize them, otherwise
275
// serialize en empty tag.
276
if ( elem.hasChildNodes() ) {
277             // Enter an element state, and serialize the children
278
// one by one. Finally, end the element.
279
state = enterElementState( null, null, tagName, preserveSpace );
280             child = elem.getFirstChild();
281             while ( child != null ) {
282                 serializeNode( child );
283                 child = child.getNextSibling();
284             }
285             endElementIO( tagName );
286         } else {
287             if ( ! isDocumentState() ) {
288                 // After element but parent element is no longer empty.
289
state.afterElement = true;
290                 state.empty = false;
291             }
292         }
293     }
294
295
296     /**
297      * Serialize the DOM node. This method is unique to the Text serializer.
298      *
299      * @param node The node to serialize
300      */

301     protected void serializeNode( Node JavaDoc node )
302         throws IOException JavaDoc
303     {
304         // Based on the node type call the suitable SAX handler.
305
// Only comments entities and documents which are not
306
// handled by SAX are serialized directly.
307
switch ( node.getNodeType() ) {
308         case Node.TEXT_NODE : {
309             String JavaDoc text;
310
311             text = node.getNodeValue();
312             if ( text != null )
313                 characters( node.getNodeValue(), true );
314             break;
315         }
316
317         case Node.CDATA_SECTION_NODE : {
318             String JavaDoc text;
319
320             text = node.getNodeValue();
321             if ( text != null )
322                 characters( node.getNodeValue(), true );
323             break;
324         }
325
326         case Node.COMMENT_NODE :
327             break;
328
329         case Node.ENTITY_REFERENCE_NODE :
330             // Ignore.
331
break;
332
333         case Node.PROCESSING_INSTRUCTION_NODE :
334             break;
335
336         case Node.ELEMENT_NODE :
337             serializeElement( (Element JavaDoc) node );
338             break;
339
340         case Node.DOCUMENT_NODE :
341             // !!! Fall through
342
case Node.DOCUMENT_FRAGMENT_NODE : {
343             Node JavaDoc child;
344
345             // By definition this will happen if the node is a document,
346
// document fragment, etc. Just serialize its contents. It will
347
// work well for other nodes that we do not know how to serialize.
348
child = node.getFirstChild();
349             while ( child != null ) {
350                 serializeNode( child );
351                 child = child.getNextSibling();
352             }
353             break;
354         }
355
356         default:
357             break;
358         }
359     }
360
361
362     protected ElementState content()
363     {
364         ElementState state;
365
366         state = getElementState();
367         if ( ! isDocumentState() ) {
368             // If this is the first content in the element,
369
// change the state to not-empty.
370
if ( state.empty )
371                 state.empty = false;
372             // Except for one content type, all of them
373
// are not last element. That one content
374
// type will take care of itself.
375
state.afterElement = false;
376         }
377         return state;
378     }
379
380
381     protected String JavaDoc getEntityRef( int ch )
382     {
383         return null;
384     }
385
386
387 }
388
389
390
Popular Tags