com.sun.xml.ws.util.xml.StAXSource Maven / Gradle / Ivy
/*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the license at
* https://glassfish.dev.java.net/public/CDDLv1.0.html.
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at https://glassfish.dev.java.net/public/CDDLv1.0.html.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* you own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Copyright 2006 Sun Microsystems Inc. All Rights Reserved
*/
package com.sun.xml.ws.util.xml;
import com.sun.istack.XMLStreamReaderToContentHandler;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
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 {@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
* expext a {@link javax.xml.transform.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);
// createa StreamResult
Result streamResult = new StreamResult(System.out);
// run the transform
TransformerFactory.newInstance().newTransformer().transform(staxSource, streamResult);
*
*
* @author [email protected]
* @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;
// SAX allows ContentHandler to be changed during the parsing,
// but JAXB doesn't. So this repeater will sit between those
// two components.
private 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() {
public boolean getFeature(String name) throws SAXNotRecognizedException {
throw new SAXNotRecognizedException(name);
}
public void setFeature(String name, boolean value) throws SAXNotRecognizedException {
throw new SAXNotRecognizedException(name);
}
public Object getProperty(String name) throws SAXNotRecognizedException {
if( "http://xml.org/sax/properties/lexical-handler".equals(name) ) {
return lexicalHandler;
}
throw new SAXNotRecognizedException(name);
}
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;
public void setEntityResolver(EntityResolver resolver) {
this.entityResolver = resolver;
}
public EntityResolver getEntityResolver() {
return entityResolver;
}
private DTDHandler dtdHandler;
public void setDTDHandler(DTDHandler handler) {
this.dtdHandler = handler;
}
public DTDHandler getDTDHandler() {
return dtdHandler;
}
public void setContentHandler(ContentHandler handler) {
repeater.setContentHandler(handler);
}
public ContentHandler getContentHandler() {
return repeater.getContentHandler();
}
private ErrorHandler errorHandler;
public void setErrorHandler(ErrorHandler handler) {
this.errorHandler = handler;
}
public ErrorHandler getErrorHandler() {
return errorHandler;
}
public void parse(InputSource input) throws SAXException {
parse();
}
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 SAXParseException(
e.getMessage(),
null,
null,
e.getLocation().getLineNumber(),
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;
}
}
};
/**
* 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
* @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) {
if( reader == null )
throw new IllegalArgumentException();
int eventType = reader.getEventType();
if (!(eventType == XMLStreamConstants.START_DOCUMENT)
&& !(eventType == XMLStreamConstants.START_ELEMENT)) {
throw new IllegalStateException();
}
this.reader = new XMLStreamReaderToContentHandler(reader,repeater,eagerQuit,false);
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());
// }
}