Sat, 07 Nov 2020 10:30:02 +0800
Added tag mips-jdk8u275-b01 for changeset fdbe50121f48
1 /*
2 * Copyright (c) 1997, 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 */
26 package com.sun.xml.internal.bind.v2.runtime.unmarshaller;
28 import javax.xml.stream.Location;
29 import javax.xml.stream.XMLStreamConstants;
30 import javax.xml.stream.XMLStreamException;
32 import com.sun.xml.internal.bind.WhiteSpaceProcessor;
33 import com.sun.xml.internal.fastinfoset.stax.StAXDocumentParser;
34 import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
35 import org.xml.sax.SAXException;
37 /**
38 * Reads from FastInfoset StAX parser and feeds into JAXB Unmarshaller.
39 * <p>
40 * This class will peek at future events to ascertain if characters need to be
41 * buffered or not.
42 *
43 * @author Paul Sandoz.
44 */
45 final class FastInfosetConnector extends StAXConnector {
47 // event source
48 private final StAXDocumentParser fastInfosetStreamReader;
50 // Flag set to true if text has been reported
51 private boolean textReported;
53 // Buffer for octets
54 private final Base64Data base64Data = new Base64Data();
56 // Buffer for characters
57 private final StringBuilder buffer = new StringBuilder();
59 public FastInfosetConnector(StAXDocumentParser fastInfosetStreamReader,
60 XmlVisitor visitor) {
61 super(visitor);
62 fastInfosetStreamReader.setStringInterning(true);
63 this.fastInfosetStreamReader = fastInfosetStreamReader;
64 }
66 public void bridge() throws XMLStreamException {
67 try {
68 // remembers the nest level of elements to know when we are done.
69 int depth=0;
71 // if the parser is at the start tag, proceed to the first element
72 int event = fastInfosetStreamReader.getEventType();
73 if(event == XMLStreamConstants.START_DOCUMENT) {
74 // nextTag doesn't correctly handle DTDs
75 while( !fastInfosetStreamReader.isStartElement() )
76 event = fastInfosetStreamReader.next();
77 }
80 if( event!=XMLStreamConstants.START_ELEMENT)
81 throw new IllegalStateException("The current event is not START_ELEMENT\n but " + event);
83 // TODO: we don't have to rely on this hack --- we can just emulate
84 // start/end prefix mappings. But for now, I'll rely on this hack.
85 handleStartDocument(fastInfosetStreamReader.getNamespaceContext());
87 OUTER:
88 while(true) {
89 // These are all of the events listed in the javadoc for
90 // XMLEvent.
91 // The spec only really describes 11 of them.
92 switch (event) {
93 case XMLStreamConstants.START_ELEMENT :
94 handleStartElement();
95 depth++;
96 break;
97 case XMLStreamConstants.END_ELEMENT :
98 depth--;
99 handleEndElement();
100 if(depth==0) break OUTER;
101 break;
102 case XMLStreamConstants.CHARACTERS :
103 case XMLStreamConstants.CDATA :
104 case XMLStreamConstants.SPACE :
105 if (predictor.expectText()) {
106 // Peek at the next event to see if there are
107 // fragmented characters
108 event = fastInfosetStreamReader.peekNext();
109 if (event == XMLStreamConstants.END_ELEMENT)
110 processNonIgnorableText();
111 else if (event == XMLStreamConstants.START_ELEMENT)
112 processIgnorableText();
113 else
114 handleFragmentedCharacters();
115 }
116 break;
117 // otherwise simply ignore
118 }
120 event=fastInfosetStreamReader.next();
121 }
123 fastInfosetStreamReader.next(); // move beyond the end tag.
125 handleEndDocument();
126 } catch (SAXException e) {
127 throw new XMLStreamException(e);
128 }
129 }
131 protected Location getCurrentLocation() {
132 return fastInfosetStreamReader.getLocation();
133 }
135 protected String getCurrentQName() {
136 return fastInfosetStreamReader.getNameString();
137 }
139 private void handleStartElement() throws SAXException {
140 processUnreportedText();
142 for (int i = 0; i < fastInfosetStreamReader.accessNamespaceCount(); i++) {
143 visitor.startPrefixMapping(fastInfosetStreamReader.getNamespacePrefix(i),
144 fastInfosetStreamReader.getNamespaceURI(i));
145 }
147 tagName.uri = fastInfosetStreamReader.accessNamespaceURI();
148 tagName.local = fastInfosetStreamReader.accessLocalName();
149 tagName.atts = fastInfosetStreamReader.getAttributesHolder();
151 visitor.startElement(tagName);
152 }
154 private void handleFragmentedCharacters() throws XMLStreamException, SAXException {
155 buffer.setLength(0);
157 // Append characters of first character event
158 buffer.append(fastInfosetStreamReader.getTextCharacters(),
159 fastInfosetStreamReader.getTextStart(),
160 fastInfosetStreamReader.getTextLength());
162 // Consume all character
163 while(true) {
164 switch(fastInfosetStreamReader.peekNext()) {
165 case XMLStreamConstants.START_ELEMENT :
166 processBufferedText(true);
167 return;
168 case XMLStreamConstants.END_ELEMENT :
169 processBufferedText(false);
170 return;
171 case XMLStreamConstants.CHARACTERS :
172 case XMLStreamConstants.CDATA :
173 case XMLStreamConstants.SPACE :
174 // Append characters of second and subsequent character events
175 fastInfosetStreamReader.next();
176 buffer.append(fastInfosetStreamReader.getTextCharacters(),
177 fastInfosetStreamReader.getTextStart(),
178 fastInfosetStreamReader.getTextLength());
179 break;
180 default:
181 fastInfosetStreamReader.next();
182 }
183 }
184 }
186 private void handleEndElement() throws SAXException {
187 processUnreportedText();
189 tagName.uri = fastInfosetStreamReader.accessNamespaceURI();
190 tagName.local = fastInfosetStreamReader.accessLocalName();
192 visitor.endElement(tagName);
194 for (int i = fastInfosetStreamReader.accessNamespaceCount() - 1; i >= 0; i--) {
195 visitor.endPrefixMapping(fastInfosetStreamReader.getNamespacePrefix(i));
196 }
197 }
199 final private class CharSequenceImpl implements CharSequence {
200 char[] ch;
201 int start;
202 int length;
204 CharSequenceImpl() {
205 }
207 CharSequenceImpl(final char[] ch, final int start, final int length) {
208 this.ch = ch;
209 this.start = start;
210 this.length = length;
211 }
213 public void set() {
214 ch = fastInfosetStreamReader.getTextCharacters();
215 start = fastInfosetStreamReader.getTextStart();
216 length = fastInfosetStreamReader.getTextLength();
217 }
219 // CharSequence interface
221 public final int length() {
222 return length;
223 }
225 public final char charAt(final int index) {
226 return ch[start + index];
227 }
229 public final CharSequence subSequence(final int start, final int end) {
230 return new CharSequenceImpl(ch, this.start + start, end - start);
231 }
233 public String toString() {
234 return new String(ch, start, length);
235 }
236 }
238 final private CharSequenceImpl charArray = new CharSequenceImpl();
240 private void processNonIgnorableText() throws SAXException {
241 textReported = true;
242 boolean isTextAlgorithmAplied =
243 (fastInfosetStreamReader.getTextAlgorithmBytes() != null);
245 if (isTextAlgorithmAplied &&
246 fastInfosetStreamReader.getTextAlgorithmIndex() == EncodingAlgorithmIndexes.BASE64) {
247 base64Data.set(fastInfosetStreamReader.getTextAlgorithmBytesClone(),null);
248 visitor.text(base64Data);
249 } else {
250 if (isTextAlgorithmAplied) {
251 fastInfosetStreamReader.getText();
252 }
254 charArray.set();
255 visitor.text(charArray);
256 }
257 }
259 private void processIgnorableText() throws SAXException {
260 boolean isTextAlgorithmAplied =
261 (fastInfosetStreamReader.getTextAlgorithmBytes() != null);
263 if (isTextAlgorithmAplied &&
264 fastInfosetStreamReader.getTextAlgorithmIndex() == EncodingAlgorithmIndexes.BASE64) {
265 base64Data.set(fastInfosetStreamReader.getTextAlgorithmBytesClone(),null);
266 visitor.text(base64Data);
267 textReported = true;
268 } else {
269 if (isTextAlgorithmAplied) {
270 fastInfosetStreamReader.getText();
271 }
273 charArray.set();
274 if (!WhiteSpaceProcessor.isWhiteSpace(charArray)) {
275 visitor.text(charArray);
276 textReported = true;
277 }
278 }
279 }
281 private void processBufferedText(boolean ignorable) throws SAXException {
282 if (!ignorable || !WhiteSpaceProcessor.isWhiteSpace(buffer)) {
283 visitor.text(buffer);
284 textReported = true;
285 }
286 }
288 private void processUnreportedText() throws SAXException {
289 if(!textReported && predictor.expectText()) {
290 visitor.text("");
291 }
292 textReported = false;
293 }
294 }