1 /*
   2  * Copyright (c) 2005, 2013, Oracle and/or its affiliates. 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.xml.bind;
  27 
  28 import org.w3c.dom.Node;
  29 
  30 import javax.xml.validation.Schema;
  31 
  32 /**
  33  * Enable synchronization between XML infoset nodes and JAXB objects
  34  * representing same XML document.
  35  *
  36  * <p>
  37  * An instance of this class maintains the association between XML nodes of
  38  * an infoset preserving view and a JAXB representation of an XML document.
  39  * Navigation between the two views is provided by the methods
  40  * {@link #getXMLNode(Object)} and {@link #getJAXBNode(Object)}.
  41  *
  42  * <p>
  43  * Modifications can be made to either the infoset preserving view or the
  44  * JAXB representation of the document while the other view remains
  45  * unmodified. The binder is able to synchronize the changes made in the
  46  * modified view back into the other view using the appropriate
  47  * Binder update methods, {@link #updateXML(Object, Object)} or
  48  * {@link #updateJAXB(Object)}.
  49  *
  50  * <p>
  51  * A typical usage scenario is the following:
  52  * <ul>
  53  *   <li>load XML document into an XML infoset representation</li>
  54  *   <li>{@link #unmarshal(Object)} XML infoset view to JAXB view.
  55  *       (Note to conserve resources, it is possible to only unmarshal a
  56  *       subtree of the XML infoset view to the JAXB view.)</li>
  57  *   <li>application access/updates JAXB view of XML document.</li>
  58  *   <li>{@link #updateXML(Object)} synchronizes modifications to JAXB view
  59  *       back into the XML infoset view. Update operation preserves as
  60  *       much of original XML infoset as possible (i.e. comments, PI, ...)</li>
  61  * </ul>
  62  *
  63  * <p>
  64  * A Binder instance is created using the factory method
  65  * {@link JAXBContext#createBinder()} or {@link JAXBContext#createBinder(Class)}.
  66  *
  67  * <p>
  68  * The template parameter, <code>XmlNode</code>, is the
  69  * root interface/class for the XML infoset preserving representation.
  70  * A Binder implementation is required to minimally support
  71  * an <code>XmlNode</code> value of <code>org.w3c.dom.Node.class</code>.
  72  * A Binder implementation can support alternative XML infoset
  73  * preserving representations.
  74  *
  75  * @author
  76  *     Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
  77  *     Joseph Fialli
  78  *
  79  * @since 1.6, JAXB 2.0
  80  */
  81 public abstract class Binder<XmlNode> {
  82     /**
  83      * Unmarshal XML infoset view to a JAXB object tree.
  84      *
  85      * <p>
  86      * This method is similar to {@link Unmarshaller#unmarshal(Node)}
  87      * with the addition of maintaining the association between XML nodes
  88      * and the produced JAXB objects, enabling future update operations,
  89      * {@link #updateXML(Object, Object)} or {@link #updateJAXB(Object)}.
  90      *
  91      * <p>
  92      * When {@link #getSchema()} is non-null, <code>xmlNode</code>
  93      * and its descendants is validated during this operation.
  94      *
  95      * <p>
  96      * This method throws {@link UnmarshalException} when the Binder's
  97      * {@link JAXBContext} does not have a mapping for the XML element name
  98      * or the type, specifiable via <tt>@xsi:type</tt>, of <tt>xmlNode</tt>
  99      * to a JAXB mapped class. The method {@link #unmarshal(Object, Class)}
 100      * enables an application to specify the JAXB mapped class that
 101      * the <tt>xmlNode</tt> should be mapped to.
 102      *
 103      * @param xmlNode
 104      *      the document/element to unmarshal XML data from.
 105      *
 106      * @return
 107      *      the newly created root object of the JAXB object tree.
 108      *
 109      * @throws JAXBException
 110      *      If any unexpected errors occur while unmarshalling
 111      * @throws UnmarshalException
 112      *     If the {@link ValidationEventHandler ValidationEventHandler}
 113      *     returns false from its <tt>handleEvent</tt> method or the
 114      *     <tt>Binder</tt> is unable to perform the XML to Java
 115      *     binding.
 116      * @throws IllegalArgumentException
 117      *      If the node parameter is null
 118      */
 119     public abstract Object unmarshal( XmlNode xmlNode ) throws JAXBException;
 120 
 121     /**
 122      * Unmarshal XML root element by provided <tt>declaredType</tt>
 123      * to a JAXB object tree.
 124      *
 125      * <p>
 126      * Implements <a href="Unmarshaller.html#unmarshalByDeclaredType">Unmarshal by Declared Type</a>
 127      *
 128      * <p>
 129      * This method is similar to {@link Unmarshaller#unmarshal(Node, Class)}
 130      * with the addition of maintaining the association between XML nodes
 131      * and the produced JAXB objects, enabling future update operations,
 132      * {@link #updateXML(Object, Object)} or {@link #updateJAXB(Object)}.
 133      *
 134      * <p>
 135      * When {@link #getSchema()} is non-null, <code>xmlNode</code>
 136      * and its descendants is validated during this operation.
 137      *
 138      * @param xmlNode
 139      *      the document/element to unmarshal XML data from.
 140      * @param declaredType
 141      *      appropriate JAXB mapped class to hold <tt>node</tt>'s XML data.
 142      *
 143      * @return
 144      * <a href="JAXBElement.html">JAXB Element</a> representation
 145      * of <tt>node</tt>
 146      *
 147      * @throws JAXBException
 148      *      If any unexpected errors occur while unmarshalling
 149      * @throws UnmarshalException
 150      *     If the {@link ValidationEventHandler ValidationEventHandler}
 151      *     returns false from its <tt>handleEvent</tt> method or the
 152      *     <tt>Binder</tt> is unable to perform the XML to Java
 153      *     binding.
 154      * @throws IllegalArgumentException
 155      *      If any of the input parameters are null
 156      * @since 1.6, JAXB 2.0
 157      */
 158     public abstract <T> JAXBElement<T>
 159         unmarshal( XmlNode xmlNode, Class<T> declaredType )
 160         throws JAXBException;
 161 
 162     /**
 163      * Marshal a JAXB object tree to a new XML document.
 164      *
 165      * <p>
 166      * This method is similar to {@link Marshaller#marshal(Object, Node)}
 167      * with the addition of maintaining the association between JAXB objects
 168      * and the produced XML nodes,
 169      * enabling future update operations such as
 170      * {@link #updateXML(Object, Object)} or {@link #updateJAXB(Object)}.
 171      *
 172      * <p>
 173      * When {@link #getSchema()} is non-null, the marshalled
 174      * xml content is validated during this operation.
 175      *
 176      * @param jaxbObject
 177      *      The content tree to be marshalled.
 178      * @param xmlNode
 179      *      The parameter must be a Node that accepts children.
 180      *
 181      * @throws JAXBException
 182      *      If any unexpected problem occurs during the marshalling.
 183      * @throws MarshalException
 184      *      If the {@link ValidationEventHandler ValidationEventHandler}
 185      *      returns false from its <tt>handleEvent</tt> method or the
 186      *      <tt>Binder</tt> is unable to marshal <tt>jaxbObject</tt> (or any
 187      *      object reachable from <tt>jaxbObject</tt>).
 188      *
 189      * @throws IllegalArgumentException
 190      *      If any of the method parameters are null
 191      */
 192     public abstract void marshal( Object jaxbObject, XmlNode xmlNode ) throws JAXBException;
 193 
 194     /**
 195      * Gets the XML element associated with the given JAXB object.
 196      *
 197      * <p>
 198      * Once a JAXB object tree is associated with an XML fragment,
 199      * this method enables navigation between the two trees.
 200      *
 201      * <p>
 202      * An association between an XML element and a JAXB object is
 203      * established by the bind methods and the update methods.
 204      * Note that this association is partial; not all XML elements
 205      * have associated JAXB objects, and not all JAXB objects have
 206      * associated XML elements.
 207      *
 208      * @param jaxbObject An instance that is reachable from a prior
 209      *                   call to a bind or update method that returned
 210      *                   a JAXB object tree.
 211      *
 212      * @return
 213      *      null if the specified JAXB object is not known to this
 214      *      {@link Binder}, or if it is not associated with an
 215      *      XML element.
 216      *
 217      * @throws IllegalArgumentException
 218      *      If the jaxbObject parameter is null
 219      */
 220     public abstract XmlNode getXMLNode( Object jaxbObject );
 221 
 222     /**
 223      * Gets the JAXB object associated with the given XML element.
 224      *
 225      * <p>
 226      * Once a JAXB object tree is associated with an XML fragment,
 227      * this method enables navigation between the two trees.
 228      *
 229      * <p>
 230      * An association between an XML element and a JAXB object is
 231      * established by the unmarshal, marshal and update methods.
 232      * Note that this association is partial; not all XML elements
 233      * have associated JAXB objects, and not all JAXB objects have
 234      * associated XML elements.
 235      *
 236      * @return
 237      *      null if the specified XML node is not known to this
 238      *      {@link Binder}, or if it is not associated with a
 239      *      JAXB object.
 240      *
 241      * @throws IllegalArgumentException
 242      *      If the node parameter is null
 243      */
 244     public abstract Object getJAXBNode( XmlNode xmlNode );
 245 
 246     /**
 247      * Takes an JAXB object and updates
 248      * its associated XML node and its descendants.
 249      *
 250      * <p>
 251      * This is a convenience method of:
 252      * <pre>
 253      * updateXML( jaxbObject, getXMLNode(jaxbObject));
 254      * </pre>
 255      *
 256      * @throws JAXBException
 257      *      If any unexpected problem occurs updating corresponding XML content.
 258      * @throws IllegalArgumentException
 259      *      If the jaxbObject parameter is null
 260      */
 261     public abstract XmlNode updateXML( Object jaxbObject ) throws JAXBException;
 262 
 263     /**
 264      * Changes in JAXB object tree are updated in its associated XML parse tree.
 265      *
 266      * <p>
 267      * This operation can be thought of as an "in-place" marshalling.
 268      * The difference is that instead of creating a whole new XML tree,
 269      * this operation updates an existing tree while trying to preserve
 270      * the XML as much as possible.
 271      *
 272      * <p>
 273      * For example, unknown elements/attributes in XML that were not bound
 274      * to JAXB will be left untouched (whereas a marshalling operation
 275      * would create a new tree that doesn't contain any of those.)
 276      *
 277      * <p>
 278      * As a side-effect, this operation updates the association between
 279      * XML nodes and JAXB objects.
 280      *
 281      * @param jaxbObject root of potentially modified JAXB object tree
 282      * @param xmlNode    root of update target XML parse tree
 283      *
 284      * @return
 285      *      Returns the updated XML node. Typically, this is the same
 286      *      node you passed in as <i>xmlNode</i>, but it maybe
 287      *      a different object, for example when the tag name of the object
 288      *      has changed.
 289      *
 290      * @throws JAXBException
 291      *      If any unexpected problem occurs updating corresponding XML content.
 292      * @throws IllegalArgumentException
 293      *      If any of the input parameters are null
 294      */
 295     public abstract XmlNode updateXML( Object jaxbObject, XmlNode xmlNode ) throws JAXBException;
 296 
 297     /**
 298      * Takes an XML node and updates its associated JAXB object and its descendants.
 299      *
 300      * <p>
 301      * This operation can be thought of as an "in-place" unmarshalling.
 302      * The difference is that instead of creating a whole new JAXB tree,
 303      * this operation updates an existing tree, reusing as much JAXB objects
 304      * as possible.
 305      *
 306      * <p>
 307      * As a side-effect, this operation updates the association between
 308      * XML nodes and JAXB objects.
 309      *
 310      * @return
 311      *      Returns the updated JAXB object. Typically, this is the same
 312      *      object that was returned from earlier
 313      *      {@link #marshal(Object,Object)} or
 314      *      {@link #updateJAXB(Object)} method invocation,
 315      *      but it maybe
 316      *      a different object, for example when the name of the XML
 317      *      element has changed.
 318      *
 319      * @throws JAXBException
 320      *      If any unexpected problem occurs updating corresponding JAXB mapped content.
 321      * @throws IllegalArgumentException
 322      *      If node parameter is null
 323      */
 324     public abstract Object updateJAXB( XmlNode xmlNode ) throws JAXBException;
 325 
 326 
 327     /**
 328      * Specifies whether marshal, unmarshal and update methods
 329      * performs validation on their XML content.
 330      *
 331      * @param schema set to null to disable validation.
 332      *
 333      * @see Unmarshaller#setSchema(Schema)
 334      */
 335     public abstract void setSchema( Schema schema );
 336 
 337     /**
 338      * Gets the last {@link Schema} object (including null) set by the
 339      * {@link #setSchema(Schema)} method.
 340      *
 341      * @return the Schema object for validation or null if not present
 342      */
 343     public abstract Schema getSchema();
 344 
 345     /**
 346      * Allow an application to register a <tt>ValidationEventHandler</tt>.
 347      * <p>
 348      * The <tt>ValidationEventHandler</tt> will be called by the JAXB Provider
 349      * if any validation errors are encountered during calls to any of the
 350      * Binder unmarshal, marshal and update methods.
 351      *
 352      * <p>
 353      * Calling this method with a null parameter will cause the Binder
 354      * to revert back to the default default event handler.
 355      *
 356      * @param handler the validation event handler
 357      * @throws JAXBException if an error was encountered while setting the
 358      *         event handler
 359      */
 360     public abstract void setEventHandler( ValidationEventHandler handler ) throws JAXBException;
 361 
 362     /**
 363      * Return the current event handler or the default event handler if one
 364      * hasn't been set.
 365      *
 366      * @return the current ValidationEventHandler or the default event handler
 367      *         if it hasn't been set
 368      * @throws JAXBException if an error was encountered while getting the
 369      *         current event handler
 370      */
 371     public abstract ValidationEventHandler getEventHandler() throws JAXBException;
 372 
 373     /**
 374      *
 375      * Set the particular property in the underlying implementation of
 376      * <tt>Binder</tt>.  This method can only be used to set one of
 377      * the standard JAXB defined unmarshal/marshal properties
 378      * or a provider specific property for binder, unmarshal or marshal.
 379      * Attempting to set an undefined property will result in
 380      * a PropertyException being thrown.  See
 381      * <a href="Unmarshaller.html#supportedProps">Supported Unmarshal Properties</a>
 382      * and
 383      * <a href="Marshaller.html#supportedProps">Supported Marshal Properties</a>.
 384      *
 385      * @param name the name of the property to be set. This value can either
 386      *              be specified using one of the constant fields or a user
 387      *              supplied string.
 388      * @param value the value of the property to be set
 389      *
 390      * @throws PropertyException when there is an error processing the given
 391      *                            property or value
 392      * @throws IllegalArgumentException
 393      *      If the name parameter is null
 394      */
 395     abstract public void setProperty( String name, Object value ) throws PropertyException;
 396 
 397 
 398     /**
 399      * Get the particular property in the underlying implementation of
 400      * <tt>Binder</tt>.  This method can only
 401      * be used to get one of
 402      * the standard JAXB defined unmarshal/marshal properties
 403      * or a provider specific property for binder, unmarshal or marshal.
 404      * Attempting to get an undefined property will result in
 405      * a PropertyException being thrown.  See
 406      * <a href="Unmarshaller.html#supportedProps">Supported Unmarshal Properties</a>
 407      * and
 408      * <a href="Marshaller.html#supportedProps">Supported Marshal Properties</a>.
 409      *
 410      * @param name the name of the property to retrieve
 411      * @return the value of the requested property
 412      *
 413      * @throws PropertyException
 414      *      when there is an error retrieving the given property or value
 415      *      property name
 416      * @throws IllegalArgumentException
 417      *      If the name parameter is null
 418      */
 419     abstract public Object getProperty( String name ) throws PropertyException;
 420 
 421 }