KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jahia > services > importexport > DataWriter


1 // DataWriter.java - XML writer for data-oriented files.
2

3 package org.jahia.services.importexport;
4
5 import java.io.Writer JavaDoc;
6 import java.util.Stack JavaDoc;
7
8 import org.xml.sax.Attributes JavaDoc;
9 import org.xml.sax.SAXException JavaDoc;
10 import org.xml.sax.XMLReader JavaDoc;
11
12
13 /**
14  * Write data- or field-oriented XML.
15  *
16  * <p>This filter pretty-prints field-oriented XML without mixed content.
17  * all added indentation and newlines will be passed on down
18  * the filter chain (if any).</p>
19  *
20  * <p>In general, all whitespace in an XML document is potentially
21  * significant, so a general-purpose XML writing tool like the
22  * {@link com.megginson.sax.XMLWriter XMLWriter} class cannot
23  * add newlines or indentation.</p>
24  *
25  * <p>There is, however, a large class of XML documents where information
26  * is strictly fielded: each element contains either character data
27  * or other elements, but not both. For this special case, it is possible
28  * for a writing tool to provide automatic indentation and newlines
29  * without requiring extra work from the user. Note that this class
30  * will likely not yield appropriate results for document-oriented
31  * XML like XHTML pages, which mix character data and elements together.</p>
32  *
33  * <p>This writer will automatically place each start tag on a new line,
34  * optionally indented if an indent step is provided (by default, there
35  * is no indentation). If an element contains other elements, the end
36  * tag will also appear on a new line with leading indentation. Consider,
37  * for example, the following code:</p>
38  *
39  * <pre>
40  * DataWriter w = new DataWriter();
41  *
42  * w.setIndentStep(2);
43  * w.startDocument();
44  * w.startElement("Person");
45  * w.dataElement("name", "Jane Smith");
46  * w.dataElement("date-of-birth", "1965-05-23");
47  * w.dataElement("citizenship", "US");
48  * w.endElement("Person");
49  * w.endDocument();
50  * </pre>
51  *
52  * <p>This code will produce the following document:</p>
53  *
54  * <pre>
55  * &lt;?xml version="1.0" standalone="yes"?>
56  *
57  * &lt;Person>
58  * &lt;name>Jane Smith&lt;/name>
59  * &lt;date-of-birth>1965-05-23&lt;/date-of-birth>
60  * &lt;citizenship>US&lt;/citizenship>
61  * &lt;/Person>
62  * </pre>
63  *
64  * <p>This class inherits from {@link com.megginson.sax.XMLWriter
65  * XMLWriter}, and provides all of the same support for Namespaces.</p>
66  *
67  * @author David Megginson, david@megginson.com
68  * @version 0.2
69  * @see com.megginson.sax.XMLWriter
70  */

71 public class DataWriter extends XMLWriter
72 {
73
74
75
76
77     ////////////////////////////////////////////////////////////////////
78
// Constructors.
79
////////////////////////////////////////////////////////////////////
80

81
82     /**
83      * Create a new data writer for standard output.
84      */

85     public DataWriter ()
86     {
87         super();
88     }
89
90
91     /**
92      * Create a new data writer for standard output.
93      *
94      * <p>Use the XMLReader provided as the source of events.</p>
95      *
96      * @param xmlreader The parent in the filter chain.
97      */

98     public DataWriter (XMLReader JavaDoc xmlreader)
99     {
100         super(xmlreader);
101     }
102
103
104     /**
105      * Create a new data writer for the specified output.
106      *
107      * @param writer The character stream where the XML document
108      * will be written.
109      */

110     public DataWriter (Writer JavaDoc writer)
111     {
112         super(writer);
113     }
114
115
116     /**
117      * Create a new data writer for the specified output.
118      * <p>Use the XMLReader provided as the source of events.</p>
119      *
120      * @param xmlreader The parent in the filter chain.
121      * @param writer The character stream where the XML document
122      * will be written.
123      */

124     public DataWriter (XMLReader JavaDoc xmlreader, Writer JavaDoc writer)
125     {
126         super(xmlreader, writer);
127     }
128
129
130
131
132     ////////////////////////////////////////////////////////////////////
133
// Accessors and setters.
134
////////////////////////////////////////////////////////////////////
135

136
137     /**
138      * Return the current indent step.
139      *
140      * <p>Return the current indent step: each start tag will be
141      * indented by this number of spaces times the number of
142      * ancestors that the element has.</p>
143      *
144      * @return The number of spaces in each indentation step,
145      * or 0 or less for no indentation.
146      * @see #setIndentStep
147      */

148     public int getIndentStep ()
149     {
150         return indentStep;
151     }
152
153
154     /**
155      * Set the current indent step.
156      *
157      * @param indentStep The new indent step (0 or less for no
158      * indentation).
159      * @see #getIndentStep
160      */

161     public void setIndentStep (int indentStep)
162     {
163         this.indentStep = indentStep;
164     }
165
166
167
168
169     ////////////////////////////////////////////////////////////////////
170
// Override methods from XMLWriter.
171
////////////////////////////////////////////////////////////////////
172

173
174     /**
175      * Reset the writer so that it can be reused.
176      *
177      * <p>This method is especially useful if the writer failed
178      * with an exception the last time through.</p>
179      *
180      * @see com.megginson.sax.XMLWriter#reset
181      */

182     public void reset ()
183     {
184         depth = 0;
185         state = SEEN_NOTHING;
186         stateStack = new Stack JavaDoc();
187         super.reset();
188     }
189
190
191     /**
192      * Write a start tag.
193      *
194      * <p>Each tag will begin on a new line, and will be
195      * indented by the current indent step times the number
196      * of ancestors that the element has.</p>
197      *
198      * <p>The newline and indentation will be passed on down
199      * the filter chain through regular characters events.</p>
200      *
201      * @param uri The element's Namespace URI.
202      * @param localName The element's local name.
203      * @param qName The element's qualified (prefixed) name.
204      * @param atts The element's attribute list.
205      * @exception org.xml.sax.SAXException If there is an error
206      * writing the start tag, or if a filter further
207      * down the chain raises an exception.
208      * @see XMLWriter#startElement(String, String, String, Attributes)
209      */

210     public void startElement (String JavaDoc uri, String JavaDoc localName,
211                               String JavaDoc qName, Attributes JavaDoc atts)
212         throws SAXException JavaDoc
213     {
214         stateStack.push(SEEN_ELEMENT);
215         state = SEEN_NOTHING;
216         if (depth > 0) {
217             super.characters("\n");
218         }
219         doIndent();
220         super.startElement(uri, localName, qName, atts);
221         depth++;
222     }
223
224
225     /**
226      * Write an end tag.
227      *
228      * <p>If the element has contained other elements, the tag
229      * will appear indented on a new line; otherwise, it will
230      * appear immediately following whatever came before.</p>
231      *
232      * <p>The newline and indentation will be passed on down
233      * the filter chain through regular characters events.</p>
234      *
235      * @param uri The element's Namespace URI.
236      * @param localName The element's local name.
237      * @param qName The element's qualified (prefixed) name.
238      * @exception org.xml.sax.SAXException If there is an error
239      * writing the end tag, or if a filter further
240      * down the chain raises an exception.
241      * @see XMLWriter#endElement(String, String, String)
242      */

243     public void endElement (String JavaDoc uri, String JavaDoc localName, String JavaDoc qName)
244         throws SAXException JavaDoc
245     {
246         depth--;
247         if (state == SEEN_ELEMENT) {
248             super.characters("\n");
249             doIndent();
250         }
251         super.endElement(uri, localName, qName);
252         state = stateStack.pop();
253     }
254
255
256     /**
257      * Write a empty element tag.
258      *
259      * <p>Each tag will appear on a new line, and will be
260      * indented by the current indent step times the number
261      * of ancestors that the element has.</p>
262      *
263      * <p>The newline and indentation will be passed on down
264      * the filter chain through regular characters events.</p>
265      *
266      * @param uri The element's Namespace URI.
267      * @param localName The element's local name.
268      * @param qName The element's qualified (prefixed) name.
269      * @param atts The element's attribute list.
270      * @exception org.xml.sax.SAXException If there is an error
271      * writing the empty tag, or if a filter further
272      * down the chain raises an exception.
273      * @see XMLWriter#emptyElement(String, String, String, Attributes)
274      */

275     public void emptyElement (String JavaDoc uri, String JavaDoc localName,
276                               String JavaDoc qName, Attributes JavaDoc atts)
277         throws SAXException JavaDoc
278     {
279         state = SEEN_ELEMENT;
280         if (depth > 0) {
281             super.characters("\n");
282         }
283         doIndent();
284         super.emptyElement(uri, localName, qName, atts);
285     }
286
287
288     /**
289      * Write a sequence of characters.
290      *
291      * @param ch The characters to write.
292      * @param start The starting position in the array.
293      * @param length The number of characters to use.
294      * @exception org.xml.sax.SAXException If there is an error
295      * writing the characters, or if a filter further
296      * down the chain raises an exception.
297      * @see XMLWriter#characters(char[], int, int)
298      */

299     public void characters (char ch[], int start, int length)
300         throws SAXException JavaDoc
301     {
302         state = SEEN_DATA;
303         super.characters(ch, start, length);
304     }
305
306
307
308
309     ////////////////////////////////////////////////////////////////////
310
// Internal methods.
311
////////////////////////////////////////////////////////////////////
312

313
314     /**
315      * Print indentation for the current level.
316      *
317      * @exception org.xml.sax.SAXException If there is an error
318      * writing the indentation characters, or if a filter
319      * further down the chain raises an exception.
320      */

321     private void doIndent ()
322         throws SAXException JavaDoc
323     {
324         if (indentStep > 0 && depth > 0) {
325             int n = indentStep * depth;
326             char ch[] = new char[n];
327             for (int i = 0; i < n; i++) {
328                 ch[i] = ' ';
329             }
330             characters(ch, 0, n);
331         }
332     }
333
334
335
336
337     ////////////////////////////////////////////////////////////////////
338
// Constants.
339
////////////////////////////////////////////////////////////////////
340

341     private final static Object JavaDoc SEEN_NOTHING = new Object JavaDoc();
342     private final static Object JavaDoc SEEN_ELEMENT = new Object JavaDoc();
343     private final static Object JavaDoc SEEN_DATA = new Object JavaDoc();
344
345
346
347
348     ////////////////////////////////////////////////////////////////////
349
// Internal state.
350
////////////////////////////////////////////////////////////////////
351

352     private Object JavaDoc state = SEEN_NOTHING;
353     private Stack JavaDoc stateStack = new Stack JavaDoc();
354
355     private int indentStep = 4;
356     private int depth = 0;
357
358 }
359
360 // end of DataWriter.java
Popular Tags