KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > nu > xom > samples > WrappingSerializer


1 /* Copyright 2003, 2004 Elliotte Rusty Harold
2    
3    This library is free software; you can redistribute it and/or modify
4    it under the terms of version 2.1 of the GNU Lesser General Public
5    License as published by the Free Software Foundation.
6    
7    This library is distributed in the hope that it will be useful,
8    but WITHOUT ANY WARRANTY; without even the implied warranty of
9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10    GNU Lesser General Public License for more details.
11    
12    You should have received a copy of the GNU Lesser General Public
13    License along with this library; if not, write to the
14    Free Software Foundation, Inc., 59 Temple Place, Suite 330,
15    Boston, MA 02111-1307 USA
16    
17    You can contact Elliotte Rusty Harold by sending e-mail to
18    elharo@metalab.unc.edu. Please include the word "XOM" in the
19    subject line. The XOM home page is located at http://www.xom.nu/
20 */

21
22 package nu.xom.samples;
23
24 import java.io.IOException JavaDoc;
25 import java.io.OutputStream JavaDoc;
26 import java.io.UnsupportedEncodingException JavaDoc;
27
28 import nu.xom.Attribute;
29 import nu.xom.Builder;
30 import nu.xom.DocType;
31 import nu.xom.Document;
32 import nu.xom.Element;
33 import nu.xom.ParsingException;
34 import nu.xom.ProcessingInstruction;
35 import nu.xom.Serializer;
36
37 /**
38  * <p>
39  * This class writes XML with a maximum line length,
40  * but only breaks lines inside tags. It does
41  * not change a document's infoset.
42  * </p>
43  *
44  * @author Elliotte Rusty Harold
45  * @version 1.0
46  *
47  */

48 public class WrappingSerializer extends Serializer {
49
50     public WrappingSerializer(OutputStream JavaDoc out) {
51         super(out);
52     }
53
54     public WrappingSerializer(OutputStream JavaDoc out, String JavaDoc encoding)
55       throws UnsupportedEncodingException JavaDoc {
56         super(out, encoding);
57     }
58     
59     private int maxLength;
60     
61     /**
62      * <p>
63      * Returns the preferred maximum line length.
64      * </p>
65      *
66      * @return the maximum line length.
67      */

68     public int getMaxLength() {
69         return this.maxLength;
70     }
71
72     /**
73      * <p>
74      * Sets the suggested maximum line length for this serializer.
75      * Setting this to 0 indicates that no automatic wrapping is to be
76      * performed. When a line approaches this length, the serializer
77      * begins looking for opportunities to break the line.
78      * It will only break inside a tag, at places that do not
79      * affect the infoset, such as between attribute values or
80      * before the closing <code>></code>. In some circumstances the
81      * serializer may not be able to break the line before the maximum
82      * length is reached. In this case,
83      * the serializer will exceed the maximum line length.
84      * </p>
85      *
86      * <p>
87      * The default value for maxLength is 0, which is
88      * interpreted as no maximum line length.
89      * Setting this to a negative value just sets it to 0.
90      * </p>
91      *
92      * @param maxLength the suggested maximum line length
93      */

94     public void setMaxLength(int maxLength) {
95         this.maxLength = maxLength;
96     }
97
98     protected void writeStartTag(Element element)
99       throws IOException JavaDoc {
100         writeRaw("<");
101         writeRaw(element.getQualifiedName());
102         writeAttributes(element);
103         writeNamespaceDeclarations(element);
104         if (needsBreak()) breakLine();
105         writeRaw(">");
106     }
107
108     protected void writeEmptyElementTag(Element element)
109       throws IOException JavaDoc {
110         writeRaw("<");
111         writeRaw(element.getQualifiedName());
112         writeAttributes(element);
113         writeNamespaceDeclarations(element);
114         if (needsBreak()) breakLine();
115         writeRaw("/>");
116     }
117
118     public void writeEndTag(Element element) throws IOException JavaDoc {
119         writeRaw("<");
120         writeRaw(element.getQualifiedName());
121         if (needsBreak()) breakLine();
122         writeRaw("/>");
123     }
124
125     /**
126      * <p>
127      * This method writes an attribute in the form
128      * <code><i>name</i>="<i>value</i>"</code>.
129      * Characters in the attribute value are escaped as necessary.
130      * </p>
131      *
132      * @param attribute the <code>Attribute</code> to write
133      *
134      * @throws IOException if the underlying <code>OutputStream</code>
135      * encounters an I/O error
136      */

137     protected void write(Attribute attribute) throws IOException JavaDoc {
138         
139         String JavaDoc name = attribute.getQualifiedName();
140         if (maxLength <= this.getColumnNumber() + name.length()) {
141             breakLine();
142         }
143         writeRaw(name);
144         if (this.getColumnNumber() == maxLength) {
145             breakLine();
146         }
147         writeRaw("=");
148         String JavaDoc value = attribute.getValue();
149         if (maxLength < value.length() + 2) {
150             breakLine();
151         }
152         writeRaw("\"");
153         writeAttributeValue(attribute.getValue());
154         writeRaw("\"");
155         
156     }
157
158     /**
159      * <p>
160      * This writes a namespace declaration in the form
161      * <code>xmlns:<i>prefix</i>="<i>uri</i>"</code> or
162      * <code>xmlns="<i>uri</i>"</code>.
163      * </p>
164      *
165      * @param prefix the namespace prefix; the empty string for the
166      * default namespace
167      * @param uri the namespace URI
168      *
169      * @throws IOException if the underlying <code>OutputStream</code>
170      * encounters an I/O error
171      */

172     protected void writeNamespaceDeclaration(String JavaDoc prefix, String JavaDoc uri)
173       throws IOException JavaDoc {
174           
175         String JavaDoc name;
176         if ("".equals(prefix)) {
177             name = "xmlns";
178         }
179         else {
180             name = "xmlns:" + prefix;
181         }
182         if (this.maxLength < this.getColumnNumber() + name.length()) {
183             breakLine();
184         }
185         writeRaw(name);
186
187         if (this.getColumnNumber() == maxLength) {
188             breakLine();
189         }
190         writeRaw("=");
191         
192         if (this.maxLength < this.getColumnNumber() + uri.length() + 2) {
193             breakLine();
194         }
195         writeRaw("\"");
196         writeEscaped(uri);
197         writeRaw("\"");
198     }
199
200     private boolean needsBreak() {
201         if (maxLength > 0) {
202             return this.maxLength - this.getColumnNumber() <= 10;
203         }
204         return false;
205     }
206
207     /**
208      * <p>
209      * Serializes a <code>ProcessingInstruction</code> object
210      * onto the output stream. Line breaks may be inserted
211      * following the target.
212      * </p>
213      *
214      * <p>
215      * Since character and entity references are not resolved
216      * in processing instructions, processing instructions
217      * can only be serialized when all
218      * characters they contain are available in the current
219      * encoding.
220      * </p>
221      *
222      * @param instruction the <code>ProcessingInstruction</code>
223      * to serialize.
224      *
225      * @throws IOException if the underlying <code>OutputStream</code>
226      * encounters an I/O error
227      */

228     protected void write(ProcessingInstruction instruction)
229       throws IOException JavaDoc {
230         writeRaw("<?");
231         writeRaw(instruction.getTarget());
232         String JavaDoc value = instruction.getValue();
233         if (maxLength < getColumnNumber() + value.length() + 3) {
234             breakLine();
235         }
236         else {
237             writeRaw(" ");
238         }
239         writeRaw(value);
240         writeRaw("?>");
241     }
242
243     /**
244      * <p>
245      * Serializes a <code>DocType</code> object
246      * onto the output stream.
247      * </p>
248      *
249      * @param doctype the document type declaration to serialize
250      *
251      * @throws IOException if the underlying
252      * <code>OutputStream</code> encounters an I/O error
253      */

254     protected void write(DocType doctype) throws IOException JavaDoc {
255         writeRaw("<!DOCTYPE");
256         String JavaDoc rootElementName = doctype.getRootElementName();
257         if (maxLength < getColumnNumber() + rootElementName.length() + 1) {
258             breakLine();
259         }
260         else {
261             writeRaw(" ");
262         }
263         writeRaw(rootElementName);
264         
265         String JavaDoc publicID = doctype.getPublicID();
266         String JavaDoc systemID = doctype.getSystemID();
267         if (publicID != null) {
268             if (maxLength < getColumnNumber() + 6) {
269                 breakLine();
270             }
271             else {
272                 writeRaw(" ");
273             }
274             writeRaw("PUBLIC");
275               
276             if (maxLength < getColumnNumber() + publicID.length() + 2) {
277                 breakLine();
278             }
279             else {
280                 writeRaw(" ");
281             }
282             writeRaw("\"");
283             writeRaw(publicID);
284             writeRaw("\"");
285             
286             if (maxLength < getColumnNumber() + systemID.length() + 2) {
287                 breakLine();
288             }
289             else {
290                 writeRaw(" ");
291             }
292             writeRaw("\"");
293             writeRaw(systemID);
294             writeRaw("\"");
295         }
296         else if (systemID != null) {
297             if (maxLength < getColumnNumber() + 6) {
298                 breakLine();
299             }
300             else {
301                 writeRaw(" ");
302             }
303             writeRaw("SYSTEM");
304             
305             if (maxLength < getColumnNumber() + systemID.length() + 2) {
306                 breakLine();
307             }
308             else {
309                 writeRaw(" ");
310             }
311             writeRaw("\"");
312             writeRaw(systemID);
313             writeRaw("\"");
314         }
315         
316         String JavaDoc internalDTDSubset = doctype.getInternalDTDSubset();
317         if (!internalDTDSubset.equals("")) {
318             if (maxLength < getColumnNumber() + 2) {
319                 breakLine();
320             }
321             else writeRaw(" ");
322             writeRaw("[");
323             breakLine();
324             writeRaw(internalDTDSubset);
325             breakLine();
326             writeRaw("]");
327         }
328
329         if (maxLength < getColumnNumber() + 1) {
330             breakLine();
331         }
332         writeRaw(">");
333
334     }
335     
336     public static void main(String JavaDoc[] args) {
337   
338         if (args.length <= 0) {
339           System.out.println("Usage: java nu.xom.samples.WrappingSerializer URL");
340           return;
341         }
342         
343         try {
344           Builder parser = new Builder();
345           Document doc = parser.build(args[0]);
346           Serializer serializer = new WrappingSerializer(System.out, "ISO-8859-1");
347           serializer.setIndent(4);
348           serializer.setMaxLength(24);
349           serializer.setPreserveBaseURI(true);
350           serializer.write(doc);
351           serializer.flush();
352         }
353         catch (ParsingException ex) {
354           System.out.println(args[0] + " is not well-formed.");
355           System.out.println(ex.getMessage());
356         }
357         catch (IOException JavaDoc ex) {
358           System.out.println(
359            "Due to an IOException, the parser could not read "
360            + args[0]
361           );
362         }
363   
364     }
365
366 }
367
Popular Tags