001 /*
002 * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.xml.bind;
027
028 import org.w3c.dom.Node;
029
030 import javax.xml.validation.Schema;
031
032 /**
033 * Enable synchronization between XML infoset nodes and JAXB objects
034 * representing same XML document.
035 *
036 * <p>
037 * An instance of this class maintains the association between XML nodes of
038 * an infoset preserving view and a JAXB representation of an XML document.
039 * Navigation between the two views is provided by the methods
040 * {@link #getXMLNode(Object)} and {@link #getJAXBNode(Object)}.
041 *
042 * <p>
043 * Modifications can be made to either the infoset preserving view or the
044 * JAXB representation of the document while the other view remains
045 * unmodified. The binder is able to synchronize the changes made in the
046 * modified view back into the other view using the appropriate
047 * Binder update methods, {@link #updateXML(Object, Object)} or
048 * {@link #updateJAXB(Object)}.
049 *
050 * <p>
051 * A typical usage scenario is the following:
052 * <ul>
053 * <li>load XML document into an XML infoset representation</li>
054 * <li>{@link #unmarshal(Object)} XML infoset view to JAXB view.
055 * (Note to conserve resources, it is possible to only unmarshal a
056 * subtree of the XML infoset view to the JAXB view.)</li>
057 * <li>application access/updates JAXB view of XML document.</li>
058 * <li>{@link #updateXML(Object)} synchronizes modifications to JAXB view
059 * back into the XML infoset view. Update operation preserves as
060 * much of original XML infoset as possible (i.e. comments, PI, ...)</li>
061 * </ul>
062 *
063 * <p>
064 * A Binder instance is created using the factory method
065 * {@link JAXBContext#createBinder()} or {@link JAXBContext#createBinder(Class)}.
066 *
067 * <p>
068 * The template parameter, <code>XmlNode</code>, is the
069 * root interface/class for the XML infoset preserving representation.
070 * A Binder implementation is required to minimally support
071 * an <code>XmlNode</code> value of <code>org.w3c.dom.Node.class</code>.
072 * A Binder implementation can support alternative XML infoset
073 * preserving representations.
074 *
075 * @author
076 * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
077 * Joseph Fialli
078 *
079 * @since JAXB 2.0
080 */
081 public abstract class Binder<XmlNode> {
082 /**
083 * Unmarshal XML infoset view to a JAXB object tree.
084 *
085 * <p>
086 * This method is similar to {@link Unmarshaller#unmarshal(Node)}
087 * with the addition of maintaining the association between XML nodes
088 * and the produced JAXB objects, enabling future update operations,
089 * {@link #updateXML(Object, Object)} or {@link #updateJAXB(Object)}.
090 *
091 * <p>
092 * When {@link #getSchema()} is non-null, <code>xmlNode</code>
093 * and its descendants is validated during this operation.
094 *
095 * <p>
096 * This method throws {@link UnmarshalException} when the Binder's
097 * {@link JAXBContext} does not have a mapping for the XML element name
098 * or the type, specifiable via <tt>@xsi:type</tt>, of <tt>xmlNode</tt>
099 * 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)
120 throws JAXBException;
121
122 /**
123 * Unmarshal XML root element by provided <tt>declaredType</tt>
124 * to a JAXB object tree.
125 *
126 * <p>
127 * Implements <a href="Unmarshaller.html#unmarshalByDeclaredType">Unmarshal by Declared Type</a>
128 *
129 * <p>
130 * This method is similar to {@link Unmarshaller#unmarshal(Node, Class)}
131 * with the addition of maintaining the association between XML nodes
132 * and the produced JAXB objects, enabling future update operations,
133 * {@link #updateXML(Object, Object)} or {@link #updateJAXB(Object)}.
134 *
135 * <p>
136 * When {@link #getSchema()} is non-null, <code>xmlNode</code>
137 * and its descendants is validated during this operation.
138 *
139 * @param xmlNode
140 * the document/element to unmarshal XML data from.
141 * @param declaredType
142 * appropriate JAXB mapped class to hold <tt>node</tt>'s XML data.
143 *
144 * @return
145 * <a href="#unmarshalDeclaredTypeReturn">JAXB Element</a> representation
146 * of <tt>node</tt>
147 *
148 * @throws JAXBException
149 * If any unexpected errors occur while unmarshalling
150 * @throws UnmarshalException
151 * If the {@link ValidationEventHandler ValidationEventHandler}
152 * returns false from its <tt>handleEvent</tt> method or the
153 * <tt>Binder</tt> is unable to perform the XML to Java
154 * binding.
155 * @throws IllegalArgumentException
156 * If any of the input parameters are null
157 * @since JAXB2.0
158 */
159 public abstract <T> JAXBElement<T> unmarshal(XmlNode xmlNode,
160 Class<T> declaredType) 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)
193 throws JAXBException;
194
195 /**
196 * Gets the XML element associated with the given JAXB object.
197 *
198 * <p>
199 * Once a JAXB object tree is associated with an XML fragment,
200 * this method enables navigation between the two trees.
201 *
202 * <p>
203 * An association between an XML element and a JAXB object is
204 * established by the bind methods and the update methods.
205 * Note that this association is partial; not all XML elements
206 * have associated JAXB objects, and not all JAXB objects have
207 * associated XML elements.
208 *
209 * @param jaxbObject An instance that is reachable from a prior
210 * call to a bind or update method that returned
211 * a JAXB object tree.
212 *
213 * @return
214 * null if the specified JAXB object is not known to this
215 * {@link Binder}, or if it is not associated with an
216 * XML element.
217 *
218 * @throws IllegalArgumentException
219 * If the jaxbObject parameter is null
220 */
221 public abstract XmlNode getXMLNode(Object jaxbObject);
222
223 /**
224 * Gets the JAXB object associated with the given XML element.
225 *
226 * <p>
227 * Once a JAXB object tree is associated with an XML fragment,
228 * this method enables navigation between the two trees.
229 *
230 * <p>
231 * An association between an XML element and a JAXB object is
232 * established by the unmarshal, marshal and update methods.
233 * Note that this association is partial; not all XML elements
234 * have associated JAXB objects, and not all JAXB objects have
235 * associated XML elements.
236 *
237 * @return
238 * null if the specified XML node is not known to this
239 * {@link Binder}, or if it is not associated with a
240 * JAXB object.
241 *
242 * @throws IllegalArgumentException
243 * If the node parameter is null
244 */
245 public abstract Object getJAXBNode(XmlNode xmlNode);
246
247 /**
248 * Takes an JAXB object and updates
249 * its associated XML node and its descendants.
250 *
251 * <p>
252 * This is a convenience method of:
253 * <pre>
254 * updateXML( jaxbObject, getXMLNode(jaxbObject));
255 * </pre>
256 *
257 * @throws JAXBException
258 * If any unexpected problem occurs updating corresponding XML content.
259 * @throws IllegalArgumentException
260 * If the jaxbObject parameter is null
261 */
262 public abstract XmlNode updateXML(Object jaxbObject)
263 throws JAXBException;
264
265 /**
266 * Changes in JAXB object tree are updated in its associated XML parse tree.
267 *
268 * <p>
269 * This operation can be thought of as an "in-place" marshalling.
270 * The difference is that instead of creating a whole new XML tree,
271 * this operation updates an existing tree while trying to preserve
272 * the XML as much as possible.
273 *
274 * <p>
275 * For example, unknown elements/attributes in XML that were not bound
276 * to JAXB will be left untouched (whereas a marshalling operation
277 * would create a new tree that doesn't contain any of those.)
278 *
279 * <p>
280 * As a side-effect, this operation updates the association between
281 * XML nodes and JAXB objects.
282 *
283 * @param jaxbObject root of potentially modified JAXB object tree
284 * @param xmlNode root of update target XML parse tree
285 *
286 * @return
287 * Returns the updated XML node. Typically, this is the same
288 * node you passed in as <i>xmlNode</i>, but it maybe
289 * a different object, for example when the tag name of the object
290 * has changed.
291 *
292 * @throws JAXBException
293 * If any unexpected problem occurs updating corresponding XML content.
294 * @throws IllegalArgumentException
295 * If any of the input parameters are null
296 */
297 public abstract XmlNode updateXML(Object jaxbObject, XmlNode xmlNode)
298 throws JAXBException;
299
300 /**
301 * Takes an XML node and updates its associated JAXB object and its descendants.
302 *
303 * <p>
304 * This operation can be thought of as an "in-place" unmarshalling.
305 * The difference is that instead of creating a whole new JAXB tree,
306 * this operation updates an existing tree, reusing as much JAXB objects
307 * as possible.
308 *
309 * <p>
310 * As a side-effect, this operation updates the association between
311 * XML nodes and JAXB objects.
312 *
313 * @return
314 * Returns the updated JAXB object. Typically, this is the same
315 * object that was returned from earlier
316 * {@link #marshal(Object,Object)} or
317 * {@link #updateJAXB(Object)} method invocation,
318 * but it maybe
319 * a different object, for example when the name of the XML
320 * element has changed.
321 *
322 * @throws JAXBException
323 * If any unexpected problem occurs updating corresponding JAXB mapped content.
324 * @throws IllegalArgumentException
325 * If node parameter is null
326 */
327 public abstract Object updateJAXB(XmlNode xmlNode)
328 throws JAXBException;
329
330 /**
331 * Specifies whether marshal, unmarshal and update methods
332 * performs validation on their XML content.
333 *
334 * @param schema set to null to disable validation.
335 *
336 * @see Unmarshaller#setSchema(Schema)
337 */
338 public abstract void setSchema(Schema schema);
339
340 /**
341 * Gets the last {@link Schema} object (including null) set by the
342 * {@link #setSchema(Schema)} method.
343 *
344 * @return the Schema object for validation or null if not present
345 */
346 public abstract Schema getSchema();
347
348 /**
349 * Allow an application to register a <tt>ValidationEventHandler</tt>.
350 * <p>
351 * The <tt>ValidationEventHandler</tt> will be called by the JAXB Provider
352 * if any validation errors are encountered during calls to any of the
353 * Binder unmarshal, marshal and update methods.
354 *
355 * <p>
356 * Calling this method with a null parameter will cause the Binder
357 * to revert back to the default default event handler.
358 *
359 * @param handler the validation event handler
360 * @throws JAXBException if an error was encountered while setting the
361 * event handler
362 */
363 public abstract void setEventHandler(ValidationEventHandler handler)
364 throws JAXBException;
365
366 /**
367 * Return the current event handler or the default event handler if one
368 * hasn't been set.
369 *
370 * @return the current ValidationEventHandler or the default event handler
371 * if it hasn't been set
372 * @throws JAXBException if an error was encountered while getting the
373 * current event handler
374 */
375 public abstract ValidationEventHandler getEventHandler()
376 throws JAXBException;
377
378 /**
379 *
380 * Set the particular property in the underlying implementation of
381 * <tt>Binder</tt>. This method can only be used to set one of
382 * the standard JAXB defined unmarshal/marshal properties
383 * or a provider specific property for binder, unmarshal or marshal.
384 * Attempting to set an undefined property will result in
385 * a PropertyException being thrown. See
386 * <a href="Unmarshaller.html#supportedProps">Supported Unmarshal Properties</a>
387 * and
388 * <a href="Marshaller.html#supportedProps">Supported Marshal Properties</a>.
389 *
390 * @param name the name of the property to be set. This value can either
391 * be specified using one of the constant fields or a user
392 * supplied string.
393 * @param value the value of the property to be set
394 *
395 * @throws PropertyException when there is an error processing the given
396 * property or value
397 * @throws IllegalArgumentException
398 * If the name parameter is null
399 */
400 abstract public void setProperty(String name, Object value)
401 throws PropertyException;
402
403 /**
404 * Get the particular property in the underlying implementation of
405 * <tt>Binder</tt>. This method can only
406 * be used to get one of
407 * the standard JAXB defined unmarshal/marshal properties
408 * or a provider specific property for binder, unmarshal or marshal.
409 * Attempting to get an undefined property will result in
410 * a PropertyException being thrown. See
411 * <a href="Unmarshaller.html#supportedProps">Supported Unmarshal Properties</a>
412 * and
413 * <a href="Marshaller.html#supportedProps">Supported Marshal Properties</a>.
414 *
415 * @param name the name of the property to retrieve
416 * @return the value of the requested property
417 *
418 * @throws PropertyException
419 * when there is an error retrieving the given property or value
420 * property name
421 * @throws IllegalArgumentException
422 * If the name parameter is null
423 */
424 abstract public Object getProperty(String name)
425 throws PropertyException;
426
427 }
|