Home » xml-commons-external-1.4.01-src » javax » xml » bind » helpers » [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.helpers;
   26   
   27   import org.xml.sax.InputSource;
   28   import org.xml.sax.SAXException;
   29   import org.xml.sax.XMLReader;
   30   import org.w3c.dom.Node;
   31   
   32   import javax.xml.bind.JAXBException;
   33   import javax.xml.bind.PropertyException;
   34   import javax.xml.bind.UnmarshalException;
   35   import javax.xml.bind.Unmarshaller;
   36   import javax.xml.bind.ValidationEventHandler;
   37   import javax.xml.bind.JAXBElement;
   38   import javax.xml.bind.annotation.adapters.XmlAdapter;
   39   import javax.xml.bind.attachment.AttachmentUnmarshaller;
   40   import javax.xml.parsers.ParserConfigurationException;
   41   import javax.xml.parsers.SAXParserFactory;
   42   import javax.xml.stream.XMLEventReader;
   43   import javax.xml.stream.XMLStreamReader;
   44   import javax.xml.transform.Source;
   45   import javax.xml.transform.dom.DOMSource;
   46   import javax.xml.transform.sax.SAXSource;
   47   import javax.xml.transform.stream.StreamSource;
   48   import javax.xml.validation.Schema;
   49   import java.io.File;
   50   import java.io.Reader;
   51   import java.net.MalformedURLException;
   52   import java.net.URL;
   53   
   54   /**
   55    * Partial default <tt>Unmarshaller</tt> implementation.
   56    *
   57    * <p>
   58    * This class provides a partial default implementation for the
   59    * {@link javax.xml.bind.Unmarshaller}interface.
   60    *
   61    * <p>
   62    * A JAXB Provider has to implement five methods (getUnmarshallerHandler,
   63    * unmarshal(Node), unmarshal(XMLReader,InputSource),
   64    * unmarshal(XMLStreamReader), and unmarshal(XMLEventReader).
   65    *
   66    * @author <ul>
   67    *         <li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li>
   68    *         </ul>
   69    * @version $Revision: 1.14 $ $Date: 2006/03/08 17:01:00 $
   70    * @see javax.xml.bind.Unmarshaller
   71    * @since JAXB1.0
   72    */
   73   public abstract class AbstractUnmarshallerImpl implements Unmarshaller
   74   {
   75       /** handler that will be used to process errors and warnings during unmarshal */
   76       private ValidationEventHandler eventHandler =
   77           new DefaultValidationEventHandler();
   78   
   79       /** whether or not the unmarshaller will validate */
   80       protected boolean validating = false;
   81   
   82       /**
   83        * XMLReader that will be used to parse a document.
   84        */
   85       private XMLReader reader = null;
   86   
   87       /**
   88        * Obtains a configured XMLReader.
   89        *
   90        * This method is used when the client-specified
   91        * {@link SAXSource} object doesn't have XMLReader.
   92        *
   93        * {@link Unmarshaller} is not re-entrant, so we will
   94        * only use one instance of XMLReader.
   95        */
   96       protected XMLReader getXMLReader() throws JAXBException {
   97           if(reader==null) {
   98               try {
   99                   SAXParserFactory parserFactory;
  100                   parserFactory = SAXParserFactory.newInstance();
  101                   parserFactory.setNamespaceAware(true);
  102                   // there is no point in asking a validation because
  103                   // there is no guarantee that the document will come with
  104                   // a proper schemaLocation.
  105                   parserFactory.setValidating(false);
  106                   reader = parserFactory.newSAXParser().getXMLReader();
  107               } catch( ParserConfigurationException e ) {
  108                   throw new JAXBException(e);
  109               } catch( SAXException e ) {
  110                   throw new JAXBException(e);
  111               }
  112           }
  113           return reader;
  114       }
  115   
  116       public Object unmarshal( Source source ) throws JAXBException {
  117           if( source == null ) {
  118               throw new IllegalArgumentException(
  119                   Messages.format( Messages.MUST_NOT_BE_NULL, "source" ) );
  120           }
  121   
  122           if(source instanceof SAXSource)
  123               return unmarshal( (SAXSource)source );
  124           if(source instanceof StreamSource)
  125               return unmarshal( streamSourceToInputSource((StreamSource)source));
  126           if(source instanceof DOMSource)
  127               return unmarshal( ((DOMSource)source).getNode() );
  128   
  129           // we don't handle other types of Source
  130           throw new IllegalArgumentException();
  131       }
  132   
  133       // use the client specified XMLReader contained in the SAXSource.
  134       private Object unmarshal( SAXSource source ) throws JAXBException {
  135   
  136           XMLReader reader = source.getXMLReader();
  137           if( reader == null )
  138               reader = getXMLReader();
  139   
  140           return unmarshal( reader, source.getInputSource() );
  141       }
  142   
  143       /**
  144        * Unmarshals an object by using the specified XMLReader and the InputSource.
  145        *
  146        * The callee should call the setErrorHandler method of the XMLReader
  147        * so that errors are passed to the client-specified ValidationEventHandler.
  148        */
  149       protected abstract Object unmarshal( XMLReader reader, InputSource source ) throws JAXBException;
  150   
  151       public final Object unmarshal( InputSource source ) throws JAXBException {
  152           if( source == null ) {
  153               throw new IllegalArgumentException(
  154                   Messages.format( Messages.MUST_NOT_BE_NULL, "source" ) );
  155           }
  156   
  157           return unmarshal( getXMLReader(), source );
  158       }
  159   
  160   
  161       private Object unmarshal( String url ) throws JAXBException {
  162           return unmarshal( new InputSource(url) );
  163       }
  164   
  165       public final Object unmarshal( URL url ) throws JAXBException {
  166           if( url == null ) {
  167               throw new IllegalArgumentException(
  168                   Messages.format( Messages.MUST_NOT_BE_NULL, "url" ) );
  169           }
  170   
  171           return unmarshal( url.toExternalForm() );
  172       }
  173   
  174       public final Object unmarshal( File f ) throws JAXBException {
  175           if( f == null ) {
  176               throw new IllegalArgumentException(
  177                   Messages.format( Messages.MUST_NOT_BE_NULL, "file" ) );
  178           }
  179   
  180           try {
  181               // copied from JAXP
  182               String path = f.getAbsolutePath();
  183               if (File.separatorChar != '/')
  184                   path = path.replace(File.separatorChar, '/');
  185               if (!path.startsWith("/"))
  186                   path = "/" + path;
  187               if (!path.endsWith("/") && f.isDirectory())
  188                   path = path + "/";
  189               return unmarshal(new URL("file", "", path));
  190           } catch( MalformedURLException e ) {
  191               throw new IllegalArgumentException(e.getMessage());
  192           }
  193       }
  194   
  195       public final Object unmarshal( java.io.InputStream is )
  196           throws JAXBException {
  197   
  198           if( is == null ) {
  199               throw new IllegalArgumentException(
  200                   Messages.format( Messages.MUST_NOT_BE_NULL, "is" ) );
  201           }
  202   
  203           InputSource isrc = new InputSource( is );
  204           return unmarshal( isrc );
  205       }
  206   
  207       public final Object unmarshal( Reader reader ) throws JAXBException {
  208           if( reader == null ) {
  209               throw new IllegalArgumentException(
  210                   Messages.format( Messages.MUST_NOT_BE_NULL, "reader" ) );
  211           }
  212   
  213           InputSource isrc = new InputSource( reader );
  214           return unmarshal( isrc );
  215       }
  216   
  217   
  218       private static InputSource streamSourceToInputSource( StreamSource ss ) {
  219           InputSource is = new InputSource();
  220           is.setSystemId( ss.getSystemId() );
  221           is.setByteStream( ss.getInputStream() );
  222           is.setCharacterStream( ss.getReader() );
  223   
  224           return is;
  225       }
  226   
  227   
  228       /**
  229        * Indicates whether or not the Unmarshaller is configured to validate
  230        * during unmarshal operations.
  231        * <p>
  232        * <i><b>Note:</b> I named this method isValidating() to stay in-line
  233        * with JAXP, as opposed to naming it getValidating(). </i>
  234        *
  235        * @return true if the Unmarshaller is configured to validate during
  236        *        unmarshal operations, false otherwise
  237        * @throws JAXBException if an error occurs while retrieving the validating
  238        *        flag
  239        */
  240       public boolean isValidating() throws JAXBException {
  241           return validating;
  242       }
  243   
  244       /**
  245        * Allow an application to register a validation event handler.
  246        * <p>
  247        * The validation event handler will be called by the JAXB Provider if any
  248        * validation errors are encountered during calls to any of the
  249        * <tt>unmarshal</tt> methods.  If the client application does not register
  250        * a validation event handler before invoking the unmarshal methods, then
  251        * all validation events will be silently ignored and may result in
  252        * unexpected behaviour.
  253        *
  254        * @param handler the validation event handler
  255        * @throws JAXBException if an error was encountered while setting the
  256        *        event handler
  257        */
  258       public void setEventHandler(ValidationEventHandler handler)
  259           throws JAXBException {
  260   
  261           if( handler == null ) {
  262               eventHandler = new DefaultValidationEventHandler();
  263           } else {
  264               eventHandler = handler;
  265           }
  266       }
  267   
  268       /**
  269        * Specifies whether or not the Unmarshaller should validate during
  270        * unmarshal operations.  By default, the <tt>Unmarshaller</tt> does
  271        * not validate.
  272        * <p>
  273        * This method may only be invoked before or after calling one of the
  274        * unmarshal methods.
  275        *
  276        * @param validating true if the Unmarshaller should validate during
  277        *       unmarshal, false otherwise
  278        * @throws JAXBException if an error occurred while enabling or disabling
  279        * validation at unmarshal time
  280        */
  281       public void setValidating(boolean validating) throws JAXBException {
  282           this.validating = validating;
  283       }
  284   
  285       /**
  286        * Return the current event handler or the default event handler if one
  287        * hasn't been set.
  288        *
  289        * @return the current ValidationEventHandler or the default event handler
  290        *        if it hasn't been set
  291        * @throws JAXBException if an error was encountered while getting the
  292        *        current event handler
  293        */
  294       public ValidationEventHandler getEventHandler() throws JAXBException {
  295           return eventHandler;
  296       }
  297   
  298   
  299       /**
  300        * Creates an UnmarshalException from a SAXException.
  301        *
  302        * This is an utility method provided for the derived classes.
  303        *
  304        * <p>
  305        * When a provider-implemented ContentHandler wants to throw a
  306        * JAXBException, it needs to wrap the exception by a SAXException.
  307        * If the unmarshaller implementation blindly wrap SAXException
  308        * by JAXBException, such an exception will be a JAXBException
  309        * wrapped by a SAXException wrapped by another JAXBException.
  310        * This is silly.
  311        *
  312        * <p>
  313        * This method checks the nested exception of SAXException
  314        * and reduce those excessive wrapping.
  315        *
  316        * @return the resulting UnmarshalException
  317        */
  318       protected UnmarshalException createUnmarshalException( SAXException e ) {
  319           // check the nested exception to see if it's an UnmarshalException
  320           Exception nested = e.getException();
  321           if(nested instanceof UnmarshalException)
  322               return (UnmarshalException)nested;
  323   
  324           if(nested instanceof RuntimeException)
  325               // typically this is an unexpected exception,
  326               // just throw it rather than wrap it, so that the full stack
  327               // trace can be displayed.
  328               throw (RuntimeException)nested;
  329   
  330   
  331           // otherwise simply wrap it
  332           if(nested!=null)
  333               return new UnmarshalException(nested);
  334           else
  335               return new UnmarshalException(e);
  336       }
  337   
  338       /**
  339        * Default implementation of the setProperty method always
  340        * throws PropertyException since there are no required
  341        * properties. If a provider needs to handle additional
  342        * properties, it should override this method in a derived class.
  343        */
  344       public void setProperty( String name, Object value )
  345           throws PropertyException {
  346   
  347           if( name == null ) {
  348               throw new IllegalArgumentException(
  349                   Messages.format( Messages.MUST_NOT_BE_NULL, "name" ) );
  350           }
  351   
  352           throw new PropertyException(name, value);
  353       }
  354   
  355       /**
  356        * Default implementation of the getProperty method always
  357        * throws PropertyException since there are no required
  358        * properties. If a provider needs to handle additional
  359        * properties, it should override this method in a derived class.
  360        */
  361       public Object getProperty( String name )
  362           throws PropertyException {
  363   
  364           if( name == null ) {
  365               throw new IllegalArgumentException(
  366                   Messages.format( Messages.MUST_NOT_BE_NULL, "name" ) );
  367           }
  368   
  369           throw new PropertyException(name);
  370       }
  371   
  372       public Object unmarshal(XMLEventReader reader) throws JAXBException {
  373   
  374           throw new UnsupportedOperationException();
  375       }
  376   
  377       public Object unmarshal(XMLStreamReader reader) throws JAXBException {
  378   
  379           throw new UnsupportedOperationException();
  380       }
  381   
  382       public <T> JAXBElement<T> unmarshal(Node node, Class<T> expectedType) throws JAXBException {
  383           throw new UnsupportedOperationException();
  384       }
  385   
  386       public <T> JAXBElement<T> unmarshal(Source source, Class<T> expectedType) throws JAXBException {
  387           throw new UnsupportedOperationException();
  388       }
  389   
  390       public <T> JAXBElement<T> unmarshal(XMLStreamReader reader, Class<T> expectedType) throws JAXBException {
  391           throw new UnsupportedOperationException();
  392       }
  393   
  394       public <T> JAXBElement<T> unmarshal(XMLEventReader reader, Class<T> expectedType) throws JAXBException {
  395           throw new UnsupportedOperationException();
  396       }
  397   
  398       public void setSchema(Schema schema) {
  399           throw new UnsupportedOperationException();
  400       }
  401   
  402       public Schema getSchema() {
  403           throw new UnsupportedOperationException();
  404       }
  405   
  406       public void setAdapter(XmlAdapter adapter) {
  407           if(adapter==null)
  408               throw new IllegalArgumentException();
  409           setAdapter((Class)adapter.getClass(),adapter);
  410       }
  411   
  412       public <A extends XmlAdapter> void setAdapter(Class<A> type, A adapter) {
  413           throw new UnsupportedOperationException();
  414       }
  415   
  416       public <A extends XmlAdapter> A getAdapter(Class<A> type) {
  417           throw new UnsupportedOperationException();
  418       }
  419   
  420       public void setAttachmentUnmarshaller(AttachmentUnmarshaller au) {
  421           throw new UnsupportedOperationException();
  422       }
  423   
  424       public AttachmentUnmarshaller getAttachmentUnmarshaller() {
  425           throw new UnsupportedOperationException();
  426       }
  427   
  428       public void setListener(Listener listener) {
  429           throw new UnsupportedOperationException();
  430       }
  431   
  432       public Listener getListener() {
  433           throw new UnsupportedOperationException();
  434       }
  435   }

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