author | henryjen |
Mon, 22 Jan 2018 23:37:23 -0800 | |
changeset 48657 | 7e5fbd3a2254 |
parent 48577 | 8dff65f1d611 |
child 50114 | d2cfda6a00de |
permissions | -rw-r--r-- |
12005 | 1 |
/* |
48577 | 2 |
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. |
12005 | 3 |
*/ |
4 |
/* |
|
44797
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
5 |
* Licensed to the Apache Software Foundation (ASF) under one or more |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
6 |
* contributor license agreements. See the NOTICE file distributed with |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
7 |
* this work for additional information regarding copyright ownership. |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
8 |
* The ASF licenses this file to You under the Apache License, Version 2.0 |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
9 |
* (the "License"); you may not use this file except in compliance with |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
10 |
* the License. You may obtain a copy of the License at |
12005 | 11 |
* |
44797
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
12 |
* http://www.apache.org/licenses/LICENSE-2.0 |
12005 | 13 |
* |
14 |
* Unless required by applicable law or agreed to in writing, software |
|
15 |
* distributed under the License is distributed on an "AS IS" BASIS, |
|
16 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
17 |
* See the License for the specific language governing permissions and |
|
18 |
* limitations under the License. |
|
19 |
*/ |
|
20 |
||
21 |
||
22 |
package com.sun.org.apache.xalan.internal.xsltc.trax; |
|
23 |
||
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
24 |
import com.sun.org.apache.xalan.internal.xsltc.runtime.Constants; |
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
25 |
import java.util.ArrayList; |
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
26 |
import java.util.List; |
12005 | 27 |
import java.util.Stack; |
48577 | 28 |
|
12005 | 29 |
import javax.xml.parsers.DocumentBuilderFactory; |
30 |
import javax.xml.parsers.ParserConfigurationException; |
|
48577 | 31 |
|
32 |
import com.sun.org.apache.xalan.internal.xsltc.runtime.Constants; |
|
33 |
import jdk.xml.internal.JdkXmlUtils; |
|
34 |
||
12005 | 35 |
import org.w3c.dom.Comment; |
36 |
import org.w3c.dom.Document; |
|
37 |
import org.w3c.dom.Element; |
|
38 |
import org.w3c.dom.Node; |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
39 |
import org.w3c.dom.ProcessingInstruction; |
12005 | 40 |
import org.xml.sax.Attributes; |
41 |
import org.xml.sax.ContentHandler; |
|
42 |
import org.xml.sax.Locator; |
|
43 |
import org.xml.sax.SAXException; |
|
44 |
import org.xml.sax.ext.LexicalHandler; |
|
45 |
import org.xml.sax.ext.Locator2; |
|
46 |
||
47 |
/** |
|
48 |
* @author G. Todd Miller |
|
49 |
* @author Sunitha Reddy |
|
12458 | 50 |
* @author Huizhe Wang |
48409 | 51 |
* @LastModified: Nov 2017 |
12005 | 52 |
*/ |
53 |
public class SAX2DOM implements ContentHandler, LexicalHandler, Constants { |
|
54 |
||
55 |
private Node _root = null; |
|
56 |
private Document _document = null; |
|
57 |
private Node _nextSibling = null; |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
58 |
private Stack<Node> _nodeStk = new Stack<>(); |
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
59 |
private List<String> _namespaceDecls = null; |
12005 | 60 |
private Node _lastSibling = null; |
61 |
private Locator locator = null; |
|
62 |
private boolean needToSetDocumentInfo = true; |
|
63 |
||
64 |
//Replace StringBuffer with StringBuilder now that we no long support jdk1.4 |
|
65 |
private StringBuilder _textBuffer = new StringBuilder(); |
|
66 |
private Node _nextSiblingCache = null; |
|
67 |
/** |
|
68 |
* JAXP document builder factory. Create a single instance and use |
|
69 |
* synchronization because the Javadoc is not explicit about |
|
70 |
* thread safety. |
|
71 |
*/ |
|
48577 | 72 |
private DocumentBuilderFactory _factory; |
12458 | 73 |
private boolean _internal = true; |
12005 | 74 |
|
48577 | 75 |
public SAX2DOM(boolean overrideDefaultParser) throws ParserConfigurationException { |
76 |
_document = createDocument(overrideDefaultParser); |
|
12005 | 77 |
_root = _document; |
78 |
} |
|
79 |
||
48577 | 80 |
public SAX2DOM(Node root, Node nextSibling, boolean overrideDefaultParser) |
81 |
throws ParserConfigurationException { |
|
12005 | 82 |
_root = root; |
83 |
if (root instanceof Document) { |
|
84 |
_document = (Document)root; |
|
85 |
} |
|
86 |
else if (root != null) { |
|
87 |
_document = root.getOwnerDocument(); |
|
88 |
} |
|
89 |
else { |
|
48577 | 90 |
_document = createDocument(overrideDefaultParser); |
12005 | 91 |
_root = _document; |
92 |
} |
|
93 |
||
94 |
_nextSibling = nextSibling; |
|
95 |
} |
|
96 |
||
48577 | 97 |
public SAX2DOM(Node root, boolean overrideDefaultParser) |
98 |
throws ParserConfigurationException { |
|
99 |
this(root, null, overrideDefaultParser); |
|
12005 | 100 |
} |
101 |
||
102 |
public Node getDOM() { |
|
103 |
return _root; |
|
104 |
} |
|
105 |
||
106 |
public void characters(char[] ch, int start, int length) { |
|
107 |
// Ignore text nodes of length 0 |
|
108 |
if (length == 0) { |
|
109 |
return; |
|
110 |
} |
|
111 |
||
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
112 |
final Node last = _nodeStk.peek(); |
12005 | 113 |
|
114 |
// No text nodes can be children of root (DOM006 exception) |
|
115 |
if (last != _document) { |
|
116 |
_nextSiblingCache = _nextSibling; |
|
117 |
_textBuffer.append(ch, start, length); |
|
118 |
} |
|
119 |
} |
|
120 |
private void appendTextNode() { |
|
121 |
if (_textBuffer.length() > 0) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
122 |
final Node last = _nodeStk.peek(); |
12005 | 123 |
if (last == _root && _nextSiblingCache != null) { |
124 |
_lastSibling = last.insertBefore(_document.createTextNode(_textBuffer.toString()), _nextSiblingCache); |
|
125 |
} |
|
126 |
else { |
|
127 |
_lastSibling = last.appendChild(_document.createTextNode(_textBuffer.toString())); |
|
128 |
} |
|
129 |
_textBuffer.setLength(0); |
|
130 |
} |
|
131 |
} |
|
132 |
public void startDocument() { |
|
133 |
_nodeStk.push(_root); |
|
134 |
} |
|
135 |
||
136 |
public void endDocument() { |
|
137 |
_nodeStk.pop(); |
|
138 |
} |
|
139 |
||
140 |
private void setDocumentInfo() { |
|
141 |
//try to set document version |
|
142 |
if (locator == null) return; |
|
143 |
try{ |
|
144 |
_document.setXmlVersion(((Locator2)locator).getXMLVersion()); |
|
145 |
}catch(ClassCastException e){} |
|
146 |
||
147 |
} |
|
148 |
||
149 |
public void startElement(String namespace, String localName, String qName, |
|
150 |
Attributes attrs) |
|
151 |
{ |
|
152 |
appendTextNode(); |
|
153 |
if (needToSetDocumentInfo) { |
|
154 |
setDocumentInfo(); |
|
155 |
needToSetDocumentInfo = false; |
|
156 |
} |
|
157 |
||
47712 | 158 |
final Element tmp = _document.createElementNS(namespace, qName); |
12005 | 159 |
|
160 |
// Add namespace declarations first |
|
161 |
if (_namespaceDecls != null) { |
|
162 |
final int nDecls = _namespaceDecls.size(); |
|
163 |
for (int i = 0; i < nDecls; i++) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
164 |
final String prefix = _namespaceDecls.get(i++); |
12005 | 165 |
|
166 |
if (prefix == null || prefix.equals(EMPTYSTRING)) { |
|
167 |
tmp.setAttributeNS(XMLNS_URI, XMLNS_PREFIX, |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
168 |
_namespaceDecls.get(i)); |
12005 | 169 |
} |
170 |
else { |
|
171 |
tmp.setAttributeNS(XMLNS_URI, XMLNS_STRING + prefix, |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
172 |
_namespaceDecls.get(i)); |
12005 | 173 |
} |
174 |
} |
|
175 |
_namespaceDecls.clear(); |
|
176 |
} |
|
177 |
||
178 |
// Add attributes to element |
|
179 |
/* final int nattrs = attrs.getLength(); |
|
180 |
for (int i = 0; i < nattrs; i++) { |
|
181 |
if (attrs.getLocalName(i) == null) { |
|
182 |
tmp.setAttribute(attrs.getQName(i), attrs.getValue(i)); |
|
183 |
} |
|
184 |
else { |
|
185 |
tmp.setAttributeNS(attrs.getURI(i), attrs.getQName(i), |
|
186 |
attrs.getValue(i)); |
|
187 |
} |
|
188 |
} */ |
|
189 |
||
190 |
||
191 |
// Add attributes to element |
|
192 |
final int nattrs = attrs.getLength(); |
|
193 |
for (int i = 0; i < nattrs; i++) { |
|
194 |
// checking if Namespace processing is being done |
|
195 |
String attQName = attrs.getQName(i); |
|
196 |
String attURI = attrs.getURI(i); |
|
197 |
if (attrs.getLocalName(i).equals("")) { |
|
198 |
tmp.setAttribute(attQName, attrs.getValue(i)); |
|
199 |
if (attrs.getType(i).equals("ID")) { |
|
200 |
tmp.setIdAttribute(attQName, true); |
|
201 |
} |
|
202 |
} else { |
|
203 |
tmp.setAttributeNS(attURI, attQName, attrs.getValue(i)); |
|
204 |
if (attrs.getType(i).equals("ID")) { |
|
205 |
tmp.setIdAttributeNS(attURI, attrs.getLocalName(i), true); |
|
206 |
} |
|
207 |
} |
|
208 |
} |
|
209 |
||
210 |
||
211 |
// Append this new node onto current stack node |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
212 |
Node last = _nodeStk.peek(); |
12005 | 213 |
|
214 |
// If the SAX2DOM is created with a non-null next sibling node, |
|
215 |
// insert the result nodes before the next sibling under the root. |
|
216 |
if (last == _root && _nextSibling != null) |
|
217 |
last.insertBefore(tmp, _nextSibling); |
|
218 |
else |
|
219 |
last.appendChild(tmp); |
|
220 |
||
221 |
// Push this node onto stack |
|
222 |
_nodeStk.push(tmp); |
|
223 |
_lastSibling = null; |
|
224 |
} |
|
225 |
||
226 |
public void endElement(String namespace, String localName, String qName) { |
|
227 |
appendTextNode(); |
|
228 |
_nodeStk.pop(); |
|
229 |
_lastSibling = null; |
|
230 |
} |
|
231 |
||
232 |
public void startPrefixMapping(String prefix, String uri) { |
|
233 |
if (_namespaceDecls == null) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
234 |
_namespaceDecls = new ArrayList<>(2); |
12005 | 235 |
} |
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
236 |
_namespaceDecls.add(prefix); |
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
237 |
_namespaceDecls.add(uri); |
12005 | 238 |
} |
239 |
||
240 |
public void endPrefixMapping(String prefix) { |
|
241 |
// do nothing |
|
242 |
} |
|
243 |
||
244 |
/** |
|
245 |
* This class is only used internally so this method should never |
|
246 |
* be called. |
|
247 |
*/ |
|
248 |
public void ignorableWhitespace(char[] ch, int start, int length) { |
|
249 |
} |
|
250 |
||
251 |
/** |
|
252 |
* adds processing instruction node to DOM. |
|
253 |
*/ |
|
254 |
public void processingInstruction(String target, String data) { |
|
255 |
appendTextNode(); |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
256 |
final Node last = _nodeStk.peek(); |
12005 | 257 |
ProcessingInstruction pi = _document.createProcessingInstruction( |
258 |
target, data); |
|
259 |
if (pi != null){ |
|
260 |
if (last == _root && _nextSibling != null) |
|
261 |
last.insertBefore(pi, _nextSibling); |
|
262 |
else |
|
263 |
last.appendChild(pi); |
|
264 |
||
265 |
_lastSibling = pi; |
|
266 |
} |
|
267 |
} |
|
268 |
||
269 |
/** |
|
270 |
* This class is only used internally so this method should never |
|
271 |
* be called. |
|
272 |
*/ |
|
273 |
public void setDocumentLocator(Locator locator) { |
|
274 |
this.locator = locator; |
|
275 |
} |
|
276 |
||
277 |
/** |
|
278 |
* This class is only used internally so this method should never |
|
279 |
* be called. |
|
280 |
*/ |
|
281 |
public void skippedEntity(String name) { |
|
282 |
} |
|
283 |
||
284 |
||
285 |
/** |
|
286 |
* Lexical Handler method to create comment node in DOM tree. |
|
287 |
*/ |
|
288 |
public void comment(char[] ch, int start, int length) { |
|
289 |
appendTextNode(); |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
290 |
final Node last = _nodeStk.peek(); |
12005 | 291 |
Comment comment = _document.createComment(new String(ch,start,length)); |
292 |
if (comment != null){ |
|
293 |
if (last == _root && _nextSibling != null) |
|
294 |
last.insertBefore(comment, _nextSibling); |
|
295 |
else |
|
296 |
last.appendChild(comment); |
|
297 |
||
298 |
_lastSibling = comment; |
|
299 |
} |
|
300 |
} |
|
301 |
||
302 |
// Lexical Handler methods- not implemented |
|
303 |
public void startCDATA() { } |
|
304 |
public void endCDATA() { } |
|
305 |
public void startEntity(java.lang.String name) { } |
|
306 |
public void endDTD() { } |
|
307 |
public void endEntity(String name) { } |
|
308 |
public void startDTD(String name, String publicId, String systemId) |
|
309 |
throws SAXException {} |
|
310 |
||
48577 | 311 |
private Document createDocument(boolean overrideDefaultParser) |
312 |
throws ParserConfigurationException { |
|
12458 | 313 |
if (_factory == null) { |
48577 | 314 |
_factory = JdkXmlUtils.getDOMFactory(overrideDefaultParser); |
315 |
_internal = true; |
|
316 |
if (!(_factory instanceof com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl)) { |
|
317 |
_internal = false; |
|
21469 | 318 |
} |
12458 | 319 |
} |
12005 | 320 |
Document doc; |
12458 | 321 |
if (_internal) { |
12005 | 322 |
//default implementation is thread safe |
12458 | 323 |
doc = _factory.newDocumentBuilder().newDocument(); |
12005 | 324 |
} else { |
325 |
synchronized(SAX2DOM.class) { |
|
326 |
doc = _factory.newDocumentBuilder().newDocument(); |
|
327 |
} |
|
328 |
} |
|
329 |
return doc; |
|
330 |
} |
|
331 |
||
332 |
} |