1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package org.xwiki.xml

File Sax2Dom.java

 

Coverage histogram

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

Code metrics

26
54
22
1
293
181
35
0.65
2.45
22
1.59

Classes

Class Line # Actions
Sax2Dom 46 54 0% 35 65
0.362745136.3%
 

Contributing tests

This file is covered by 576 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 org.xwiki.xml;
21   
22    import java.util.ArrayList;
23    import java.util.List;
24    import java.util.Stack;
25   
26    import javax.xml.parsers.DocumentBuilderFactory;
27    import javax.xml.parsers.ParserConfigurationException;
28   
29    import org.apache.commons.lang3.StringUtils;
30    import org.w3c.dom.Comment;
31    import org.w3c.dom.Document;
32    import org.w3c.dom.Element;
33    import org.w3c.dom.Node;
34    import org.w3c.dom.ProcessingInstruction;
35    import org.xml.sax.Attributes;
36    import org.xml.sax.ContentHandler;
37    import org.xml.sax.Locator;
38    import org.xml.sax.SAXException;
39    import org.xml.sax.ext.LexicalHandler;
40   
41    /**
42    * Convert SAX events into a Document.
43    *
44    * @version $Id: c92afca6a9c7814c95875eebf380fa550225c0d3 $
45    */
 
46    public class Sax2Dom implements ContentHandler, LexicalHandler
47    {
48    /**
49    * "xml" namespace prefix.
50    */
51    public static final String XML_PREFIX = "xml";
52   
53    /**
54    * "xmlns" namespace prefix.
55    */
56    public static final String XMLNS_PREFIX = "xmlns";
57   
58    /**
59    * "xmlns" namespace prefix with :.
60    */
61    public static final String XMLNS_STRING = XMLNS_PREFIX + ':';
62   
63    /**
64    * "xmlns" URL.
65    */
66    public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
67   
68    /**
69    * The root node.
70    */
71    private final Node rootNode;
72   
73    /**
74    * The document used to create new nodes.
75    */
76    private final Document document;
77   
78    /**
79    * The current nodes.
80    */
81    private final Stack<Node> nodes = new Stack<Node>();
82   
83    /**
84    * The namespaces declarations.
85    */
86    private List<String> namespaceDecls;
87   
88    /**
89    * Default constructor.
90    *
91    * @throws ParserConfigurationException failed to create a new {@link Document}
92    */
 
93  930 toggle public Sax2Dom() throws ParserConfigurationException
94    {
95  930 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
96  930 this.document = factory.newDocumentBuilder().newDocument();
97  930 this.rootNode = this.document;
98    }
99   
100    /**
101    * @param root the root node to fill with SAX events
102    * @throws ParserConfigurationException failed to create a new {@link Document}
103    */
 
104  0 toggle public Sax2Dom(Node root) throws ParserConfigurationException
105    {
106  0 if (root instanceof Document) {
107  0 this.document = (Document) root;
108  0 this.rootNode = root;
109  0 } else if (root != null) {
110  0 this.document = root.getOwnerDocument();
111  0 this.rootNode = root;
112    } else {
113  0 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
114  0 this.document = factory.newDocumentBuilder().newDocument();
115  0 this.rootNode = this.document;
116    }
117    }
118   
119    /**
120    * @return the root {@link Node}
121    */
 
122  0 toggle public Node getRootNode()
123    {
124  0 return this.rootNode;
125    }
126   
127    /**
128    * @return the root {@link Element}
129    */
 
130  930 toggle public Element getRootElement()
131    {
132  930 Element rootElement;
133   
134  930 if (this.rootNode instanceof Element) {
135  0 rootElement = (Element) this.rootNode;
136  930 } else if (this.rootNode instanceof Document) {
137  930 rootElement = ((Document) this.rootNode).getDocumentElement();
138    } else {
139  0 rootElement = null;
140    }
141   
142  930 return rootElement;
143    }
144   
 
145  18466 toggle @Override
146    public void characters(char[] ch, int start, int length)
147    {
148  18466 Node currentNode = this.nodes.peek();
149   
150    // No text nodes can be children of root (DOM006 exception)
151  18466 if (currentNode != this.document) {
152  18466 final String text = String.valueOf(ch, start, length);
153  18466 currentNode.appendChild(this.document.createTextNode(text));
154    }
155    }
156   
 
157  930 toggle @Override
158    public void startDocument()
159    {
160  930 this.nodes.push(this.rootNode);
161    }
162   
 
163  930 toggle @Override
164    public void endDocument()
165    {
166  930 this.nodes.pop();
167    }
168   
 
169  10306 toggle @Override
170    public void startElement(String namespace, String localName, String qName, Attributes atts)
171    {
172  10306 final Element element = this.document.createElementNS(namespace, qName);
173   
174    // Add namespace declarations first
175  10306 if (this.namespaceDecls != null) {
176  0 final int nDecls = this.namespaceDecls.size();
177  0 for (int i = 0; i < nDecls; i += 2) {
178  0 String prefix = this.namespaceDecls.get(i);
179  0 String uri = this.namespaceDecls.get(i + 1);
180   
181  0 if (StringUtils.isEmpty(prefix)) {
182  0 element.setAttributeNS(XMLNS_URI, XMLNS_PREFIX, uri);
183    } else {
184  0 element.setAttributeNS(XMLNS_URI, XMLNS_STRING + prefix, uri);
185    }
186    }
187  0 this.namespaceDecls.clear();
188    }
189   
190    // Add attributes to element
191  10306 final int nattrs = atts.getLength();
192  10830 for (int i = 0; i < nattrs; i++) {
193  524 if (atts.getLocalName(i) == null) {
194  0 element.setAttribute(atts.getQName(i), atts.getValue(i));
195    } else {
196  524 element.setAttributeNS(atts.getURI(i), atts.getQName(i), atts.getValue(i));
197    }
198    }
199   
200    // Append this new node onto current stack node
201  10306 this.nodes.peek().appendChild(element);
202   
203    // Push this node onto stack
204  10306 this.nodes.push(element);
205    }
206   
 
207  10306 toggle @Override
208    public void endElement(String namespace, String localName, String qName)
209    {
210  10306 this.nodes.pop();
211    }
212   
 
213  0 toggle @Override
214    public void startPrefixMapping(String prefix, String uri)
215    {
216  0 if (this.namespaceDecls == null) {
217  0 this.namespaceDecls = new ArrayList<String>(2);
218    }
219  0 this.namespaceDecls.add(prefix);
220  0 this.namespaceDecls.add(uri);
221    }
222   
 
223  0 toggle @Override
224    public void endPrefixMapping(String prefix)
225    {
226   
227    }
228   
 
229  0 toggle @Override
230    public void ignorableWhitespace(char[] ch, int start, int length)
231    {
232    }
233   
 
234  0 toggle @Override
235    public void processingInstruction(String target, String data)
236    {
237  0 ProcessingInstruction pi = this.document.createProcessingInstruction(target, data);
238  0 if (pi != null) {
239  0 this.nodes.peek().appendChild(pi);
240    }
241    }
242   
 
243  0 toggle @Override
244    public void setDocumentLocator(Locator locator)
245    {
246    }
247   
 
248  0 toggle @Override
249    public void skippedEntity(String name)
250    {
251    }
252   
 
253  0 toggle @Override
254    public void comment(char[] ch, int start, int length)
255    {
256  0 Comment comment = this.document.createComment(String.valueOf(ch, start, length));
257  0 if (comment != null) {
258  0 this.nodes.peek().appendChild(comment);
259    }
260    }
261   
262    // Lexical Handler methods- not implemented
263   
 
264  0 toggle @Override
265    public void startCDATA()
266    {
267    }
268   
 
269  0 toggle @Override
270    public void endCDATA()
271    {
272    }
273   
 
274  0 toggle @Override
275    public void startEntity(java.lang.String name)
276    {
277    }
278   
 
279  0 toggle @Override
280    public void endEntity(String name)
281    {
282    }
283   
 
284  0 toggle @Override
285    public void startDTD(String name, String publicId, String systemId) throws SAXException
286    {
287    }
288   
 
289  0 toggle @Override
290    public void endDTD()
291    {
292    }
293    }