/* Copyright 2003, 2004 Elliotte Rusty Harold This library is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . You can contact Elliotte Rusty Harold by sending e-mail to elharo@ibiblio.org. Please include the word "XOM" in the subject line. The XOM home page is located at https://xom.nu/ */ package nu.xom.samples; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import nu.xom.Attribute; import nu.xom.Builder; import nu.xom.DocType; import nu.xom.Document; import nu.xom.Element; import nu.xom.ParsingException; import nu.xom.ProcessingInstruction; import nu.xom.Serializer; /** *

* This class writes XML with a maximum line length, * but only breaks lines inside tags. It does * not change a document's infoset. *

* * @author Elliotte Rusty Harold * @version 1.0 * */ public class WrappingSerializer extends Serializer { public WrappingSerializer(OutputStream out) { super(out); } public WrappingSerializer(OutputStream out, String encoding) throws UnsupportedEncodingException { super(out, encoding); } private int maxLength; /** *

* Returns the preferred maximum line length. *

* * @return the maximum line length. */ public int getMaxLength() { return this.maxLength; } /** *

* Sets the suggested maximum line length for this serializer. * Setting this to 0 indicates that no automatic wrapping is to be * performed. When a line approaches this length, the serializer * begins looking for opportunities to break the line. * It will only break inside a tag, at places that do not * affect the infoset, such as between attribute values or * before the closing >. In some circumstances the * serializer may not be able to break the line before the maximum * length is reached. In this case, * the serializer will exceed the maximum line length. *

* *

* The default value for maxLength is 0, which is * interpreted as no maximum line length. * Setting this to a negative value just sets it to 0. *

* * @param maxLength the suggested maximum line length */ public void setMaxLength(int maxLength) { this.maxLength = maxLength; } protected void writeStartTag(Element element) throws IOException { writeRaw("<"); writeRaw(element.getQualifiedName()); writeAttributes(element); writeNamespaceDeclarations(element); if (needsBreak()) breakLine(); writeRaw(">"); } protected void writeEmptyElementTag(Element element) throws IOException { writeRaw("<"); writeRaw(element.getQualifiedName()); writeAttributes(element); writeNamespaceDeclarations(element); if (needsBreak()) breakLine(); writeRaw("/>"); } public void writeEndTag(Element element) throws IOException { writeRaw("<"); writeRaw(element.getQualifiedName()); if (needsBreak()) breakLine(); writeRaw("/>"); } /** *

* This method writes an attribute in the form * name="value". * Characters in the attribute value are escaped as necessary. *

* * @param attribute the Attribute to write * * @throws IOException if the underlying OutputStream * encounters an I/O error */ protected void write(Attribute attribute) throws IOException { String name = attribute.getQualifiedName(); if (maxLength <= this.getColumnNumber() + name.length()) { breakLine(); } writeRaw(name); if (this.getColumnNumber() == maxLength) { breakLine(); } writeRaw("="); String value = attribute.getValue(); if (maxLength < value.length() + 2) { breakLine(); } writeRaw("\""); writeAttributeValue(attribute.getValue()); writeRaw("\""); } /** *

* This writes a namespace declaration in the form * xmlns:prefix="uri" or * xmlns="uri". *

* * @param prefix the namespace prefix; the empty string for the * default namespace * @param uri the namespace URI * * @throws IOException if the underlying OutputStream * encounters an I/O error */ protected void writeNamespaceDeclaration(String prefix, String uri) throws IOException { String name; if ("".equals(prefix)) { name = "xmlns"; } else { name = "xmlns:" + prefix; } if (this.maxLength < this.getColumnNumber() + name.length()) { breakLine(); } writeRaw(name); if (this.getColumnNumber() == maxLength) { breakLine(); } writeRaw("="); if (this.maxLength < this.getColumnNumber() + uri.length() + 2) { breakLine(); } writeRaw("\""); writeEscaped(uri); writeRaw("\""); } private boolean needsBreak() { if (maxLength > 0) { return this.maxLength - this.getColumnNumber() <= 10; } return false; } /** *

* Serializes a ProcessingInstruction object * onto the output stream. Line breaks may be inserted * following the target. *

* *

* Since character and entity references are not resolved * in processing instructions, processing instructions * can only be serialized when all * characters they contain are available in the current * encoding. *

* * @param instruction the ProcessingInstruction * to serialize. * * @throws IOException if the underlying OutputStream * encounters an I/O error */ protected void write(ProcessingInstruction instruction) throws IOException { writeRaw(""); } /** *

* Serializes a DocType object * onto the output stream. *

* * @param doctype the document type declaration to serialize * * @throws IOException if the underlying * OutputStream encounters an I/O error */ protected void write(DocType doctype) throws IOException { writeRaw(""); } public static void main(String[] args) { if (args.length <= 0) { System.out.println("Usage: java nu.xom.samples.WrappingSerializer URL"); return; } try { Builder parser = new Builder(); Document doc = parser.build(args[0]); Serializer serializer = new WrappingSerializer(System.out, "ISO-8859-1"); serializer.setIndent(4); serializer.setMaxLength(24); serializer.setPreserveBaseURI(true); serializer.write(doc); serializer.flush(); } catch (ParsingException ex) { System.out.println(args[0] + " is not well-formed."); System.out.println(ex.getMessage()); } catch (IOException ex) { System.out.println( "Due to an IOException, the parser could not read " + args[0] ); } } }