/*
 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.xml.internal.ws.util.xml;

import com.sun.istack.internal.NotNull;
import com.sun.istack.internal.SAXParseException2;
import com.sun.istack.internal.XMLStreamReaderToContentHandler;
import org.xml.sax.*;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.XMLFilterImpl;

import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.sax.SAXSource;

A JAXP Source implementation that wraps the specified XMLStreamReader or XMLEventReader for use by applications that expect a Source.

The fact that StAXSource derives from SAXSource is an implementation detail. Thus in general applications are strongly discouraged from accessing methods defined on SAXSource. In particular:

  • The setXMLReader and setInputSource methods shall never be called.
  • The XMLReader object obtained by the getXMLReader method shall be used only for parsing the InputSource object returned by the getInputSource method.
  • The InputSource object obtained by the getInputSource method shall be used only for being parsed by the XMLReader object returned by the getXMLReader method.

Example:

// create a StAXSource
XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(new FileReader(args[0]));
Source staxSource = new StAXSource(reader);
// create a StreamResult
Result streamResult = new StreamResult(System.out);
// run the transform
TransformerFactory.newInstance().newTransformer().transform(staxSource, streamResult);
Author:Ryan.Shoemaker@Sun.COM
Version:1.0
/** * A JAXP {@link javax.xml.transform.Source} implementation that wraps * the specified {@link javax.xml.stream.XMLStreamReader} or * {@link javax.xml.stream.XMLEventReader} for use by applications that * expect a {@link javax.xml.transform.Source}. * * <p> * The fact that StAXSource derives from SAXSource is an implementation * detail. Thus in general applications are strongly discouraged from * accessing methods defined on SAXSource. In particular: * * <ul> * <li> The setXMLReader and setInputSource methods shall never be called.</li> * <li> The XMLReader object obtained by the getXMLReader method shall * be used only for parsing the InputSource object returned by * the getInputSource method.</li> * <li> The InputSource object obtained by the getInputSource method shall * be used only for being parsed by the XMLReader object returned by * the getXMLReader method.</li> * </ul> * * <p> * Example: * * <pre> // create a StAXSource XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(new FileReader(args[0])); Source staxSource = new StAXSource(reader); // create a StreamResult Result streamResult = new StreamResult(System.out); // run the transform TransformerFactory.newInstance().newTransformer().transform(staxSource, streamResult); * </pre> * * @author Ryan.Shoemaker@Sun.COM * @version 1.0 */
public class StAXSource extends SAXSource { // StAX to SAX converter that will read from StAX and produce SAX // this object will be wrapped by the XMLReader exposed to the client private final XMLStreamReaderToContentHandler reader; private final XMLStreamReader staxReader; // SAX allows ContentHandler to be changed during the parsing, // but JAXB doesn't. So this repeater will sit between those // two components. private final XMLFilterImpl repeater = new XMLFilterImpl(); // this object will pretend as an XMLReader. // no matter what parameter is specified to the parse method, // it will just read from the StAX reader. private final XMLReader pseudoParser = new XMLReader() { @Override public boolean getFeature(String name) throws SAXNotRecognizedException { throw new SAXNotRecognizedException(name); } @Override public void setFeature(String name, boolean value) throws SAXNotRecognizedException { // Should support these two features according to XMLReader javadoc. if (name.equals("http://xml.org/sax/features/namespaces") && value) { // Ignore for now } else if (name.equals("http://xml.org/sax/features/namespace-prefixes") && !value) { // Ignore for now } else { throw new SAXNotRecognizedException(name); } } @Override public Object getProperty(String name) throws SAXNotRecognizedException { if( "http://xml.org/sax/properties/lexical-handler".equals(name) ) { return lexicalHandler; } throw new SAXNotRecognizedException(name); } @Override public void setProperty(String name, Object value) throws SAXNotRecognizedException { if( "http://xml.org/sax/properties/lexical-handler".equals(name) ) { this.lexicalHandler = (LexicalHandler)value; return; } throw new SAXNotRecognizedException(name); } private LexicalHandler lexicalHandler; // we will store this value but never use it by ourselves. private EntityResolver entityResolver; @Override public void setEntityResolver(EntityResolver resolver) { this.entityResolver = resolver; } @Override public EntityResolver getEntityResolver() { return entityResolver; } private DTDHandler dtdHandler; @Override public void setDTDHandler(DTDHandler handler) { this.dtdHandler = handler; } @Override public DTDHandler getDTDHandler() { return dtdHandler; } @Override public void setContentHandler(ContentHandler handler) { repeater.setContentHandler(handler); } @Override public ContentHandler getContentHandler() { return repeater.getContentHandler(); } private ErrorHandler errorHandler; @Override public void setErrorHandler(ErrorHandler handler) { this.errorHandler = handler; } @Override public ErrorHandler getErrorHandler() { return errorHandler; } @Override public void parse(InputSource input) throws SAXException { parse(); } @Override public void parse(String systemId) throws SAXException { parse(); } public void parse() throws SAXException { // parses from a StAX reader and generates SAX events which // go through the repeater and are forwarded to the appropriate // component try { reader.bridge(); } catch( XMLStreamException e ) { // wrap it in a SAXException SAXParseException se = new SAXParseException2( e.getMessage(), null, null, e.getLocation() == null ? -1 : e.getLocation().getLineNumber(), e.getLocation() == null ? -1 : e.getLocation().getColumnNumber(), e); // if the consumer sets an error handler, it is our responsibility // to notify it. if(errorHandler!=null) errorHandler.fatalError(se); // this is a fatal error. Even if the error handler // returns, we will abort anyway. throw se; } finally { try { staxReader.close(); } catch(XMLStreamException xe) { //falls through. Not much can be done. } } } };
Creates a new Source for the given XMLStreamReader.
Params:
  • reader – XMLStreamReader that will be exposed as a Source
  • eagerQuit – if true, when the conversion is completed, leave the cursor to the last event that was fired (such as end element)
See Also:
/** * Creates a new {@link javax.xml.transform.Source} for the given * {@link XMLStreamReader}. * * @param reader XMLStreamReader that will be exposed as a Source * @param eagerQuit if true, when the conversion is completed, leave the cursor to the last * event that was fired (such as end element) * @see #StAXSource(XMLStreamReader, boolean, String[]) */
public StAXSource(XMLStreamReader reader, boolean eagerQuit) { this(reader, eagerQuit, new String[0]); }
Creates a new Source for the given XMLStreamReader. The XMLStreamReader must be pointing at either a XMLStreamConstants.START_DOCUMENT or XMLStreamConstants.START_ELEMENT event.
Params:
  • reader – XMLStreamReader that will be exposed as a Source
  • eagerQuit – if true, when the conversion is completed, leave the cursor to the last event that was fired (such as end element)
  • inscope – inscope Namespaces array of the even length of the form { prefix0, uri0, prefix1, uri1, ... }
Throws:
/** * Creates a new {@link javax.xml.transform.Source} for the given * {@link XMLStreamReader}. * * The XMLStreamReader must be pointing at either a * {@link javax.xml.stream.XMLStreamConstants#START_DOCUMENT} or * {@link javax.xml.stream.XMLStreamConstants#START_ELEMENT} event. * * @param reader XMLStreamReader that will be exposed as a Source * @param eagerQuit if true, when the conversion is completed, leave the cursor to the last * event that was fired (such as end element) * @param inscope inscope Namespaces * array of the even length of the form { prefix0, uri0, prefix1, uri1, ... } * @throws IllegalArgumentException iff the reader is null * @throws IllegalStateException iff the reader is not pointing at either a * START_DOCUMENT or START_ELEMENT event */
public StAXSource(XMLStreamReader reader, boolean eagerQuit, @NotNull String[] inscope) { if( reader == null ) throw new IllegalArgumentException(); this.staxReader = reader; int eventType = reader.getEventType(); if (!(eventType == XMLStreamConstants.START_DOCUMENT) && !(eventType == XMLStreamConstants.START_ELEMENT)) { throw new IllegalStateException(); } this.reader = new XMLStreamReaderToContentHandler(reader,repeater,eagerQuit,false,inscope); super.setXMLReader(pseudoParser); // pass a dummy InputSource. We don't care super.setInputSource(new InputSource()); } // /** // * Creates a new {@link javax.xml.transform.Source} for the given // * {@link XMLEventReader}. // * // * The XMLEventReader must be pointing at either a // * {@link javax.xml.stream.XMLStreamConstants#START_DOCUMENT} or // * {@link javax.xml.stream.XMLStreamConstants#START_ELEMENT} event. // * // * @param reader XMLEventReader that will be exposed as a Source // * @throws IllegalArgumentException iff the reader is null // * @throws IllegalStateException iff the reader is not pointing at either a // * START_DOCUEMENT or START_ELEMENT event // */ // public StAXSource(XMLEventReader reader) { // if( reader == null ) // throw new IllegalArgumentException(); // // // TODO: detect IllegalStateException for START_ELEMENT|DOCUMENT // // bugid 5046340 - peek not implemented // // XMLEvent event = staxEventReader.peek(); // // this.reader = // new XMLEventReaderToContentHandler( // reader, // repeater); // // super.setXMLReader(pseudoParser); // // pass a dummy InputSource. We don't care // super.setInputSource(new InputSource()); // } }