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

File DOMXMLWriter.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart4.png
78% of files have more coverage

Code metrics

8
35
17
2
322
130
22
0.63
2.06
8.5
1.29

Classes

Class Line # Actions
DOMXMLWriter 91 34 0% 21 36
0.3793103437.9%
DOMXMLWriter.SAXUnsupportedException 312 1 0% 1 2
0.00%
 

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.ByteArrayOutputStream;
23    import java.io.IOException;
24    import java.io.InputStream;
25    import java.io.Reader;
26    import java.util.EmptyStackException;
27   
28    import org.apache.commons.codec.binary.Base64OutputStream;
29    import org.apache.commons.io.IOUtils;
30    import org.dom4j.Document;
31    import org.dom4j.Element;
32    import org.dom4j.io.OutputFormat;
33    import org.xml.sax.Attributes;
34    import org.xml.sax.SAXException;
35   
36    /**
37    * This a minimal implementation to transform an XMLWriter into a <code>{@link org.dom4j.dom.DOMDocument}</code>
38    * builder.
39    * <p>
40    * This implementation allow the use of a same function accepting an XMLWriter, to either produce output into an
41    * <code>{@link java.io.OutputStream}</code> or to create a <code>{@link org.dom4j.dom.DOMDocument}</code>. Here a
42    * sample of the way to do so:
43    * </p>
44    * <code><pre>
45    * public void toXML(XMLWriter wr) throws IOException
46    * {
47    * Element docel = new DOMElement("html");
48    * wr.writeOpen(docel);
49    * Element hbel = new DOMElement("head");
50    * wr.writeOpen(hbel);
51    * Element el = new DOMElement("title");
52    * el.addText("My Title");
53    * wr.write(el);
54    * wr.writeClose(hbel);
55    * hbel = new DOMElement("body");
56    * wr.writeOpen(hbel);
57    * el = new DOMElement("p");
58    * el.addText("My Body");
59    * wr.write(el);
60    * }
61    *
62    * public void toXML(OutputStream out) throws IOException
63    * {
64    * XMLWriter wr = new XMLWriter(out, new OutputFormat(" ", true, "UTF-8"));
65    *
66    * Document doc = new DOMDocument();
67    * wr.writeDocumentStart(doc);
68    * toXML(wr);
69    * wr.writeDocumentEnd(doc);
70    * }
71    *
72    * public Document toXMLDocument()
73    * {
74    * Document doc = new DOMDocument();
75    * DOMXMLWriter wr = new DOMXMLWriter(doc, new OutputFormat(" ", true, "UTF-8"));
76    *
77    * try {
78    * toXML(wr);
79    * return doc;
80    * } catch (IOException e) {
81    * throw new RuntimeException(e);
82    * }
83    * }
84    * </pre></code>
85    * <p>
86    * <b>WARNING</b> - This implementation in INCOMPLETE and a minimal support. It should be improve as needed over time
87    * </p>
88    *
89    * @version $Id: 46dca947c8d30ffa6ed5b67eb019965de8657d73 $
90    */
 
91    public class DOMXMLWriter extends XMLWriter
92    {
93    /**
94    * The <code>{@link Document}</code> currently built by this writer.
95    */
96    private Document doc;
97   
98    /**
99    * The <code>{@link OutputFormat}</code> providing the encoding requested.
100    */
101    private OutputFormat format;
102   
103    /**
104    * Create a new <code>{@link DOMXMLWriter}</code> that will build into the provided document using the default
105    * encoding.
106    *
107    * @param doc <code>{@link Document}</code> that will be build by this writer
108    */
 
109  2 toggle public DOMXMLWriter(Document doc)
110    {
111  2 this.format = DEFAULT_FORMAT;
112  2 this.doc = doc;
113    }
114   
115    /**
116    * Create a new <code>{@link DOMXMLWriter}</code> that will build into the provided document using the encoding
117    * provided in the <code>{@link OutputFormat}</code>.
118    *
119    * @param doc <code>{@link Document}</code> that will be build by this writer
120    * @param format <code>{@link OutputFormat}</code> used to retrieve the proper encoding
121    */
 
122  1 toggle public DOMXMLWriter(Document doc, OutputFormat format)
123    {
124  1 this.format = format;
125  1 this.doc = doc;
126    }
127   
128    /**
129    * {@inheritDoc}
130    * <p>
131    * Add the element into the <code>{@link Document}</code> as a children of the element at the top of the stack of
132    * opened elements, putting the whole stream content as text in the content of the <code>{@link Element}</code>. The
133    * stream is converted to a String encoded in the current encoding.
134    * </p>
135    *
136    * @see com.xpn.xwiki.internal.xml.XMLWriter#write(org.dom4j.Element, java.io.InputStream)
137    */
 
138  0 toggle @Override
139    public void write(Element element, InputStream is) throws IOException
140    {
141  0 element.addText(IOUtils.toString(is, this.format.getEncoding()));
142  0 write(element);
143    }
144   
145    /**
146    * {@inheritDoc}
147    * <p>
148    * Add the element into the <code>{@link Document}</code> as a children of the element at the top of the stack of of
149    * the <code>{@link Element}</code>.
150    * </p>
151    *
152    * @see com.xpn.xwiki.internal.xml.XMLWriter#write(org.dom4j.Element, java.io.Reader)
153    */
 
154  0 toggle @Override
155    public void write(Element element, Reader rd) throws IOException
156    {
157  0 element.addText(IOUtils.toString(rd));
158  0 write(element);
159    }
160   
161    /**
162    * {@inheritDoc}
163    * <p>
164    * Add the element into the <code>{@link Document}</code> as a children of the element at the top of the stack of
165    * opened elements, putting the whole stream content as Base64 text in the content of the
166    * <code>{@link Element}</code>.
167    * </p>
168    *
169    * @see com.xpn.xwiki.internal.xml.XMLWriter#writeBase64(org.dom4j.Element, java.io.InputStream)
170    */
 
171  0 toggle @Override
172    public void writeBase64(Element element, InputStream is) throws IOException
173    {
174  0 ByteArrayOutputStream baos = new ByteArrayOutputStream();
175  0 Base64OutputStream out = new Base64OutputStream(baos, true, 0, null);
176  0 IOUtils.copy(is, out);
177  0 out.close();
178  0 element.addText(baos.toString(this.format.getEncoding()));
179  0 write(element);
180    }
181   
182    /**
183    * {@inheritDoc}
184    * <p>
185    * Cleanup the stack of opened elements.
186    * </p>
187    *
188    * @see com.xpn.xwiki.internal.xml.XMLWriter#writeDocumentEnd(org.dom4j.Document)
189    */
 
190  0 toggle @Override
191    public void writeDocumentEnd(Document doc) throws IOException
192    {
193  0 if (!this.parent.isEmpty()) {
194  0 writeClose(this.parent.firstElement());
195    }
196    }
197   
198    /**
199    * {@inheritDoc}
200    * <p>
201    * Does nothing, avoid default action.
202    * </p>
203    *
204    * @see com.xpn.xwiki.internal.xml.XMLWriter#writeDocumentStart(org.dom4j.Document)
205    */
 
206  0 toggle @Override
207    public void writeDocumentStart(Document doc) throws IOException
208    {
209    }
210   
211    /**
212    * {@inheritDoc}
213    * <p>
214    * Add the element into the <code>{@link Document}</code> as a children of the element at the top of the stack of
215    * opened elements.
216    * </p>
217    *
218    * @see org.dom4j.io.XMLWriter#write(org.dom4j.Element)
219    */
 
220  4 toggle @Override
221    public void write(Element element) throws IOException
222    {
223  4 if (this.parent.isEmpty()) {
224  3 this.doc.setRootElement((Element) element.clone());
225    } else {
226  1 this.parent.peek().add((Element) element.clone());
227    }
228    }
229   
230    /**
231    * {@inheritDoc}
232    * <p>
233    * Cleanup the stack of opened elements up to the given element.
234    * </p>
235    *
236    * @see com.xpn.xwiki.internal.xml.XMLWriter#writeClose(org.dom4j.Element)
237    */
 
238  1 toggle @Override
239    public void writeClose(Element element) throws IOException
240    {
241  1 try {
242  1 while (this.parent.peek() != element) {
243  0 this.parent.pop();
244    }
245  1 this.parent.pop();
246    } catch (EmptyStackException e) {
247  0 throw new IOException("FATAL: Closing a element that have never been opened");
248    }
249    }
250   
251    /**
252    * {@inheritDoc}
253    * <p>
254    * Add the element into the <code>{@link Document}</code> as a children of the element at the top of the stack of
255    * opened elements. Add this element at the top of the stack of opened elements.
256    * </p>
257    *
258    * @see com.xpn.xwiki.internal.xml.XMLWriter#writeOpen(org.dom4j.Element)
259    */
 
260  1 toggle @Override
261    public void writeOpen(Element element) throws IOException
262    {
263  1 if (this.parent.isEmpty()) {
264  1 this.doc.setRootElement(element);
265    } else {
266  0 this.parent.add(element);
267    }
268   
269  1 this.parent.push(element);
270    }
271   
 
272  0 toggle @Override
273    public void startCDATA() throws SAXException
274    {
275  0 throw new SAXUnsupportedException();
276    }
277   
 
278  0 toggle @Override
279    public void startElement(String namespaceURI, String localName, String qName, Attributes attributes)
280    throws SAXException
281    {
282  0 throw new SAXUnsupportedException();
283    }
284   
 
285  0 toggle @Override
286    public void startEntity(String name) throws SAXException
287    {
288  0 throw new SAXUnsupportedException();
289    }
290   
 
291  0 toggle @Override
292    public void endCDATA() throws SAXException
293    {
294  0 throw new SAXUnsupportedException();
295    }
296   
 
297  0 toggle @Override
298    public void endElement(String namespaceURI, String localName, String qName) throws SAXException
299    {
300  0 throw new SAXUnsupportedException();
301    }
302   
 
303  0 toggle @Override
304    public void endEntity(String name) throws SAXException
305    {
306  0 throw new SAXUnsupportedException();
307    }
308   
309    /**
310    * Thrown for SAX api methods since we don't support them.
311    */
 
312    public class SAXUnsupportedException extends RuntimeException
313    {
314    /**
315    * Constructs a <code>SAXUnsupportedException</code>.
316    */
 
317  0 toggle public SAXUnsupportedException()
318    {
319  0 super("SAX api is not supported");
320    }
321    }
322    }