325N/A/*
325N/A * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
325N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
325N/A *
325N/A * This code is free software; you can redistribute it and/or modify it
325N/A * under the terms of the GNU General Public License version 2 only, as
325N/A * published by the Free Software Foundation. Oracle designates this
325N/A * particular file as subject to the "Classpath" exception as provided
325N/A * by Oracle in the LICENSE file that accompanied this code.
325N/A *
325N/A * This code is distributed in the hope that it will be useful, but WITHOUT
325N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
325N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
325N/A * version 2 for more details (a copy is included in the LICENSE file that
325N/A * accompanied this code).
325N/A *
325N/A * You should have received a copy of the GNU General Public License version
325N/A * 2 along with this work; if not, write to the Free Software Foundation,
325N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
325N/A *
325N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
325N/A * or visit www.oracle.com if you need additional information or have any
325N/A * questions.
325N/A */
325N/A
325N/Apackage javax.xml.bind.util;
325N/A
325N/Aimport org.xml.sax.ContentHandler;
325N/Aimport org.xml.sax.DTDHandler;
325N/Aimport org.xml.sax.EntityResolver;
325N/Aimport org.xml.sax.ErrorHandler;
325N/Aimport org.xml.sax.InputSource;
325N/Aimport org.xml.sax.SAXException;
325N/Aimport org.xml.sax.SAXNotRecognizedException;
325N/Aimport org.xml.sax.SAXParseException;
325N/Aimport org.xml.sax.XMLReader;
325N/Aimport org.xml.sax.ext.LexicalHandler;
325N/Aimport org.xml.sax.helpers.XMLFilterImpl;
325N/A
325N/Aimport javax.xml.bind.JAXBContext;
325N/Aimport javax.xml.bind.JAXBException;
325N/Aimport javax.xml.bind.Marshaller;
325N/Aimport javax.xml.transform.sax.SAXSource;
325N/A
325N/A/**
325N/A * JAXP {@link javax.xml.transform.Source} implementation
325N/A * that marshals a JAXB-generated object.
325N/A *
325N/A * <p>
325N/A * This utility class is useful to combine JAXB with
325N/A * other Java/XML technologies.
325N/A *
325N/A * <p>
325N/A * The following example shows how to use JAXB to marshal a document
325N/A * for transformation by XSLT.
325N/A *
325N/A * <blockquote>
325N/A * <pre>
325N/A * MyObject o = // get JAXB content tree
325N/A *
325N/A * // jaxbContext is a JAXBContext object from which 'o' is created.
325N/A * JAXBSource source = new JAXBSource( jaxbContext, o );
325N/A *
325N/A * // set up XSLT transformation
325N/A * TransformerFactory tf = TransformerFactory.newInstance();
325N/A * Transformer t = tf.newTransformer(new StreamSource("test.xsl"));
325N/A *
325N/A * // run transformation
325N/A * t.transform(source,new StreamResult(System.out));
325N/A * </pre>
325N/A * </blockquote>
325N/A *
325N/A * <p>
325N/A * The fact that JAXBSource derives from SAXSource is an implementation
325N/A * detail. Thus in general applications are strongly discouraged from
325N/A * accessing methods defined on SAXSource. In particular,
325N/A * the setXMLReader and setInputSource methods shall never be called.
325N/A * The XMLReader object obtained by the getXMLReader method shall
325N/A * be used only for parsing the InputSource object returned by
325N/A * the getInputSource method.
325N/A *
325N/A * <p>
325N/A * Similarly the InputSource object obtained by the getInputSource
325N/A * method shall be used only for being parsed by the XMLReader object
325N/A * returned by the getXMLReader.
325N/A *
325N/A * @author
325N/A * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
325N/A */
325N/Apublic class JAXBSource extends SAXSource {
325N/A
325N/A /**
325N/A * Creates a new {@link javax.xml.transform.Source} for the given content object.
325N/A *
325N/A * @param context
325N/A * JAXBContext that was used to create
325N/A * <code>contentObject</code>. This context is used
325N/A * to create a new instance of marshaller and must not be null.
325N/A * @param contentObject
325N/A * An instance of a JAXB-generated class, which will be
325N/A * used as a {@link javax.xml.transform.Source} (by marshalling it into XML). It must
325N/A * not be null.
325N/A * @throws JAXBException if an error is encountered while creating the
325N/A * JAXBSource or if either of the parameters are null.
325N/A */
325N/A public JAXBSource( JAXBContext context, Object contentObject )
325N/A throws JAXBException {
325N/A
325N/A this(
325N/A ( context == null ) ?
325N/A assertionFailed( Messages.format( Messages.SOURCE_NULL_CONTEXT ) ) :
325N/A context.createMarshaller(),
325N/A
325N/A ( contentObject == null ) ?
325N/A assertionFailed( Messages.format( Messages.SOURCE_NULL_CONTENT ) ) :
325N/A contentObject);
325N/A }
325N/A
325N/A /**
325N/A * Creates a new {@link javax.xml.transform.Source} for the given content object.
325N/A *
325N/A * @param marshaller
325N/A * A marshaller instance that will be used to marshal
325N/A * <code>contentObject</code> into XML. This must be
325N/A * created from a JAXBContext that was used to build
325N/A * <code>contentObject</code> and must not be null.
325N/A * @param contentObject
325N/A * An instance of a JAXB-generated class, which will be
325N/A * used as a {@link javax.xml.transform.Source} (by marshalling it into XML). It must
325N/A * not be null.
325N/A * @throws JAXBException if an error is encountered while creating the
325N/A * JAXBSource or if either of the parameters are null.
325N/A */
325N/A public JAXBSource( Marshaller marshaller, Object contentObject )
325N/A throws JAXBException {
325N/A
325N/A if( marshaller == null )
325N/A throw new JAXBException(
325N/A Messages.format( Messages.SOURCE_NULL_MARSHALLER ) );
325N/A
325N/A if( contentObject == null )
325N/A throw new JAXBException(
325N/A Messages.format( Messages.SOURCE_NULL_CONTENT ) );
325N/A
325N/A this.marshaller = marshaller;
325N/A this.contentObject = contentObject;
325N/A
325N/A super.setXMLReader(pseudoParser);
325N/A // pass a dummy InputSource. We don't care
325N/A super.setInputSource(new InputSource());
325N/A }
325N/A
325N/A private final Marshaller marshaller;
325N/A private final Object contentObject;
325N/A
325N/A // this object will pretend as an XMLReader.
325N/A // no matter what parameter is specified to the parse method,
325N/A // it just parse the contentObject.
325N/A private final XMLReader pseudoParser = new XMLReader() {
325N/A public boolean getFeature(String name) throws SAXNotRecognizedException {
325N/A if(name.equals("http://xml.org/sax/features/namespaces"))
325N/A return true;
325N/A if(name.equals("http://xml.org/sax/features/namespace-prefixes"))
325N/A return false;
325N/A throw new SAXNotRecognizedException(name);
325N/A }
325N/A
325N/A public void setFeature(String name, boolean value) throws SAXNotRecognizedException {
325N/A if(name.equals("http://xml.org/sax/features/namespaces") && value)
325N/A return;
325N/A if(name.equals("http://xml.org/sax/features/namespace-prefixes") && !value)
325N/A return;
325N/A throw new SAXNotRecognizedException(name);
325N/A }
325N/A
325N/A public Object getProperty(String name) throws SAXNotRecognizedException {
325N/A if( "http://xml.org/sax/properties/lexical-handler".equals(name) ) {
325N/A return lexicalHandler;
325N/A }
325N/A throw new SAXNotRecognizedException(name);
325N/A }
325N/A
325N/A public void setProperty(String name, Object value) throws SAXNotRecognizedException {
325N/A if( "http://xml.org/sax/properties/lexical-handler".equals(name) ) {
325N/A this.lexicalHandler = (LexicalHandler)value;
325N/A return;
325N/A }
325N/A throw new SAXNotRecognizedException(name);
325N/A }
325N/A
325N/A private LexicalHandler lexicalHandler;
325N/A
325N/A // we will store this value but never use it by ourselves.
325N/A private EntityResolver entityResolver;
325N/A public void setEntityResolver(EntityResolver resolver) {
325N/A this.entityResolver = resolver;
325N/A }
325N/A public EntityResolver getEntityResolver() {
325N/A return entityResolver;
325N/A }
325N/A
325N/A private DTDHandler dtdHandler;
325N/A public void setDTDHandler(DTDHandler handler) {
325N/A this.dtdHandler = handler;
325N/A }
325N/A public DTDHandler getDTDHandler() {
325N/A return dtdHandler;
325N/A }
325N/A
325N/A // SAX allows ContentHandler to be changed during the parsing,
325N/A // but JAXB doesn't. So this repeater will sit between those
325N/A // two components.
325N/A private XMLFilterImpl repeater = new XMLFilterImpl();
325N/A
325N/A public void setContentHandler(ContentHandler handler) {
325N/A repeater.setContentHandler(handler);
325N/A }
325N/A public ContentHandler getContentHandler() {
325N/A return repeater.getContentHandler();
325N/A }
325N/A
325N/A private ErrorHandler errorHandler;
325N/A public void setErrorHandler(ErrorHandler handler) {
325N/A this.errorHandler = handler;
325N/A }
325N/A public ErrorHandler getErrorHandler() {
325N/A return errorHandler;
325N/A }
325N/A
325N/A public void parse(InputSource input) throws SAXException {
325N/A parse();
325N/A }
325N/A
325N/A public void parse(String systemId) throws SAXException {
325N/A parse();
325N/A }
325N/A
325N/A public void parse() throws SAXException {
325N/A // parses a content object by using the given marshaller
325N/A // SAX events will be sent to the repeater, and the repeater
325N/A // will further forward it to an appropriate component.
325N/A try {
325N/A marshaller.marshal( contentObject, repeater );
325N/A } catch( JAXBException e ) {
325N/A // wrap it to a SAXException
325N/A SAXParseException se =
325N/A new SAXParseException( e.getMessage(),
325N/A null, null, -1, -1, e );
325N/A
325N/A // if the consumer sets an error handler, it is our responsibility
325N/A // to notify it.
325N/A if(errorHandler!=null)
325N/A errorHandler.fatalError(se);
325N/A
325N/A // this is a fatal error. Even if the error handler
325N/A // returns, we will abort anyway.
325N/A throw se;
325N/A }
325N/A }
325N/A };
325N/A
325N/A /**
325N/A * Hook to throw exception from the middle of a contructor chained call
325N/A * to this
325N/A */
325N/A private static Marshaller assertionFailed( String message )
325N/A throws JAXBException {
325N/A
325N/A throw new JAXBException( message );
325N/A }
325N/A}