KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xml > internal > serialize > TextSerializer


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999-2002 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 1999, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58
59 // Sep 14, 2000:
60
// Fixed serializer to report IO exception directly, instead at
61
// the end of document processing.
62
// Reported by Patrick Higgins <phiggins@transzap.com>
63

64
65 package com.sun.org.apache.xml.internal.serialize;
66
67
68 import java.io.IOException JavaDoc;
69
70 import org.w3c.dom.Element JavaDoc;
71 import org.w3c.dom.Node JavaDoc;
72 import org.xml.sax.AttributeList JavaDoc;
73 import org.xml.sax.Attributes JavaDoc;
74 import org.xml.sax.SAXException JavaDoc;
75
76
77 /**
78  * Implements a text serializer supporting both DOM and SAX
79  * serializing. For usage instructions see {@link Serializer}.
80  * <p>
81  * If an output stream is used, the encoding is taken from the
82  * output format (defaults to <tt>UTF-8</tt>). If a writer is
83  * used, make sure the writer uses the same encoding (if applies)
84  * as specified in the output format.
85  * <p>
86  * The serializer supports both DOM and SAX. DOM serializing is done
87  * by calling {@link #serialize} and SAX serializing is done by firing
88  * SAX events and using the serializer as a document handler.
89  * <p>
90  * If an I/O exception occurs while serializing, the serializer
91  * will not throw an exception directly, but only throw it
92  * at the end of serializing (either DOM or SAX's {@link
93  * org.xml.sax.DocumentHandler#endDocument}.
94  *
95  *
96  * @version $Revision: 1.13 $ $Date: 2003/05/13 13:23:49 $
97  * @author <a HREF="mailto:arkin@intalio.com">Assaf Arkin</a>
98  * @see Serializer
99  */

100 public class TextSerializer
101     extends BaseMarkupSerializer
102 {
103
104
105     /**
106      * Constructs a new serializer. The serializer cannot be used without
107      * calling {@link #setOutputCharStream} or {@link #setOutputByteStream}
108      * first.
109      */

110     public TextSerializer()
111     {
112         super( new OutputFormat( Method.TEXT, null, false ) );
113     }
114
115
116     public void setOutputFormat( OutputFormat format )
117     {
118         super.setOutputFormat( format != null ? format : new OutputFormat( Method.TEXT, null, false ) );
119     }
120
121
122     //-----------------------------------------//
123
// SAX content handler serializing methods //
124
//-----------------------------------------//
125

126
127     public void startElement( String JavaDoc namespaceURI, String JavaDoc localName,
128                               String JavaDoc rawName, Attributes JavaDoc attrs )
129         throws SAXException JavaDoc
130     {
131         startElement( rawName == null ? localName : rawName, null );
132     }
133
134
135     public void endElement( String JavaDoc namespaceURI, String JavaDoc localName,
136                             String JavaDoc rawName )
137         throws SAXException JavaDoc
138     {
139         endElement( rawName == null ? localName : rawName );
140     }
141
142
143     //------------------------------------------//
144
// SAX document handler serializing methods //
145
//------------------------------000---------//
146

147
148     public void startElement( String JavaDoc tagName, AttributeList JavaDoc attrs )
149         throws SAXException JavaDoc
150     {
151         boolean preserveSpace;
152         ElementState state;
153
154         try {
155             state = getElementState();
156             if ( isDocumentState() ) {
157                 // If this is the root element handle it differently.
158
// If the first root element in the document, serialize
159
// the document's DOCTYPE. Space preserving defaults
160
// to that of the output format.
161
if ( ! _started )
162                     startDocument( tagName );
163             }
164             // For any other element, if first in parent, then
165
// use the parnet's space preserving.
166
preserveSpace = state.preserveSpace;
167
168             // Do not change the current element state yet.
169
// This only happens in endElement().
170

171             // Ignore all other attributes of the element, only printing
172
// its contents.
173

174             // Now it's time to enter a new element state
175
// with the tag name and space preserving.
176
// We still do not change the curent element state.
177
state = enterElementState( null, null, tagName, preserveSpace );
178         } catch ( IOException JavaDoc except ) {
179             throw new SAXException JavaDoc( except );
180         }
181     }
182
183
184     public void endElement( String JavaDoc tagName )
185         throws SAXException JavaDoc
186     {
187         try {
188             endElementIO( tagName );
189         } catch ( IOException JavaDoc except ) {
190             throw new SAXException JavaDoc( except );
191         }
192     }
193
194
195     public void endElementIO( String JavaDoc tagName )
196         throws IOException JavaDoc
197     {
198         ElementState state;
199
200         // Works much like content() with additions for closing
201
// an element. Note the different checks for the closed
202
// element's state and the parent element's state.
203
state = getElementState();
204         // Leave the element state and update that of the parent
205
// (if we're not root) to not empty and after element.
206
state = leaveElementState();
207         state.afterElement = true;
208         state.empty = false;
209         if ( isDocumentState() )
210             _printer.flush();
211     }
212
213
214     public void processingInstructionIO( String JavaDoc target, String JavaDoc code ) throws IOException JavaDoc
215     {
216     }
217
218
219     public void comment( String JavaDoc text )
220     {
221     }
222
223
224     public void comment( char[] chars, int start, int length )
225     {
226     }
227
228
229     public void characters( char[] chars, int start, int length )
230         throws SAXException JavaDoc
231     {
232         ElementState state;
233
234         try {
235             state = content();
236             state.doCData = state.inCData = false;
237             printText( chars, start, length, true, true );
238         } catch ( IOException JavaDoc except ) {
239             throw new SAXException JavaDoc( except );
240         }
241     }
242
243
244     protected void characters( String JavaDoc text, boolean unescaped )
245         throws IOException JavaDoc
246     {
247         ElementState state;
248
249         state = content();
250         state.doCData = state.inCData = false;
251         printText( text, true, true );
252     }
253
254
255     //------------------------------------------//
256
// Generic node serializing methods methods //
257
//------------------------------------------//
258

259
260     /**
261      * Called to serialize the document's DOCTYPE by the root element.
262      * <p>
263      * This method will check if it has not been called before ({@link #_started}),
264      * will serialize the document type declaration, and will serialize all
265      * pre-root comments and PIs that were accumulated in the document
266      * (see {@link #serializePreRoot}). Pre-root will be serialized even if
267      * this is not the first root element of the document.
268      */

269     protected void startDocument( String JavaDoc rootTagName )
270         throws IOException JavaDoc
271     {
272         // Required to stop processing the DTD, even though the DTD
273
// is not printed.
274
_printer.leaveDTD();
275
276         _started = true;
277         // Always serialize these, even if not te first root element.
278
serializePreRoot();
279     }
280
281
282     /**
283      * Called to serialize a DOM element. Equivalent to calling {@link
284      * #startElement}, {@link #endElement} and serializing everything
285      * inbetween, but better optimized.
286      */

287     protected void serializeElement( Element JavaDoc elem )
288         throws IOException JavaDoc
289     {
290         Node JavaDoc child;
291         ElementState state;
292         boolean preserveSpace;
293         String JavaDoc tagName;
294
295         tagName = elem.getTagName();
296         state = getElementState();
297         if ( isDocumentState() ) {
298             // If this is the root element handle it differently.
299
// If the first root element in the document, serialize
300
// the document's DOCTYPE. Space preserving defaults
301
// to that of the output format.
302
if ( ! _started )
303                 startDocument( tagName );
304         }
305         // For any other element, if first in parent, then
306
// use the parnet's space preserving.
307
preserveSpace = state.preserveSpace;
308
309         // Do not change the current element state yet.
310
// This only happens in endElement().
311

312         // Ignore all other attributes of the element, only printing
313
// its contents.
314

315         // If element has children, then serialize them, otherwise
316
// serialize en empty tag.
317
if ( elem.hasChildNodes() ) {
318             // Enter an element state, and serialize the children
319
// one by one. Finally, end the element.
320
state = enterElementState( null, null, tagName, preserveSpace );
321             child = elem.getFirstChild();
322             while ( child != null ) {
323                 serializeNode( child );
324                 child = child.getNextSibling();
325             }
326             endElementIO( tagName );
327         } else {
328             if ( ! isDocumentState() ) {
329                 // After element but parent element is no longer empty.
330
state.afterElement = true;
331                 state.empty = false;
332             }
333         }
334     }
335
336
337     /**
338      * Serialize the DOM node. This method is unique to the Text serializer.
339      *
340      * @param node The node to serialize
341      */

342     protected void serializeNode( Node JavaDoc node )
343         throws IOException JavaDoc
344     {
345         // Based on the node type call the suitable SAX handler.
346
// Only comments entities and documents which are not
347
// handled by SAX are serialized directly.
348
switch ( node.getNodeType() ) {
349         case Node.TEXT_NODE : {
350             String JavaDoc text;
351
352             text = node.getNodeValue();
353             if ( text != null )
354                 characters( node.getNodeValue(), true );
355             break;
356         }
357
358         case Node.CDATA_SECTION_NODE : {
359             String JavaDoc text;
360
361             text = node.getNodeValue();
362             if ( text != null )
363                 characters( node.getNodeValue(), true );
364             break;
365         }
366
367         case Node.COMMENT_NODE :
368             break;
369
370         case Node.ENTITY_REFERENCE_NODE :
371             // Ignore.
372
break;
373
374         case Node.PROCESSING_INSTRUCTION_NODE :
375             break;
376
377         case Node.ELEMENT_NODE :
378             serializeElement( (Element JavaDoc) node );
379             break;
380
381         case Node.DOCUMENT_NODE :
382             // !!! Fall through
383
case Node.DOCUMENT_FRAGMENT_NODE : {
384             Node JavaDoc child;
385
386             // By definition this will happen if the node is a document,
387
// document fragment, etc. Just serialize its contents. It will
388
// work well for other nodes that we do not know how to serialize.
389
child = node.getFirstChild();
390             while ( child != null ) {
391                 serializeNode( child );
392                 child = child.getNextSibling();
393             }
394             break;
395         }
396
397         default:
398             break;
399         }
400     }
401
402
403     protected ElementState content(boolean ignorable)
404     {
405         ElementState state;
406
407         state = getElementState();
408         if ( ! isDocumentState() ) {
409             // If this is the first content in the element,
410
// change the state to not-empty.
411
if ( state.empty )
412                 state.empty = false;
413             // Except for one content type, all of them
414
// are not last element. That one content
415
// type will take care of itself.
416
state.afterElement = false;
417         }
418         return state;
419     }
420
421
422     protected String JavaDoc getEntityRef( int ch )
423     {
424         return null;
425     }
426
427
428 }
429
430
431
Popular Tags