Wed, 12 Jun 2013 14:47:09 +0100
8013021: Rebase 8005432 & 8003542 against the latest jdk8/jaxws
8003542: Improve processing of MTOM attachments
8005432: Update access to JAX-WS
Reviewed-by: mullan
1 /*
2 * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 *
25 * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC.
26 */
28 package com.sun.xml.internal.fastinfoset.dom;
30 import com.sun.xml.internal.fastinfoset.Encoder;
31 import com.sun.xml.internal.fastinfoset.EncodingConstants;
32 import com.sun.xml.internal.fastinfoset.QualifiedName;
33 import com.sun.xml.internal.fastinfoset.util.NamespaceContextImplementation;
34 import com.sun.xml.internal.fastinfoset.util.LocalNameQualifiedNamesMap;
35 import java.io.IOException;
36 import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetException;
37 import org.w3c.dom.Document;
38 import org.w3c.dom.NamedNodeMap;
39 import org.w3c.dom.Node;
40 import org.w3c.dom.NodeList;
42 /**
43 * The Fast Infoset DOM serializer.
44 * <p>
45 * Instantiate this serializer to serialize a fast infoset document in accordance
46 * with the DOM API.
47 *
48 */
49 public class DOMDocumentSerializer extends Encoder {
51 /**
52 * Serialize a {@link Node}.
53 *
54 * @param n the node to serialize.
55 */
56 public final void serialize(Node n) throws IOException {
57 switch (n.getNodeType()) {
58 case Node.DOCUMENT_NODE:
59 serialize((Document)n);
60 break;
61 case Node.ELEMENT_NODE:
62 serializeElementAsDocument(n);
63 break;
64 case Node.COMMENT_NODE:
65 serializeComment(n);
66 break;
67 case Node.PROCESSING_INSTRUCTION_NODE:
68 serializeProcessingInstruction(n);
69 break;
70 }
71 }
73 /**
74 * Serialize a {@link Document}.
75 *
76 * @param d the document to serialize.
77 */
78 public final void serialize(Document d) throws IOException {
79 reset();
80 encodeHeader(false);
81 encodeInitialVocabulary();
83 final NodeList nl = d.getChildNodes();
84 for (int i = 0; i < nl.getLength(); i++) {
85 final Node n = nl.item(i);
86 switch (n.getNodeType()) {
87 case Node.ELEMENT_NODE:
88 serializeElement(n);
89 break;
90 case Node.COMMENT_NODE:
91 serializeComment(n);
92 break;
93 case Node.PROCESSING_INSTRUCTION_NODE:
94 serializeProcessingInstruction(n);
95 break;
96 }
97 }
98 encodeDocumentTermination();
99 }
101 protected final void serializeElementAsDocument(Node e) throws IOException {
102 reset();
103 encodeHeader(false);
104 encodeInitialVocabulary();
106 serializeElement(e);
108 encodeDocumentTermination();
109 }
111 // protected Node[] _namespaceAttributes = new Node[4];
113 // map which will hold all current scope prefixes and associated attributes
114 // Collection of populated namespace available for current scope
115 protected NamespaceContextImplementation _namespaceScopeContext = new NamespaceContextImplementation();
116 protected Node[] _attributes = new Node[32];
118 protected final void serializeElement(Node e) throws IOException {
119 encodeTermination();
121 int attributesSize = 0;
123 _namespaceScopeContext.pushContext();
125 if (e.hasAttributes()) {
126 /*
127 * Split the attribute nodes into namespace attributes
128 * or normal attributes.
129 */
130 final NamedNodeMap nnm = e.getAttributes();
131 for (int i = 0; i < nnm.getLength(); i++) {
132 final Node a = nnm.item(i);
133 final String namespaceURI = a.getNamespaceURI();
134 if (namespaceURI != null && namespaceURI.equals("http://www.w3.org/2000/xmlns/")) {
135 String attrPrefix = a.getLocalName();
136 String attrNamespace = a.getNodeValue();
137 if (attrPrefix == "xmlns" || attrPrefix.equals("xmlns")) {
138 attrPrefix = "";
139 }
140 _namespaceScopeContext.declarePrefix(attrPrefix, attrNamespace);
141 } else {
142 if (attributesSize == _attributes.length) {
143 final Node[] attributes = new Node[attributesSize * 3 / 2 + 1];
144 System.arraycopy(_attributes, 0, attributes, 0, attributesSize);
145 _attributes = attributes;
146 }
147 _attributes[attributesSize++] = a;
149 String attrNamespaceURI = a.getNamespaceURI();
150 String attrPrefix = a.getPrefix();
151 if (attrPrefix != null && !_namespaceScopeContext.getNamespaceURI(attrPrefix).equals(attrNamespaceURI)) {
152 _namespaceScopeContext.declarePrefix(attrPrefix, attrNamespaceURI);
153 }
154 }
155 }
156 }
158 String elementNamespaceURI = e.getNamespaceURI();
159 String elementPrefix = e.getPrefix();
160 if (elementPrefix == null) elementPrefix = "";
161 if (elementNamespaceURI != null &&
162 !_namespaceScopeContext.getNamespaceURI(elementPrefix).equals(elementNamespaceURI)) {
163 _namespaceScopeContext.declarePrefix(elementPrefix, elementNamespaceURI);
164 }
166 if (!_namespaceScopeContext.isCurrentContextEmpty()) {
167 if (attributesSize > 0) {
168 write(EncodingConstants.ELEMENT | EncodingConstants.ELEMENT_NAMESPACES_FLAG |
169 EncodingConstants.ELEMENT_ATTRIBUTE_FLAG);
170 } else {
171 write(EncodingConstants.ELEMENT | EncodingConstants.ELEMENT_NAMESPACES_FLAG);
172 }
174 for (int i = _namespaceScopeContext.getCurrentContextStartIndex();
175 i < _namespaceScopeContext.getCurrentContextEndIndex(); i++) {
177 String prefix = _namespaceScopeContext.getPrefix(i);
178 String uri = _namespaceScopeContext.getNamespaceURI(i);
179 encodeNamespaceAttribute(prefix, uri);
180 }
181 write(EncodingConstants.TERMINATOR);
182 _b = 0;
183 } else {
184 _b = (attributesSize > 0) ? EncodingConstants.ELEMENT | EncodingConstants.ELEMENT_ATTRIBUTE_FLAG :
185 EncodingConstants.ELEMENT;
186 }
188 String namespaceURI = elementNamespaceURI;
189 // namespaceURI = (namespaceURI == null) ? _namespaceScopeContext.getNamespaceURI("") : namespaceURI;
190 namespaceURI = (namespaceURI == null) ? "" : namespaceURI;
191 encodeElement(namespaceURI, e.getNodeName(), e.getLocalName());
193 if (attributesSize > 0) {
194 // Serialize the attributes
195 for (int i = 0; i < attributesSize; i++) {
196 final Node a = _attributes[i];
197 _attributes[i] = null;
198 namespaceURI = a.getNamespaceURI();
199 namespaceURI = (namespaceURI == null) ? "" : namespaceURI;
200 encodeAttribute(namespaceURI, a.getNodeName(), a.getLocalName());
202 final String value = a.getNodeValue();
203 final boolean addToTable = isAttributeValueLengthMatchesLimit(value.length());
204 encodeNonIdentifyingStringOnFirstBit(value, _v.attributeValue, addToTable, false);
205 }
207 _b = EncodingConstants.TERMINATOR;
208 _terminate = true;
209 }
211 if (e.hasChildNodes()) {
212 // Serialize the children
213 final NodeList nl = e.getChildNodes();
214 for (int i = 0; i < nl.getLength(); i++) {
215 final Node n = nl.item(i);
216 switch (n.getNodeType()) {
217 case Node.ELEMENT_NODE:
218 serializeElement(n);
219 break;
220 case Node.TEXT_NODE:
221 serializeText(n);
222 break;
223 case Node.CDATA_SECTION_NODE:
224 serializeCDATA(n);
225 break;
226 case Node.COMMENT_NODE:
227 serializeComment(n);
228 break;
229 case Node.PROCESSING_INSTRUCTION_NODE:
230 serializeProcessingInstruction(n);
231 break;
232 }
233 }
234 }
235 encodeElementTermination();
236 _namespaceScopeContext.popContext();
237 }
240 protected final void serializeText(Node t) throws IOException {
241 final String text = t.getNodeValue();
243 final int length = (text != null) ? text.length() : 0;
244 if (length == 0) {
245 return;
246 } else if (length < _charBuffer.length) {
247 text.getChars(0, length, _charBuffer, 0);
248 if (getIgnoreWhiteSpaceTextContent() &&
249 isWhiteSpace(_charBuffer, 0, length)) return;
251 encodeTermination();
252 encodeCharacters(_charBuffer, 0, length);
253 } else {
254 final char ch[] = text.toCharArray();
255 if (getIgnoreWhiteSpaceTextContent() &&
256 isWhiteSpace(ch, 0, length)) return;
258 encodeTermination();
259 encodeCharactersNoClone(ch, 0, length);
260 }
261 }
263 protected final void serializeCDATA(Node t) throws IOException {
264 final String text = t.getNodeValue();
266 final int length = (text != null) ? text.length() : 0;
267 if (length == 0) {
268 return;
269 } else {
270 final char ch[] = text.toCharArray();
271 if (getIgnoreWhiteSpaceTextContent() &&
272 isWhiteSpace(ch, 0, length)) return;
274 encodeTermination();
275 try {
276 encodeCIIBuiltInAlgorithmDataAsCDATA(ch, 0, length);
277 } catch (FastInfosetException e) {
278 throw new IOException("");
279 }
280 }
281 }
283 protected final void serializeComment(Node c) throws IOException {
284 if (getIgnoreComments()) return;
286 encodeTermination();
288 final String comment = c.getNodeValue();
290 final int length = (comment != null) ? comment.length() : 0;
291 if (length == 0) {
292 encodeComment(_charBuffer, 0, 0);
293 } else if (length < _charBuffer.length) {
294 comment.getChars(0, length, _charBuffer, 0);
295 encodeComment(_charBuffer, 0, length);
296 } else {
297 final char ch[] = comment.toCharArray();
298 encodeCommentNoClone(ch, 0, length);
299 }
300 }
302 protected final void serializeProcessingInstruction(Node pi) throws IOException {
303 if (getIgnoreProcesingInstructions()) return;
305 encodeTermination();
307 final String target = pi.getNodeName();
308 final String data = pi.getNodeValue();
309 encodeProcessingInstruction(target, data);
310 }
312 protected final void encodeElement(String namespaceURI, String qName, String localName) throws IOException {
313 LocalNameQualifiedNamesMap.Entry entry = _v.elementName.obtainEntry(qName);
314 if (entry._valueIndex > 0) {
315 final QualifiedName[] names = entry._value;
316 for (int i = 0; i < entry._valueIndex; i++) {
317 if ((namespaceURI == names[i].namespaceName || namespaceURI.equals(names[i].namespaceName))) {
318 encodeNonZeroIntegerOnThirdBit(names[i].index);
319 return;
320 }
321 }
322 }
324 // Was DOM node created using an NS-aware call?
325 if (localName != null) {
326 encodeLiteralElementQualifiedNameOnThirdBit(namespaceURI, getPrefixFromQualifiedName(qName),
327 localName, entry);
328 } else {
329 encodeLiteralElementQualifiedNameOnThirdBit(namespaceURI, "", qName, entry);
330 }
331 }
333 protected final void encodeAttribute(String namespaceURI, String qName, String localName) throws IOException {
334 LocalNameQualifiedNamesMap.Entry entry = _v.attributeName.obtainEntry(qName);
335 if (entry._valueIndex > 0) {
336 final QualifiedName[] names = entry._value;
337 for (int i = 0; i < entry._valueIndex; i++) {
338 if ((namespaceURI == names[i].namespaceName || namespaceURI.equals(names[i].namespaceName))) {
339 encodeNonZeroIntegerOnSecondBitFirstBitZero(names[i].index);
340 return;
341 }
342 }
343 }
345 // Was DOM node created using an NS-aware call?
346 if (localName != null) {
347 encodeLiteralAttributeQualifiedNameOnSecondBit(namespaceURI, getPrefixFromQualifiedName(qName),
348 localName, entry);
349 } else {
350 encodeLiteralAttributeQualifiedNameOnSecondBit(namespaceURI, "", qName, entry);
351 }
352 }
353 }