Home » xml-commons-external-1.4.01-src » javax » xml » bind » util » [javadoc | source]

    1   /*
    2    * Copyright 2005-2006 Sun Microsystems, Inc.  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.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   package javax.xml.bind.util;
   26   
   27   import org.xml.sax.ContentHandler;
   28   import org.xml.sax.DTDHandler;
   29   import org.xml.sax.EntityResolver;
   30   import org.xml.sax.ErrorHandler;
   31   import org.xml.sax.InputSource;
   32   import org.xml.sax.SAXException;
   33   import org.xml.sax.SAXNotRecognizedException;
   34   import org.xml.sax.SAXParseException;
   35   import org.xml.sax.XMLReader;
   36   import org.xml.sax.ext.LexicalHandler;
   37   import org.xml.sax.helpers.XMLFilterImpl;
   38   
   39   import javax.xml.bind.JAXBContext;
   40   import javax.xml.bind.JAXBException;
   41   import javax.xml.bind.Marshaller;
   42   import javax.xml.transform.sax.SAXSource;
   43   
   44   /**
   45    * JAXP {@link javax.xml.transform.Source} implementation
   46    * that marshals a JAXB-generated object.
   47    *
   48    * <p>
   49    * This utility class is useful to combine JAXB with
   50    * other Java/XML technologies.
   51    *
   52    * <p>
   53    * The following example shows how to use JAXB to marshal a document
   54    * for transformation by XSLT.
   55    *
   56    * <blockquote>
   57    *    <pre>
   58    *       MyObject o = // get JAXB content tree
   59    *
   60    *       // jaxbContext is a JAXBContext object from which 'o' is created.
   61    *       JAXBSource source = new JAXBSource( jaxbContext, o );
   62    *
   63    *       // set up XSLT transformation
   64    *       TransformerFactory tf = TransformerFactory.newInstance();
   65    *       Transformer t = tf.newTransformer(new StreamSource("test.xsl"));
   66    *
   67    *       // run transformation
   68    *       t.transform(source,new StreamResult(System.out));
   69    *    </pre>
   70    * </blockquote>
   71    *
   72    * <p>
   73    * The fact that JAXBSource derives from SAXSource is an implementation
   74    * detail. Thus in general applications are strongly discouraged from
   75    * accessing methods defined on SAXSource. In particular,
   76    * the setXMLReader and setInputSource methods shall never be called.
   77    * The XMLReader object obtained by the getXMLReader method shall
   78    * be used only for parsing the InputSource object returned by
   79    * the getInputSource method.
   80    *
   81    * <p>
   82    * Similarly the InputSource object obtained by the getInputSource
   83    * method shall be used only for being parsed by the XMLReader object
   84    * returned by the getXMLReader.
   85    *
   86    * @author
   87    *      Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
   88    */
   89   public class JAXBSource extends SAXSource {
   90   
   91       /**
   92        * Creates a new {@link javax.xml.transform.Source} for the given content object.
   93        *
   94        * @param   context
   95        *      JAXBContext that was used to create
   96        *      <code>contentObject</code>. This context is used
   97        *      to create a new instance of marshaller and must not be null.
   98        * @param   contentObject
   99        *      An instance of a JAXB-generated class, which will be
  100        *      used as a {@link javax.xml.transform.Source} (by marshalling it into XML).  It must
  101        *      not be null.
  102        * @throws JAXBException if an error is encountered while creating the
  103        * JAXBSource or if either of the parameters are null.
  104        */
  105       public JAXBSource( JAXBContext context, Object contentObject )
  106           throws JAXBException {
  107   
  108           this(
  109               ( context == null ) ?
  110                   assertionFailed( Messages.format( Messages.SOURCE_NULL_CONTEXT ) ) :
  111                   context.createMarshaller(),
  112   
  113               ( contentObject == null ) ?
  114                   assertionFailed( Messages.format( Messages.SOURCE_NULL_CONTENT ) ) :
  115                   contentObject);
  116       }
  117   
  118       /**
  119        * Creates a new {@link javax.xml.transform.Source} for the given content object.
  120        *
  121        * @param   marshaller
  122        *      A marshaller instance that will be used to marshal
  123        *      <code>contentObject</code> into XML. This must be
  124        *      created from a JAXBContext that was used to build
  125        *      <code>contentObject</code> and must not be null.
  126        * @param   contentObject
  127        *      An instance of a JAXB-generated class, which will be
  128        *      used as a {@link javax.xml.transform.Source} (by marshalling it into XML).  It must
  129        *      not be null.
  130        * @throws JAXBException if an error is encountered while creating the
  131        * JAXBSource or if either of the parameters are null.
  132        */
  133       public JAXBSource( Marshaller marshaller, Object contentObject )
  134           throws JAXBException {
  135   
  136           if( marshaller == null )
  137               throw new JAXBException(
  138                   Messages.format( Messages.SOURCE_NULL_MARSHALLER ) );
  139   
  140           if( contentObject == null )
  141               throw new JAXBException(
  142                   Messages.format( Messages.SOURCE_NULL_CONTENT ) );
  143   
  144           this.marshaller = marshaller;
  145           this.contentObject = contentObject;
  146   
  147           super.setXMLReader(pseudoParser);
  148           // pass a dummy InputSource. We don't care
  149           super.setInputSource(new InputSource());
  150       }
  151   
  152       private final Marshaller marshaller;
  153       private final Object contentObject;
  154   
  155       // this object will pretend as an XMLReader.
  156       // no matter what parameter is specified to the parse method,
  157       // it just parse the contentObject.
  158       private final XMLReader pseudoParser = new XMLReader() {
  159           public boolean getFeature(String name) throws SAXNotRecognizedException {
  160               if(name.equals("http://xml.org/sax/features/namespaces"))
  161                   return true;
  162               if(name.equals("http://xml.org/sax/features/namespace-prefixes"))
  163                   return false;
  164               throw new SAXNotRecognizedException(name);
  165           }
  166   
  167           public void setFeature(String name, boolean value) throws SAXNotRecognizedException {
  168               if(name.equals("http://xml.org/sax/features/namespaces") && value)
  169                   return;
  170               if(name.equals("http://xml.org/sax/features/namespace-prefixes") && !value)
  171                   return;
  172               throw new SAXNotRecognizedException(name);
  173           }
  174   
  175           public Object getProperty(String name) throws SAXNotRecognizedException {
  176               if( "http://xml.org/sax/properties/lexical-handler".equals(name) ) {
  177                   return lexicalHandler;
  178               }
  179               throw new SAXNotRecognizedException(name);
  180           }
  181   
  182           public void setProperty(String name, Object value) throws SAXNotRecognizedException {
  183               if( "http://xml.org/sax/properties/lexical-handler".equals(name) ) {
  184                   this.lexicalHandler = (LexicalHandler)value;
  185                   return;
  186               }
  187               throw new SAXNotRecognizedException(name);
  188           }
  189   
  190           private LexicalHandler lexicalHandler;
  191   
  192           // we will store this value but never use it by ourselves.
  193           private EntityResolver entityResolver;
  194           public void setEntityResolver(EntityResolver resolver) {
  195               this.entityResolver = resolver;
  196           }
  197           public EntityResolver getEntityResolver() {
  198               return entityResolver;
  199           }
  200   
  201           private DTDHandler dtdHandler;
  202           public void setDTDHandler(DTDHandler handler) {
  203               this.dtdHandler = handler;
  204           }
  205           public DTDHandler getDTDHandler() {
  206               return dtdHandler;
  207           }
  208   
  209           // SAX allows ContentHandler to be changed during the parsing,
  210           // but JAXB doesn't. So this repeater will sit between those
  211           // two components.
  212           private XMLFilterImpl repeater = new XMLFilterImpl();
  213   
  214           public void setContentHandler(ContentHandler handler) {
  215               repeater.setContentHandler(handler);
  216           }
  217           public ContentHandler getContentHandler() {
  218               return repeater.getContentHandler();
  219           }
  220   
  221           private ErrorHandler errorHandler;
  222           public void setErrorHandler(ErrorHandler handler) {
  223               this.errorHandler = handler;
  224           }
  225           public ErrorHandler getErrorHandler() {
  226               return errorHandler;
  227           }
  228   
  229           public void parse(InputSource input) throws SAXException {
  230               parse();
  231           }
  232   
  233           public void parse(String systemId) throws SAXException {
  234               parse();
  235           }
  236   
  237           public void parse() throws SAXException {
  238               // parses a content object by using the given marshaller
  239               // SAX events will be sent to the repeater, and the repeater
  240               // will further forward it to an appropriate component.
  241               try {
  242                   marshaller.marshal( contentObject, repeater );
  243               } catch( JAXBException e ) {
  244                   // wrap it to a SAXException
  245                   SAXParseException se =
  246                       new SAXParseException( e.getMessage(),
  247                           null, null, -1, -1, e );
  248   
  249                   // if the consumer sets an error handler, it is our responsibility
  250                   // to notify it.
  251                   if(errorHandler!=null)
  252                       errorHandler.fatalError(se);
  253   
  254                   // this is a fatal error. Even if the error handler
  255                   // returns, we will abort anyway.
  256                   throw se;
  257               }
  258           }
  259       };
  260   
  261       /**
  262        * Hook to throw exception from the middle of a contructor chained call
  263        * to this
  264        */
  265       private static Marshaller assertionFailed( String message )
  266           throws JAXBException {
  267   
  268           throw new JAXBException( message );
  269       }
  270   }

Home » xml-commons-external-1.4.01-src » javax » xml » bind » util » [javadoc | source]