src/share/jaxws_classes/com/sun/istack/internal/XMLStreamReaderToContentHandler.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 368
0989ad8c0860
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.istack.internal;
aoqi@0 27
aoqi@0 28 import org.xml.sax.ContentHandler;
aoqi@0 29 import org.xml.sax.SAXException;
aoqi@0 30 import org.xml.sax.Locator;
aoqi@0 31 import org.xml.sax.Attributes;
aoqi@0 32 import org.xml.sax.helpers.AttributesImpl;
aoqi@0 33
aoqi@0 34 import javax.xml.stream.XMLStreamReader;
aoqi@0 35 import javax.xml.stream.XMLStreamException;
aoqi@0 36 import javax.xml.stream.XMLStreamConstants;
aoqi@0 37 import javax.xml.namespace.QName;
aoqi@0 38
aoqi@0 39 /**
aoqi@0 40 * This is a simple utility class that adapts StAX events from an
aoqi@0 41 * {@link XMLStreamReader} to SAX events on a
aoqi@0 42 * {@link ContentHandler}, bridging between the two
aoqi@0 43 * parser technologies.
aoqi@0 44 *
aoqi@0 45 * @author Ryan.Shoemaker@Sun.COM
aoqi@0 46 * @version 1.0
aoqi@0 47 */
aoqi@0 48 public class XMLStreamReaderToContentHandler {
aoqi@0 49
aoqi@0 50 // StAX event source
aoqi@0 51 private final XMLStreamReader staxStreamReader;
aoqi@0 52
aoqi@0 53 // SAX event sink
aoqi@0 54 private final ContentHandler saxHandler;
aoqi@0 55
aoqi@0 56 // if true, when the conversion is completed, leave the cursor to the last
aoqi@0 57 // event that was fired (such as end element)
aoqi@0 58 private final boolean eagerQuit;
aoqi@0 59
aoqi@0 60 /**
aoqi@0 61 * If true, not start/endDocument event.
aoqi@0 62 */
aoqi@0 63 private final boolean fragment;
aoqi@0 64
aoqi@0 65 // array of the even length of the form { prefix0, uri0, prefix1, uri1, ... }
aoqi@0 66 private final String[] inscopeNamespaces;
aoqi@0 67
aoqi@0 68 /**
aoqi@0 69 * @see #XMLStreamReaderToContentHandler(XMLStreamReader, ContentHandler, boolean, boolean, String[])
aoqi@0 70 */
aoqi@0 71 public XMLStreamReaderToContentHandler(XMLStreamReader staxCore, ContentHandler saxCore, boolean eagerQuit, boolean fragment) {
aoqi@0 72 this(staxCore, saxCore, eagerQuit, fragment, new String[0]);
aoqi@0 73 }
aoqi@0 74
aoqi@0 75 /**
aoqi@0 76 * Construct a new StAX to SAX adapter that will convert a StAX event
aoqi@0 77 * stream into a SAX event stream.
aoqi@0 78 *
aoqi@0 79 * @param staxCore
aoqi@0 80 * StAX event source
aoqi@0 81 * @param saxCore
aoqi@0 82 * SAXevent sink
aoqi@0 83 * @param eagerQuit
aoqi@0 84 * @param fragment
aoqi@0 85 * @param inscopeNamespaces
aoqi@0 86 * array of the even length of the form { prefix0, uri0, prefix1, uri1, ... }
aoqi@0 87 */
aoqi@0 88 public XMLStreamReaderToContentHandler(XMLStreamReader staxCore, ContentHandler saxCore,
aoqi@0 89 boolean eagerQuit, boolean fragment, String[] inscopeNamespaces) {
aoqi@0 90 this.staxStreamReader = staxCore;
aoqi@0 91 this.saxHandler = saxCore;
aoqi@0 92 this.eagerQuit = eagerQuit;
aoqi@0 93 this.fragment = fragment;
aoqi@0 94 this.inscopeNamespaces = inscopeNamespaces;
aoqi@0 95 assert inscopeNamespaces.length%2 == 0;
aoqi@0 96 }
aoqi@0 97
aoqi@0 98
aoqi@0 99 /*
aoqi@0 100 * @see StAXReaderToContentHandler#bridge()
aoqi@0 101 */
aoqi@0 102 public void bridge() throws XMLStreamException {
aoqi@0 103
aoqi@0 104 try {
aoqi@0 105 // remembers the nest level of elements to know when we are done.
aoqi@0 106 int depth=0;
aoqi@0 107
aoqi@0 108 // if the parser is at the start tag, proceed to the first element
aoqi@0 109 int event = staxStreamReader.getEventType();
aoqi@0 110 if(event == XMLStreamConstants.START_DOCUMENT) {
aoqi@0 111 // nextTag doesn't correctly handle DTDs
aoqi@0 112 while( !staxStreamReader.isStartElement() )
aoqi@0 113 event = staxStreamReader.next();
aoqi@0 114 }
aoqi@0 115
aoqi@0 116
aoqi@0 117 if( event!=XMLStreamConstants.START_ELEMENT)
aoqi@0 118 throw new IllegalStateException("The current event is not START_ELEMENT\n but " + event);
aoqi@0 119
aoqi@0 120 handleStartDocument();
aoqi@0 121
aoqi@0 122 for(int i=0; i < inscopeNamespaces.length; i+=2) {
aoqi@0 123 saxHandler.startPrefixMapping(inscopeNamespaces[i], inscopeNamespaces[i+1]);
aoqi@0 124 }
aoqi@0 125
aoqi@0 126 OUTER:
aoqi@0 127 do {
aoqi@0 128 // These are all of the events listed in the javadoc for
aoqi@0 129 // XMLEvent.
aoqi@0 130 // The spec only really describes 11 of them.
aoqi@0 131 switch (event) {
aoqi@0 132 case XMLStreamConstants.START_ELEMENT :
aoqi@0 133 depth++;
aoqi@0 134 handleStartElement();
aoqi@0 135 break;
aoqi@0 136 case XMLStreamConstants.END_ELEMENT :
aoqi@0 137 handleEndElement();
aoqi@0 138 depth--;
aoqi@0 139 if(depth==0 && eagerQuit)
aoqi@0 140 break OUTER;
aoqi@0 141 break;
aoqi@0 142 case XMLStreamConstants.CHARACTERS :
aoqi@0 143 handleCharacters();
aoqi@0 144 break;
aoqi@0 145 case XMLStreamConstants.ENTITY_REFERENCE :
aoqi@0 146 handleEntityReference();
aoqi@0 147 break;
aoqi@0 148 case XMLStreamConstants.PROCESSING_INSTRUCTION :
aoqi@0 149 handlePI();
aoqi@0 150 break;
aoqi@0 151 case XMLStreamConstants.COMMENT :
aoqi@0 152 handleComment();
aoqi@0 153 break;
aoqi@0 154 case XMLStreamConstants.DTD :
aoqi@0 155 handleDTD();
aoqi@0 156 break;
aoqi@0 157 case XMLStreamConstants.ATTRIBUTE :
aoqi@0 158 handleAttribute();
aoqi@0 159 break;
aoqi@0 160 case XMLStreamConstants.NAMESPACE :
aoqi@0 161 handleNamespace();
aoqi@0 162 break;
aoqi@0 163 case XMLStreamConstants.CDATA :
aoqi@0 164 handleCDATA();
aoqi@0 165 break;
aoqi@0 166 case XMLStreamConstants.ENTITY_DECLARATION :
aoqi@0 167 handleEntityDecl();
aoqi@0 168 break;
aoqi@0 169 case XMLStreamConstants.NOTATION_DECLARATION :
aoqi@0 170 handleNotationDecl();
aoqi@0 171 break;
aoqi@0 172 case XMLStreamConstants.SPACE :
aoqi@0 173 handleSpace();
aoqi@0 174 break;
aoqi@0 175 default :
aoqi@0 176 throw new InternalError("processing event: " + event);
aoqi@0 177 }
aoqi@0 178
aoqi@0 179 event=staxStreamReader.next();
aoqi@0 180 } while (depth!=0);
aoqi@0 181
aoqi@0 182 for(int i=0; i < inscopeNamespaces.length; i+=2) {
aoqi@0 183 saxHandler.endPrefixMapping(inscopeNamespaces[i]);
aoqi@0 184 }
aoqi@0 185
aoqi@0 186 handleEndDocument();
aoqi@0 187 } catch (SAXException e) {
aoqi@0 188 throw new XMLStreamException2(e);
aoqi@0 189 }
aoqi@0 190 }
aoqi@0 191
aoqi@0 192 private void handleEndDocument() throws SAXException {
aoqi@0 193 if(fragment)
aoqi@0 194 return;
aoqi@0 195
aoqi@0 196 saxHandler.endDocument();
aoqi@0 197 }
aoqi@0 198
aoqi@0 199 private void handleStartDocument() throws SAXException {
aoqi@0 200 if(fragment)
aoqi@0 201 return;
aoqi@0 202
aoqi@0 203 saxHandler.setDocumentLocator(new Locator() {
aoqi@0 204 public int getColumnNumber() {
aoqi@0 205 return staxStreamReader.getLocation().getColumnNumber();
aoqi@0 206 }
aoqi@0 207 public int getLineNumber() {
aoqi@0 208 return staxStreamReader.getLocation().getLineNumber();
aoqi@0 209 }
aoqi@0 210 public String getPublicId() {
aoqi@0 211 return staxStreamReader.getLocation().getPublicId();
aoqi@0 212 }
aoqi@0 213 public String getSystemId() {
aoqi@0 214 return staxStreamReader.getLocation().getSystemId();
aoqi@0 215 }
aoqi@0 216 });
aoqi@0 217 saxHandler.startDocument();
aoqi@0 218 }
aoqi@0 219
aoqi@0 220 private void handlePI() throws XMLStreamException {
aoqi@0 221 try {
aoqi@0 222 saxHandler.processingInstruction(
aoqi@0 223 staxStreamReader.getPITarget(),
aoqi@0 224 staxStreamReader.getPIData());
aoqi@0 225 } catch (SAXException e) {
aoqi@0 226 throw new XMLStreamException2(e);
aoqi@0 227 }
aoqi@0 228 }
aoqi@0 229
aoqi@0 230 private void handleCharacters() throws XMLStreamException {
aoqi@0 231 try {
aoqi@0 232 saxHandler.characters(
aoqi@0 233 staxStreamReader.getTextCharacters(),
aoqi@0 234 staxStreamReader.getTextStart(),
aoqi@0 235 staxStreamReader.getTextLength() );
aoqi@0 236 } catch (SAXException e) {
aoqi@0 237 throw new XMLStreamException2(e);
aoqi@0 238 }
aoqi@0 239 }
aoqi@0 240
aoqi@0 241 private void handleEndElement() throws XMLStreamException {
aoqi@0 242 QName qName = staxStreamReader.getName();
aoqi@0 243
aoqi@0 244 try {
aoqi@0 245 String pfix = qName.getPrefix();
aoqi@0 246 String rawname = (pfix == null || pfix.length() == 0)
aoqi@0 247 ? qName.getLocalPart()
aoqi@0 248 : pfix + ':' + qName.getLocalPart();
aoqi@0 249 // fire endElement
aoqi@0 250 saxHandler.endElement(
aoqi@0 251 qName.getNamespaceURI(),
aoqi@0 252 qName.getLocalPart(),
aoqi@0 253 rawname);
aoqi@0 254
aoqi@0 255 // end namespace bindings
aoqi@0 256 int nsCount = staxStreamReader.getNamespaceCount();
aoqi@0 257 for (int i = nsCount - 1; i >= 0; i--) {
aoqi@0 258 String prefix = staxStreamReader.getNamespacePrefix(i);
aoqi@0 259 if (prefix == null) { // true for default namespace
aoqi@0 260 prefix = "";
aoqi@0 261 }
aoqi@0 262 saxHandler.endPrefixMapping(prefix);
aoqi@0 263 }
aoqi@0 264 } catch (SAXException e) {
aoqi@0 265 throw new XMLStreamException2(e);
aoqi@0 266 }
aoqi@0 267 }
aoqi@0 268
aoqi@0 269 private void handleStartElement() throws XMLStreamException {
aoqi@0 270
aoqi@0 271 try {
aoqi@0 272 // start namespace bindings
aoqi@0 273 int nsCount = staxStreamReader.getNamespaceCount();
aoqi@0 274 for (int i = 0; i < nsCount; i++) {
aoqi@0 275 saxHandler.startPrefixMapping(
aoqi@0 276 fixNull(staxStreamReader.getNamespacePrefix(i)),
aoqi@0 277 fixNull(staxStreamReader.getNamespaceURI(i)));
aoqi@0 278 }
aoqi@0 279
aoqi@0 280 // fire startElement
aoqi@0 281 QName qName = staxStreamReader.getName();
aoqi@0 282 String prefix = qName.getPrefix();
aoqi@0 283 String rawname;
aoqi@0 284 if(prefix==null || prefix.length()==0)
aoqi@0 285 rawname = qName.getLocalPart();
aoqi@0 286 else
aoqi@0 287 rawname = prefix + ':' + qName.getLocalPart();
aoqi@0 288 Attributes attrs = getAttributes();
aoqi@0 289 saxHandler.startElement(
aoqi@0 290 qName.getNamespaceURI(),
aoqi@0 291 qName.getLocalPart(),
aoqi@0 292 rawname,
aoqi@0 293 attrs);
aoqi@0 294 } catch (SAXException e) {
aoqi@0 295 throw new XMLStreamException2(e);
aoqi@0 296 }
aoqi@0 297 }
aoqi@0 298
aoqi@0 299 private static String fixNull(String s) {
aoqi@0 300 if(s==null) return "";
aoqi@0 301 else return s;
aoqi@0 302 }
aoqi@0 303
aoqi@0 304 /**
aoqi@0 305 * Get the attributes associated with the given START_ELEMENT or ATTRIBUTE
aoqi@0 306 * StAXevent.
aoqi@0 307 *
aoqi@0 308 * @return the StAX attributes converted to an org.xml.sax.Attributes
aoqi@0 309 */
aoqi@0 310 private Attributes getAttributes() {
aoqi@0 311 AttributesImpl attrs = new AttributesImpl();
aoqi@0 312
aoqi@0 313 int eventType = staxStreamReader.getEventType();
aoqi@0 314 if (eventType != XMLStreamConstants.ATTRIBUTE
aoqi@0 315 && eventType != XMLStreamConstants.START_ELEMENT) {
aoqi@0 316 throw new InternalError(
aoqi@0 317 "getAttributes() attempting to process: " + eventType);
aoqi@0 318 }
aoqi@0 319
aoqi@0 320 // in SAX, namespace declarations are not part of attributes by default.
aoqi@0 321 // (there's a property to control that, but as far as we are concerned
aoqi@0 322 // we don't use it.) So don't add xmlns:* to attributes.
aoqi@0 323
aoqi@0 324 // gather non-namespace attrs
aoqi@0 325 for (int i = 0; i < staxStreamReader.getAttributeCount(); i++) {
aoqi@0 326 String uri = staxStreamReader.getAttributeNamespace(i);
aoqi@0 327 if(uri==null) uri="";
aoqi@0 328 String localName = staxStreamReader.getAttributeLocalName(i);
aoqi@0 329 String prefix = staxStreamReader.getAttributePrefix(i);
aoqi@0 330 String qName;
aoqi@0 331 if(prefix==null || prefix.length()==0)
aoqi@0 332 qName = localName;
aoqi@0 333 else
aoqi@0 334 qName = prefix + ':' + localName;
aoqi@0 335 String type = staxStreamReader.getAttributeType(i);
aoqi@0 336 String value = staxStreamReader.getAttributeValue(i);
aoqi@0 337
aoqi@0 338 attrs.addAttribute(uri, localName, qName, type, value);
aoqi@0 339 }
aoqi@0 340
aoqi@0 341 return attrs;
aoqi@0 342 }
aoqi@0 343
aoqi@0 344 private void handleNamespace() {
aoqi@0 345 // no-op ???
aoqi@0 346 // namespace events don't normally occur outside of a startElement
aoqi@0 347 // or endElement
aoqi@0 348 }
aoqi@0 349
aoqi@0 350 private void handleAttribute() {
aoqi@0 351 // no-op ???
aoqi@0 352 // attribute events don't normally occur outside of a startElement
aoqi@0 353 // or endElement
aoqi@0 354 }
aoqi@0 355
aoqi@0 356 private void handleDTD() {
aoqi@0 357 // no-op ???
aoqi@0 358 // it seems like we need to pass this info along, but how?
aoqi@0 359 }
aoqi@0 360
aoqi@0 361 private void handleComment() {
aoqi@0 362 // no-op ???
aoqi@0 363 }
aoqi@0 364
aoqi@0 365 private void handleEntityReference() {
aoqi@0 366 // no-op ???
aoqi@0 367 }
aoqi@0 368
aoqi@0 369 private void handleSpace() {
aoqi@0 370 // no-op ???
aoqi@0 371 // this event is listed in the javadoc, but not in the spec.
aoqi@0 372 }
aoqi@0 373
aoqi@0 374 private void handleNotationDecl() {
aoqi@0 375 // no-op ???
aoqi@0 376 // this event is listed in the javadoc, but not in the spec.
aoqi@0 377 }
aoqi@0 378
aoqi@0 379 private void handleEntityDecl() {
aoqi@0 380 // no-op ???
aoqi@0 381 // this event is listed in the javadoc, but not in the spec.
aoqi@0 382 }
aoqi@0 383
aoqi@0 384 private void handleCDATA() {
aoqi@0 385 // no-op ???
aoqi@0 386 // this event is listed in the javadoc, but not in the spec.
aoqi@0 387 }
aoqi@0 388 }

mercurial