1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/FastInfosetConnector.java Wed Apr 27 01:27:09 2016 +0800 1.3 @@ -0,0 +1,294 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2011, 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.bind.v2.runtime.unmarshaller; 1.30 + 1.31 +import javax.xml.stream.Location; 1.32 +import javax.xml.stream.XMLStreamConstants; 1.33 +import javax.xml.stream.XMLStreamException; 1.34 + 1.35 +import com.sun.xml.internal.bind.WhiteSpaceProcessor; 1.36 +import com.sun.xml.internal.fastinfoset.stax.StAXDocumentParser; 1.37 +import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmIndexes; 1.38 +import org.xml.sax.SAXException; 1.39 + 1.40 +/** 1.41 + * Reads from FastInfoset StAX parser and feeds into JAXB Unmarshaller. 1.42 + * <p> 1.43 + * This class will peek at future events to ascertain if characters need to be 1.44 + * buffered or not. 1.45 + * 1.46 + * @author Paul Sandoz. 1.47 + */ 1.48 +final class FastInfosetConnector extends StAXConnector { 1.49 + 1.50 + // event source 1.51 + private final StAXDocumentParser fastInfosetStreamReader; 1.52 + 1.53 + // Flag set to true if text has been reported 1.54 + private boolean textReported; 1.55 + 1.56 + // Buffer for octets 1.57 + private final Base64Data base64Data = new Base64Data(); 1.58 + 1.59 + // Buffer for characters 1.60 + private final StringBuilder buffer = new StringBuilder(); 1.61 + 1.62 + public FastInfosetConnector(StAXDocumentParser fastInfosetStreamReader, 1.63 + XmlVisitor visitor) { 1.64 + super(visitor); 1.65 + fastInfosetStreamReader.setStringInterning(true); 1.66 + this.fastInfosetStreamReader = fastInfosetStreamReader; 1.67 + } 1.68 + 1.69 + public void bridge() throws XMLStreamException { 1.70 + try { 1.71 + // remembers the nest level of elements to know when we are done. 1.72 + int depth=0; 1.73 + 1.74 + // if the parser is at the start tag, proceed to the first element 1.75 + int event = fastInfosetStreamReader.getEventType(); 1.76 + if(event == XMLStreamConstants.START_DOCUMENT) { 1.77 + // nextTag doesn't correctly handle DTDs 1.78 + while( !fastInfosetStreamReader.isStartElement() ) 1.79 + event = fastInfosetStreamReader.next(); 1.80 + } 1.81 + 1.82 + 1.83 + if( event!=XMLStreamConstants.START_ELEMENT) 1.84 + throw new IllegalStateException("The current event is not START_ELEMENT\n but " + event); 1.85 + 1.86 + // TODO: we don't have to rely on this hack --- we can just emulate 1.87 + // start/end prefix mappings. But for now, I'll rely on this hack. 1.88 + handleStartDocument(fastInfosetStreamReader.getNamespaceContext()); 1.89 + 1.90 + OUTER: 1.91 + while(true) { 1.92 + // These are all of the events listed in the javadoc for 1.93 + // XMLEvent. 1.94 + // The spec only really describes 11 of them. 1.95 + switch (event) { 1.96 + case XMLStreamConstants.START_ELEMENT : 1.97 + handleStartElement(); 1.98 + depth++; 1.99 + break; 1.100 + case XMLStreamConstants.END_ELEMENT : 1.101 + depth--; 1.102 + handleEndElement(); 1.103 + if(depth==0) break OUTER; 1.104 + break; 1.105 + case XMLStreamConstants.CHARACTERS : 1.106 + case XMLStreamConstants.CDATA : 1.107 + case XMLStreamConstants.SPACE : 1.108 + if (predictor.expectText()) { 1.109 + // Peek at the next event to see if there are 1.110 + // fragmented characters 1.111 + event = fastInfosetStreamReader.peekNext(); 1.112 + if (event == XMLStreamConstants.END_ELEMENT) 1.113 + processNonIgnorableText(); 1.114 + else if (event == XMLStreamConstants.START_ELEMENT) 1.115 + processIgnorableText(); 1.116 + else 1.117 + handleFragmentedCharacters(); 1.118 + } 1.119 + break; 1.120 + // otherwise simply ignore 1.121 + } 1.122 + 1.123 + event=fastInfosetStreamReader.next(); 1.124 + } 1.125 + 1.126 + fastInfosetStreamReader.next(); // move beyond the end tag. 1.127 + 1.128 + handleEndDocument(); 1.129 + } catch (SAXException e) { 1.130 + throw new XMLStreamException(e); 1.131 + } 1.132 + } 1.133 + 1.134 + protected Location getCurrentLocation() { 1.135 + return fastInfosetStreamReader.getLocation(); 1.136 + } 1.137 + 1.138 + protected String getCurrentQName() { 1.139 + return fastInfosetStreamReader.getNameString(); 1.140 + } 1.141 + 1.142 + private void handleStartElement() throws SAXException { 1.143 + processUnreportedText(); 1.144 + 1.145 + for (int i = 0; i < fastInfosetStreamReader.accessNamespaceCount(); i++) { 1.146 + visitor.startPrefixMapping(fastInfosetStreamReader.getNamespacePrefix(i), 1.147 + fastInfosetStreamReader.getNamespaceURI(i)); 1.148 + } 1.149 + 1.150 + tagName.uri = fastInfosetStreamReader.accessNamespaceURI(); 1.151 + tagName.local = fastInfosetStreamReader.accessLocalName(); 1.152 + tagName.atts = fastInfosetStreamReader.getAttributesHolder(); 1.153 + 1.154 + visitor.startElement(tagName); 1.155 + } 1.156 + 1.157 + private void handleFragmentedCharacters() throws XMLStreamException, SAXException { 1.158 + buffer.setLength(0); 1.159 + 1.160 + // Append characters of first character event 1.161 + buffer.append(fastInfosetStreamReader.getTextCharacters(), 1.162 + fastInfosetStreamReader.getTextStart(), 1.163 + fastInfosetStreamReader.getTextLength()); 1.164 + 1.165 + // Consume all character 1.166 + while(true) { 1.167 + switch(fastInfosetStreamReader.peekNext()) { 1.168 + case XMLStreamConstants.START_ELEMENT : 1.169 + processBufferedText(true); 1.170 + return; 1.171 + case XMLStreamConstants.END_ELEMENT : 1.172 + processBufferedText(false); 1.173 + return; 1.174 + case XMLStreamConstants.CHARACTERS : 1.175 + case XMLStreamConstants.CDATA : 1.176 + case XMLStreamConstants.SPACE : 1.177 + // Append characters of second and subsequent character events 1.178 + fastInfosetStreamReader.next(); 1.179 + buffer.append(fastInfosetStreamReader.getTextCharacters(), 1.180 + fastInfosetStreamReader.getTextStart(), 1.181 + fastInfosetStreamReader.getTextLength()); 1.182 + break; 1.183 + default: 1.184 + fastInfosetStreamReader.next(); 1.185 + } 1.186 + } 1.187 + } 1.188 + 1.189 + private void handleEndElement() throws SAXException { 1.190 + processUnreportedText(); 1.191 + 1.192 + tagName.uri = fastInfosetStreamReader.accessNamespaceURI(); 1.193 + tagName.local = fastInfosetStreamReader.accessLocalName(); 1.194 + 1.195 + visitor.endElement(tagName); 1.196 + 1.197 + for (int i = fastInfosetStreamReader.accessNamespaceCount() - 1; i >= 0; i--) { 1.198 + visitor.endPrefixMapping(fastInfosetStreamReader.getNamespacePrefix(i)); 1.199 + } 1.200 + } 1.201 + 1.202 + final private class CharSequenceImpl implements CharSequence { 1.203 + char[] ch; 1.204 + int start; 1.205 + int length; 1.206 + 1.207 + CharSequenceImpl() { 1.208 + } 1.209 + 1.210 + CharSequenceImpl(final char[] ch, final int start, final int length) { 1.211 + this.ch = ch; 1.212 + this.start = start; 1.213 + this.length = length; 1.214 + } 1.215 + 1.216 + public void set() { 1.217 + ch = fastInfosetStreamReader.getTextCharacters(); 1.218 + start = fastInfosetStreamReader.getTextStart(); 1.219 + length = fastInfosetStreamReader.getTextLength(); 1.220 + } 1.221 + 1.222 + // CharSequence interface 1.223 + 1.224 + public final int length() { 1.225 + return length; 1.226 + } 1.227 + 1.228 + public final char charAt(final int index) { 1.229 + return ch[start + index]; 1.230 + } 1.231 + 1.232 + public final CharSequence subSequence(final int start, final int end) { 1.233 + return new CharSequenceImpl(ch, this.start + start, end - start); 1.234 + } 1.235 + 1.236 + public String toString() { 1.237 + return new String(ch, start, length); 1.238 + } 1.239 + } 1.240 + 1.241 + final private CharSequenceImpl charArray = new CharSequenceImpl(); 1.242 + 1.243 + private void processNonIgnorableText() throws SAXException { 1.244 + textReported = true; 1.245 + boolean isTextAlgorithmAplied = 1.246 + (fastInfosetStreamReader.getTextAlgorithmBytes() != null); 1.247 + 1.248 + if (isTextAlgorithmAplied && 1.249 + fastInfosetStreamReader.getTextAlgorithmIndex() == EncodingAlgorithmIndexes.BASE64) { 1.250 + base64Data.set(fastInfosetStreamReader.getTextAlgorithmBytesClone(),null); 1.251 + visitor.text(base64Data); 1.252 + } else { 1.253 + if (isTextAlgorithmAplied) { 1.254 + fastInfosetStreamReader.getText(); 1.255 + } 1.256 + 1.257 + charArray.set(); 1.258 + visitor.text(charArray); 1.259 + } 1.260 + } 1.261 + 1.262 + private void processIgnorableText() throws SAXException { 1.263 + boolean isTextAlgorithmAplied = 1.264 + (fastInfosetStreamReader.getTextAlgorithmBytes() != null); 1.265 + 1.266 + if (isTextAlgorithmAplied && 1.267 + fastInfosetStreamReader.getTextAlgorithmIndex() == EncodingAlgorithmIndexes.BASE64) { 1.268 + base64Data.set(fastInfosetStreamReader.getTextAlgorithmBytesClone(),null); 1.269 + visitor.text(base64Data); 1.270 + textReported = true; 1.271 + } else { 1.272 + if (isTextAlgorithmAplied) { 1.273 + fastInfosetStreamReader.getText(); 1.274 + } 1.275 + 1.276 + charArray.set(); 1.277 + if (!WhiteSpaceProcessor.isWhiteSpace(charArray)) { 1.278 + visitor.text(charArray); 1.279 + textReported = true; 1.280 + } 1.281 + } 1.282 + } 1.283 + 1.284 + private void processBufferedText(boolean ignorable) throws SAXException { 1.285 + if (!ignorable || !WhiteSpaceProcessor.isWhiteSpace(buffer)) { 1.286 + visitor.text(buffer); 1.287 + textReported = true; 1.288 + } 1.289 + } 1.290 + 1.291 + private void processUnreportedText() throws SAXException { 1.292 + if(!textReported && predictor.expectText()) { 1.293 + visitor.text(""); 1.294 + } 1.295 + textReported = false; 1.296 + } 1.297 +}