1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/jaxws_classes/com/sun/xml/internal/stream/buffer/stax/StreamWriterBufferProcessor.java Wed Apr 27 01:27:09 2016 +0800 1.3 @@ -0,0 +1,525 @@ 1.4 +/* 1.5 + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.xml.internal.stream.buffer.stax; 1.30 + 1.31 +import com.sun.xml.internal.stream.buffer.AbstractProcessor; 1.32 +import com.sun.xml.internal.stream.buffer.XMLStreamBuffer; 1.33 + 1.34 +import java.io.IOException; 1.35 +import java.util.Collections; 1.36 +import java.util.HashSet; 1.37 +import java.util.Map; 1.38 +import java.util.Set; 1.39 + 1.40 +import com.sun.xml.internal.org.jvnet.staxex.Base64Data; 1.41 +import com.sun.xml.internal.org.jvnet.staxex.XMLStreamWriterEx; 1.42 + 1.43 +import javax.xml.stream.XMLStreamException; 1.44 +import javax.xml.stream.XMLStreamWriter; 1.45 + 1.46 + 1.47 +/** 1.48 + * A processor of a {@link XMLStreamBuffer} that writes the XML infoset to a 1.49 + * {@link XMLStreamWriter}. 1.50 + * 1.51 + * @author Paul.Sandoz@Sun.Com 1.52 + * @author K.Venugopal@sun.com 1.53 + */ 1.54 +public class StreamWriterBufferProcessor extends AbstractProcessor { 1.55 + 1.56 + 1.57 + public StreamWriterBufferProcessor() { 1.58 + } 1.59 + 1.60 + /** 1.61 + * @deprecated 1.62 + * Use {@link #StreamWriterBufferProcessor(XMLStreamBuffer, boolean)} 1.63 + */ 1.64 + public StreamWriterBufferProcessor(XMLStreamBuffer buffer) { 1.65 + setXMLStreamBuffer(buffer,buffer.isFragment()); 1.66 + } 1.67 + 1.68 + /** 1.69 + * @param produceFragmentEvent 1.70 + * True to generate fragment SAX events without start/endDocument. 1.71 + * False to generate a full document SAX events. 1.72 + */ 1.73 + public StreamWriterBufferProcessor(XMLStreamBuffer buffer,boolean produceFragmentEvent) { 1.74 + setXMLStreamBuffer(buffer,produceFragmentEvent); 1.75 + } 1.76 + 1.77 + public final void process(XMLStreamBuffer buffer, XMLStreamWriter writer) throws XMLStreamException { 1.78 + setXMLStreamBuffer(buffer,buffer.isFragment()); 1.79 + process(writer); 1.80 + } 1.81 + 1.82 + public void process(XMLStreamWriter writer) throws XMLStreamException { 1.83 + if(_fragmentMode){ 1.84 + writeFragment(writer); 1.85 + }else{ 1.86 + write(writer); 1.87 + } 1.88 + } 1.89 + 1.90 + /** 1.91 + * @deprecated 1.92 + * Use {@link #setXMLStreamBuffer(XMLStreamBuffer, boolean)} 1.93 + */ 1.94 + public void setXMLStreamBuffer(XMLStreamBuffer buffer) { 1.95 + setBuffer(buffer); 1.96 + } 1.97 + 1.98 + /** 1.99 + * @param produceFragmentEvent 1.100 + * True to generate fragment SAX events without start/endDocument. 1.101 + * False to generate a full document SAX events. 1.102 + */ 1.103 + public void setXMLStreamBuffer(XMLStreamBuffer buffer, boolean produceFragmentEvent) { 1.104 + setBuffer(buffer,produceFragmentEvent); 1.105 + } 1.106 + 1.107 + /** 1.108 + * Writes a full XML infoset event to the given writer, 1.109 + * including start/end document. 1.110 + * Any inscope namespaces present will be written as namespace 1.111 + * delcarations on each top-level element. 1.112 + */ 1.113 + public void write(XMLStreamWriter writer) throws XMLStreamException{ 1.114 + 1.115 + if(!_fragmentMode) { 1.116 + if(_treeCount>1) 1.117 + throw new IllegalStateException("forest cannot be written as a full infoset"); 1.118 + writer.writeStartDocument(); 1.119 + } 1.120 + 1.121 + while(true) { 1.122 + int item = getEIIState(peekStructure()); 1.123 + writer.flush(); 1.124 + 1.125 + switch(item) { 1.126 + case STATE_DOCUMENT: 1.127 + readStructure(); //skip 1.128 + break; 1.129 + case STATE_ELEMENT_U_LN_QN: 1.130 + case STATE_ELEMENT_P_U_LN: 1.131 + case STATE_ELEMENT_U_LN: 1.132 + case STATE_ELEMENT_LN: 1.133 + writeFragment(writer); 1.134 + break; 1.135 + case STATE_COMMENT_AS_CHAR_ARRAY_SMALL: { 1.136 + readStructure(); 1.137 + final int length = readStructure(); 1.138 + final int start = readContentCharactersBuffer(length); 1.139 + final String comment = new String(_contentCharactersBuffer, start, length); 1.140 + writer.writeComment(comment); 1.141 + break; 1.142 + } 1.143 + case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM: { 1.144 + readStructure(); 1.145 + final int length = readStructure16(); 1.146 + final int start = readContentCharactersBuffer(length); 1.147 + final String comment = new String(_contentCharactersBuffer, start, length); 1.148 + writer.writeComment(comment); 1.149 + break; 1.150 + } 1.151 + case STATE_COMMENT_AS_CHAR_ARRAY_COPY: { 1.152 + readStructure(); 1.153 + final char[] ch = readContentCharactersCopy(); 1.154 + writer.writeComment(new String(ch)); 1.155 + break; 1.156 + } 1.157 + case STATE_PROCESSING_INSTRUCTION: 1.158 + readStructure(); 1.159 + writer.writeProcessingInstruction(readStructureString(), readStructureString()); 1.160 + break; 1.161 + case STATE_END: // done 1.162 + readStructure(); 1.163 + writer.writeEndDocument(); 1.164 + return; 1.165 + default: 1.166 + throw new XMLStreamException("Invalid State "+item); 1.167 + } 1.168 + } 1.169 + 1.170 + } 1.171 + 1.172 + /** 1.173 + * Writes the buffer as a fragment, meaning 1.174 + * the writer will not receive start/endDocument events. 1.175 + * Any inscope namespaces present will be written as namespace 1.176 + * delcarations on each top-level element. 1.177 + * <p> 1.178 + * If {@link XMLStreamBuffer} has a forest, this method will write all the forests. 1.179 + */ 1.180 + public void writeFragment(XMLStreamWriter writer) throws XMLStreamException { 1.181 + if (writer instanceof XMLStreamWriterEx) { 1.182 + writeFragmentEx((XMLStreamWriterEx)writer); 1.183 + } else { 1.184 + writeFragmentNoEx(writer); 1.185 + } 1.186 + } 1.187 + 1.188 + public void writeFragmentEx(XMLStreamWriterEx writer) throws XMLStreamException { 1.189 + int depth = 0; // used to determine when we are done with a tree. 1.190 + 1.191 + int item = getEIIState(peekStructure()); 1.192 + if(item==STATE_DOCUMENT) 1.193 + readStructure(); // skip STATE_DOCUMENT 1.194 + 1.195 + do { 1.196 + 1.197 + item = readEiiState(); 1.198 + 1.199 + switch(item) { 1.200 + case STATE_DOCUMENT: 1.201 + throw new AssertionError(); 1.202 + case STATE_ELEMENT_U_LN_QN: { 1.203 + depth ++; 1.204 + final String uri = readStructureString(); 1.205 + final String localName = readStructureString(); 1.206 + final String prefix = getPrefixFromQName(readStructureString()); 1.207 + writer.writeStartElement(prefix,localName,uri); 1.208 + writeAttributes(writer, isInscope(depth)); 1.209 + break; 1.210 + } 1.211 + case STATE_ELEMENT_P_U_LN: { 1.212 + depth ++; 1.213 + final String prefix = readStructureString(); 1.214 + final String uri = readStructureString(); 1.215 + final String localName = readStructureString(); 1.216 + writer.writeStartElement(prefix,localName,uri); 1.217 + writeAttributes(writer, isInscope(depth)); 1.218 + break; 1.219 + } 1.220 + case STATE_ELEMENT_U_LN: { 1.221 + depth ++; 1.222 + final String uri = readStructureString(); 1.223 + final String localName = readStructureString(); 1.224 + writer.writeStartElement("",localName,uri); 1.225 + writeAttributes(writer, isInscope(depth)); 1.226 + break; 1.227 + } 1.228 + case STATE_ELEMENT_LN: { 1.229 + depth ++; 1.230 + final String localName = readStructureString(); 1.231 + writer.writeStartElement(localName); 1.232 + writeAttributes(writer, isInscope(depth)); 1.233 + break; 1.234 + } 1.235 + case STATE_TEXT_AS_CHAR_ARRAY_SMALL: { 1.236 + final int length = readStructure(); 1.237 + final int start = readContentCharactersBuffer(length); 1.238 + writer.writeCharacters(_contentCharactersBuffer,start,length); 1.239 + break; 1.240 + } 1.241 + case STATE_TEXT_AS_CHAR_ARRAY_MEDIUM: { 1.242 + final int length = readStructure16(); 1.243 + final int start = readContentCharactersBuffer(length); 1.244 + writer.writeCharacters(_contentCharactersBuffer,start,length); 1.245 + break; 1.246 + } 1.247 + case STATE_TEXT_AS_CHAR_ARRAY_COPY: { 1.248 + char[] c = readContentCharactersCopy(); 1.249 + writer.writeCharacters(c,0,c.length); 1.250 + break; 1.251 + } 1.252 + case STATE_TEXT_AS_STRING: { 1.253 + final String s = readContentString(); 1.254 + writer.writeCharacters(s); 1.255 + break; 1.256 + } 1.257 + case STATE_TEXT_AS_OBJECT: { 1.258 + final CharSequence c = (CharSequence)readContentObject(); 1.259 + writer.writePCDATA(c); 1.260 + break; 1.261 + } 1.262 + case STATE_COMMENT_AS_CHAR_ARRAY_SMALL: { 1.263 + final int length = readStructure(); 1.264 + final int start = readContentCharactersBuffer(length); 1.265 + final String comment = new String(_contentCharactersBuffer, start, length); 1.266 + writer.writeComment(comment); 1.267 + break; 1.268 + } 1.269 + case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM: { 1.270 + final int length = readStructure16(); 1.271 + final int start = readContentCharactersBuffer(length); 1.272 + final String comment = new String(_contentCharactersBuffer, start, length); 1.273 + writer.writeComment(comment); 1.274 + break; 1.275 + } 1.276 + case STATE_COMMENT_AS_CHAR_ARRAY_COPY: { 1.277 + final char[] ch = readContentCharactersCopy(); 1.278 + writer.writeComment(new String(ch)); 1.279 + break; 1.280 + } 1.281 + case STATE_PROCESSING_INSTRUCTION: 1.282 + writer.writeProcessingInstruction(readStructureString(), readStructureString()); 1.283 + break; 1.284 + case STATE_END: 1.285 + writer.writeEndElement(); 1.286 + depth --; 1.287 + if(depth==0) 1.288 + _treeCount--; 1.289 + break; 1.290 + default: 1.291 + throw new XMLStreamException("Invalid State "+item); 1.292 + } 1.293 + } while(depth>0 || _treeCount>0); 1.294 + 1.295 + } 1.296 + 1.297 + public void writeFragmentNoEx(XMLStreamWriter writer) throws XMLStreamException { 1.298 + int depth = 0; 1.299 + 1.300 + int item = getEIIState(peekStructure()); 1.301 + if(item==STATE_DOCUMENT) 1.302 + readStructure(); // skip STATE_DOCUMENT 1.303 + 1.304 + do { 1.305 + item = readEiiState(); 1.306 + 1.307 + switch(item) { 1.308 + case STATE_DOCUMENT: 1.309 + throw new AssertionError(); 1.310 + case STATE_ELEMENT_U_LN_QN: { 1.311 + depth ++; 1.312 + final String uri = readStructureString(); 1.313 + final String localName = readStructureString(); 1.314 + final String prefix = getPrefixFromQName(readStructureString()); 1.315 + writer.writeStartElement(prefix,localName,uri); 1.316 + writeAttributes(writer, isInscope(depth)); 1.317 + break; 1.318 + } 1.319 + case STATE_ELEMENT_P_U_LN: { 1.320 + depth ++; 1.321 + final String prefix = readStructureString(); 1.322 + final String uri = readStructureString(); 1.323 + final String localName = readStructureString(); 1.324 + writer.writeStartElement(prefix,localName,uri); 1.325 + writeAttributes(writer, isInscope(depth)); 1.326 + break; 1.327 + } 1.328 + case STATE_ELEMENT_U_LN: { 1.329 + depth ++; 1.330 + final String uri = readStructureString(); 1.331 + final String localName = readStructureString(); 1.332 + writer.writeStartElement("",localName,uri); 1.333 + writeAttributes(writer, isInscope(depth)); 1.334 + break; 1.335 + } 1.336 + case STATE_ELEMENT_LN: { 1.337 + depth ++; 1.338 + final String localName = readStructureString(); 1.339 + writer.writeStartElement(localName); 1.340 + writeAttributes(writer, isInscope(depth)); 1.341 + break; 1.342 + } 1.343 + case STATE_TEXT_AS_CHAR_ARRAY_SMALL: { 1.344 + final int length = readStructure(); 1.345 + final int start = readContentCharactersBuffer(length); 1.346 + writer.writeCharacters(_contentCharactersBuffer,start,length); 1.347 + break; 1.348 + } 1.349 + case STATE_TEXT_AS_CHAR_ARRAY_MEDIUM: { 1.350 + final int length = readStructure16(); 1.351 + final int start = readContentCharactersBuffer(length); 1.352 + writer.writeCharacters(_contentCharactersBuffer,start,length); 1.353 + break; 1.354 + } 1.355 + case STATE_TEXT_AS_CHAR_ARRAY_COPY: { 1.356 + char[] c = readContentCharactersCopy(); 1.357 + writer.writeCharacters(c,0,c.length); 1.358 + break; 1.359 + } 1.360 + case STATE_TEXT_AS_STRING: { 1.361 + final String s = readContentString(); 1.362 + writer.writeCharacters(s); 1.363 + break; 1.364 + } 1.365 + case STATE_TEXT_AS_OBJECT: { 1.366 + final CharSequence c = (CharSequence)readContentObject(); 1.367 + if (c instanceof Base64Data) { 1.368 + try { 1.369 + Base64Data bd = (Base64Data)c; 1.370 + bd.writeTo(writer); 1.371 + } catch (IOException e) { 1.372 + throw new XMLStreamException(e); 1.373 + } 1.374 + } else { 1.375 + writer.writeCharacters(c.toString()); 1.376 + } 1.377 + break; 1.378 + } 1.379 + case STATE_COMMENT_AS_CHAR_ARRAY_SMALL: { 1.380 + final int length = readStructure(); 1.381 + final int start = readContentCharactersBuffer(length); 1.382 + final String comment = new String(_contentCharactersBuffer, start, length); 1.383 + writer.writeComment(comment); 1.384 + break; 1.385 + } 1.386 + case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM: { 1.387 + final int length = readStructure16(); 1.388 + final int start = readContentCharactersBuffer(length); 1.389 + final String comment = new String(_contentCharactersBuffer, start, length); 1.390 + writer.writeComment(comment); 1.391 + break; 1.392 + } 1.393 + case STATE_COMMENT_AS_CHAR_ARRAY_COPY: { 1.394 + final char[] ch = readContentCharactersCopy(); 1.395 + writer.writeComment(new String(ch)); 1.396 + break; 1.397 + } 1.398 + case STATE_PROCESSING_INSTRUCTION: 1.399 + writer.writeProcessingInstruction(readStructureString(), readStructureString()); 1.400 + break; 1.401 + case STATE_END: 1.402 + writer.writeEndElement(); 1.403 + depth --; 1.404 + if(depth==0) 1.405 + _treeCount--; 1.406 + break; 1.407 + default: 1.408 + throw new XMLStreamException("Invalid State "+item); 1.409 + } 1.410 + } while(depth > 0 || _treeCount>0); 1.411 + 1.412 + } 1.413 + 1.414 + private boolean isInscope(int depth) { 1.415 + return _buffer.getInscopeNamespaces().size() > 0 && depth ==1; 1.416 + } 1.417 + 1.418 + /* 1.419 + * @param inscope: true means write inscope namespaces 1.420 + */ 1.421 + private void writeAttributes(XMLStreamWriter writer, boolean inscope) throws XMLStreamException { 1.422 + // prefixSet to collect prefixes that are written before writing inscope namespaces 1.423 + Set<String> prefixSet = inscope ? new HashSet<String>() : Collections.<String>emptySet(); 1.424 + int item = peekStructure(); 1.425 + if ((item & TYPE_MASK) == T_NAMESPACE_ATTRIBUTE) { 1.426 + // Skip the namespace declarations on the element 1.427 + // they will have been added already 1.428 + item = writeNamespaceAttributes(item, writer, inscope, prefixSet); 1.429 + } 1.430 + if (inscope) { 1.431 + writeInscopeNamespaces(writer, prefixSet); 1.432 + } 1.433 + if ((item & TYPE_MASK) == T_ATTRIBUTE) { 1.434 + writeAttributes(item, writer); 1.435 + } 1.436 + } 1.437 + 1.438 + private static String fixNull(String s) { 1.439 + if (s == null) return ""; 1.440 + else return s; 1.441 + } 1.442 + 1.443 + /* 1.444 + * @param prefixSet: already written prefixes 1.445 + */ 1.446 + private void writeInscopeNamespaces(XMLStreamWriter writer, Set<String> prefixSet) throws XMLStreamException { 1.447 + for (Map.Entry<String, String> e : _buffer.getInscopeNamespaces().entrySet()) { 1.448 + String key = fixNull(e.getKey()); 1.449 + // If the prefix is already written, do not write the prefix 1.450 + if (!prefixSet.contains(key)) { 1.451 + writer.writeNamespace(key, e.getValue()); 1.452 + } 1.453 + } 1.454 + } 1.455 + 1.456 + private int writeNamespaceAttributes(int item, XMLStreamWriter writer, boolean collectPrefixes, Set<String> prefixSet) throws XMLStreamException { 1.457 + do { 1.458 + switch(getNIIState(item)){ 1.459 + case STATE_NAMESPACE_ATTRIBUTE: 1.460 + // Undeclaration of default namespace 1.461 + writer.writeDefaultNamespace(""); 1.462 + if (collectPrefixes) { 1.463 + prefixSet.add(""); 1.464 + } 1.465 + break; 1.466 + case STATE_NAMESPACE_ATTRIBUTE_P: 1.467 + // Undeclaration of namespace 1.468 + // Declaration with prefix 1.469 + String prefix = readStructureString(); 1.470 + writer.writeNamespace(prefix, ""); 1.471 + if (collectPrefixes) { 1.472 + prefixSet.add(prefix); 1.473 + } 1.474 + break; 1.475 + case STATE_NAMESPACE_ATTRIBUTE_P_U: 1.476 + // Declaration with prefix 1.477 + prefix = readStructureString(); 1.478 + writer.writeNamespace(prefix, readStructureString()); 1.479 + if (collectPrefixes) { 1.480 + prefixSet.add(prefix); 1.481 + } 1.482 + break; 1.483 + case STATE_NAMESPACE_ATTRIBUTE_U: 1.484 + // Default declaration 1.485 + writer.writeDefaultNamespace(readStructureString()); 1.486 + if (collectPrefixes) { 1.487 + prefixSet.add(""); 1.488 + } 1.489 + break; 1.490 + } 1.491 + readStructure(); 1.492 + 1.493 + item = peekStructure(); 1.494 + } while((item & TYPE_MASK) == T_NAMESPACE_ATTRIBUTE); 1.495 + 1.496 + return item; 1.497 + } 1.498 + 1.499 + private void writeAttributes(int item, XMLStreamWriter writer) throws XMLStreamException { 1.500 + do { 1.501 + switch(getAIIState(item)) { 1.502 + case STATE_ATTRIBUTE_U_LN_QN: { 1.503 + final String uri = readStructureString(); 1.504 + final String localName = readStructureString(); 1.505 + final String prefix = getPrefixFromQName(readStructureString()); 1.506 + writer.writeAttribute(prefix,uri,localName,readContentString()); 1.507 + break; 1.508 + } 1.509 + case STATE_ATTRIBUTE_P_U_LN: 1.510 + writer.writeAttribute(readStructureString(), readStructureString(), 1.511 + readStructureString(), readContentString()); 1.512 + break; 1.513 + case STATE_ATTRIBUTE_U_LN: 1.514 + writer.writeAttribute(readStructureString(), readStructureString(), readContentString()); 1.515 + break; 1.516 + case STATE_ATTRIBUTE_LN: 1.517 + writer.writeAttribute(readStructureString(), readContentString()); 1.518 + break; 1.519 + } 1.520 + // Ignore the attribute type 1.521 + readStructureString(); 1.522 + 1.523 + readStructure(); 1.524 + 1.525 + item = peekStructure(); 1.526 + } while((item & TYPE_MASK) == T_ATTRIBUTE); 1.527 + } 1.528 +}