1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package com.xpn.xwiki.internal.xml

File XMLWriter.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart8.png
54% of files have more coverage

Code metrics

6
28
9
1
224
78
14
0.5
3.11
9
1.56

Classes

Class Line # Actions
XMLWriter 52 28 0% 14 12
0.720930272.1%
 

Contributing tests

This file is covered by 2 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package com.xpn.xwiki.internal.xml;
21   
22    import java.io.IOException;
23    import java.io.InputStream;
24    import java.io.OutputStream;
25    import java.io.Reader;
26    import java.io.UnsupportedEncodingException;
27    import java.util.Stack;
28   
29    import org.apache.commons.codec.binary.Base64OutputStream;
30    import org.apache.commons.io.IOUtils;
31    import org.apache.commons.io.output.CloseShieldOutputStream;
32    import org.dom4j.Document;
33    import org.dom4j.Element;
34    import org.dom4j.io.OutputFormat;
35   
36    /**
37    * Extension to <code>{@link org.dom4j.io.XMLWriter}</code> to allow filling some element content with an input stream,
38    * minimizing the memory footprint of the operation.
39    * <p>
40    * This extension is not intended to be used to format a DOM4J tree to a stream, but to immediately write out the tags
41    * produced without building the document tree in memory. It is not compatible with the SAX part of the original
42    * <code>{@link org.dom4j.io.XMLWriter}</code>.
43    * </p>
44    * <p>
45    * An improvement to the writeOpen/writeClose functions ensure better handling of independent opening and closing of
46    * tags by maintaining a state stack of opened tags. New writeDocumentStart/End function also ensure proper starting and
47    * ending of the document it self.
48    * </p>
49    *
50    * @version $Id: cb5a6e08619da9ffe54b8833cdaa0dcd887c770b $
51    */
 
52    public class XMLWriter extends org.dom4j.io.XMLWriter
53    {
54    /**
55    * <code>{@link Stack}</code> of currently opened <code>{@link Element}</code>, the first
56    * <code>{@link Element}</code> is the document root element, and the top of the stack is the last opened
57    * <code>{@link Element}</code>.
58    */
59    protected Stack<Element> parent = new Stack<Element>();
60   
61    /**
62    * Current <code>{@link OutputStream}</code> of this writer.
63    */
64    private OutputStream out;
65   
66    /**
67    * Default constructor used by <code>{@link DOMXMLWriter}</code>.
68    *
69    * @see DOMXMLWriter
70    */
 
71  3 toggle protected XMLWriter()
72    {
73    }
74   
75    /**
76    * Create a new XMLWriter writing to a provided OutputStream in a given format. Note that other constructor of the
77    * original DOM4J XMLWriter are unsupported since a OutputStream is the only way we can support the extensions
78    * provided here.
79    * <p>
80    * Note that the writer is buffered and only a call to flush() or writeDocuemntEnd() will ensure the output has been
81    * fully written to the <code>{@link OutputStream}</code>.
82    * </p>
83    *
84    * @param out an <code>{@link OutputStream}</code> where to output the XML produced.
85    * @param format an <code>{@link OutputFormat}</code> defining the encoding that should be used and esthetics of the
86    * produced XML.
87    * @throws UnsupportedEncodingException the requested encoding is unsupported.
88    */
 
89  63 toggle public XMLWriter(OutputStream out, OutputFormat format) throws UnsupportedEncodingException
90    {
91  63 super(out, format);
92  63 this.out = out;
93    }
94   
95    /**
96    * Write the <code>{@link Document}</code> declaration, and its <code>{@link org.dom4j.DocumentType}</code> if
97    * available to the output stream.
98    *
99    * @param doc <code>{@link Document}</code> to be started, may specify a <code>{@link org.dom4j.DocumentType}</code>
100    * .
101    * @throws IOException a problem occurs during writing
102    */
 
103  63 toggle public void writeDocumentStart(Document doc) throws IOException
104    {
105  63 writeDeclaration();
106   
107  63 if (doc.getDocType() != null) {
108  0 indent();
109  0 writeDocType(doc.getDocType());
110    }
111    }
112   
113    /**
114    * Close all remaining opened <code>{@link Element}</code> including the root element to terminate the current
115    * document. Also flush the writer to ensure the whole document has been written to the
116    * <code>{@link OutputStream}</code>.
117    *
118    * @param doc <code>{@link Document}</code> to be end, actually unused.
119    * @throws IOException a problem occurs during writing.
120    */
 
121  63 toggle public void writeDocumentEnd(Document doc) throws IOException
122    {
123  63 if (!this.parent.isEmpty()) {
124  1 writeClose(this.parent.firstElement());
125    }
126  63 writePrintln();
127  63 flush();
128    }
129   
130    /**
131    * Writes the <code>{@link Element}</code>, including its <code>{@link
132    * org.dom4j.Attribute}</code>s, using the <code>{@link Reader}</code> for its content.
133    * <p>
134    * Note that proper decoding/encoding will occurs during this operation, converting the encoding of the Reader into
135    * the encoding of the Writer.
136    * </p>
137    *
138    * @param element <code>{@link Element}</code> to output.
139    * @param rd <code>{@link Reader}</code> that will be fully read and transfered into the element content.
140    * @throws IOException a problem occurs during reading or writing.
141    */
 
142  0 toggle public void write(Element element, Reader rd) throws IOException
143    {
144  0 writeOpen(element);
145  0 IOUtils.copy(rd, this.writer);
146  0 writeClose(element);
147    }
148   
149    /**
150    * Writes the <code>{@link Element}</code>, including its <code>{@link
151    * org.dom4j.Attribute}</code>s, using the <code>{@link InputStream}</code> for its content.
152    * <p>
153    * Note that no decoding/encoding of the InputStream will be ensured during this operation. The byte content is
154    * transfered untouched.
155    * </p>
156    *
157    * @param element <code>{@link Element}</code> to output.
158    * @param is <code>{@link InputStream}</code> that will be fully read and transfered into the element content.
159    * @throws IOException a problem occurs during reading or writing.
160    */
 
161  0 toggle public void write(Element element, InputStream is) throws IOException
162    {
163  0 writeOpen(element);
164  0 flush();
165  0 IOUtils.copy(is, this.out);
166  0 writeClose(element);
167    }
168   
169    /**
170    * Writes the <code>{@link Element}</code>, including its <code>{@link
171    * org.dom4j.Attribute}</code>s, using the <code>{@link InputStream}</code> encoded in Base64 for its content.
172    *
173    * @param element <code>{@link Element}</code> to output.
174    * @param is <code>{@link InputStream}</code> that will be fully read and encoded in Base64 into the element
175    * content.
176    * @throws IOException a problem occurs during reading or writing.
177    */
 
178  62 toggle public void writeBase64(Element element, InputStream is) throws IOException
179    {
180  62 writeOpen(element);
181  62 flush();
182  62 try (Base64OutputStream base64 = new Base64OutputStream(new CloseShieldOutputStream(this.out))) {
183  62 IOUtils.copy(is, base64);
184    }
185  62 writeClose(element);
186    }
187   
188    /**
189    * Writes the opening tag of an {@link Element}, including its {@link org.dom4j.Attribute}s but without its content.
190    * <p>
191    * Compared to the DOM4J implementation, this function keeps track of opened elements.
192    * </p>
193    *
194    * @param element <code>{@link Element}</code> to output.
195    * @throws IOException a problem occurs during writing.
196    * @see org.dom4j.io.XMLWriter#writeOpen(org.dom4j.Element)
197    */
 
198  126 toggle @Override
199    public void writeOpen(Element element) throws IOException
200    {
201  126 super.writeOpen(element);
202  126 this.parent.push(element);
203    }
204   
205    /**
206    * Writes the closing tag of an {@link Element}.
207    * <p>
208    * Compared to the DOM4J implementation, this function ensure closing of all opened element including the one that
209    * is requested to be closed.
210    * </p>
211    *
212    * @param element <code>{@link Element}</code> to output.
213    * @throws IOException a problem occurs during writing.
214    * @see org.dom4j.io.XMLWriter#writeClose(org.dom4j.Element)
215    */
 
216  125 toggle @Override
217    public void writeClose(Element element) throws IOException
218    {
219  126 while (this.parent.peek() != element) {
220  1 super.writeClose(this.parent.pop());
221    }
222  125 super.writeClose(this.parent.pop());
223    }
224    }