blob: 26359f5d2896b01faf60ae8dc7f15e3b091a0c8e [file] [log] [blame]
//
// Copyright (c) 2020, 2022 Contributors to the Eclipse Foundation
//
== The Binding Framework
The _binding framework_ defines APIs to
access unmarshalling, validation and marshalling operations for
manipulating XML data and JAXB mapped objects. The framework is
presented here in overview; its full specification is available in the
javadoc for the package `jakarta.xml.bind`.
The binding framework resides in two main
packages. The `jakarta.xml.bind` package defines abstract classes and
interfaces that are used directly with content classes. The
`jakarta.xml.bind` package defines the
`Unmarshaller`, `Marshaller` and `Binder` classes, which are auxiliary
objects for providing their respective operations.
The `JAXBContext` class is the entry point
for a Java application into the JAXB framework. A `JAXBContext` instance
manages the binding relationship between XML element names to Java value
class for a JAXB implementation to be used by the unmarshal, marshal and
binder operations. The `jakarta.xml.bind.helper` package provides partial
default implementations for some of the `jakarta.xml.bind` interfaces.
Implementations of JAXB technology can extend these classes and
implement the abstract methods. These APIs are not intended to be used
directly by applications using the JAXB architecture. A third package,
`jakarta.xml.bind.util`, contains utility classes that may be used
directly by client applications.
The binding framework defines a hierarchy of
exception and validation event classes for use when
marshalling/unmarshalling errors occur, when constraints are violated,
and when other types of errors are detected.
=== Annotation-driven Binding Framework
The portability of JAXB annotated classes is
achieved via an annotation-driven architecture. The program annotations,
specified in Section 8, describe the mapping from the Java program
elements to XML Schema components. This information is used by the
binding framework to unmarshal and marshal to XML content into/from
JAXB-annotated classes. All JAXB schema binding compilers must be able
to generate portable schema-derived JAXB-annotated classes following the
constraints described in <<Binding XML Schema to Java Representations>>.
All binding runtime frameworks are required
to be able to marshal and unmarshal portable JAXB-annotated classes
generated by other Jakarta XML Binding schema binding compiler.
It is not possible to require portability of
the interface/implementation binding from JAXB 1.0. For backwards
compatibility with existing implementations, that binding remains a
tight coupling between the schema-derived implementation classes and the
JAXB implementation’s runtime framework. Users are required to
regenerate the schema-derived implementation classes when changing JAXB
implementations.
=== JAXBContext
The `JAXBContext` class provides the client’s
entry point to the JAXB API. It provides an abstraction for managing the
XML/Java binding information necessary to implement the JAXB binding
framework operations: unmarshal and marshal.
The following summarizes the `JAXBContext` class defined in package `jakarta.xml.bind`.
[source,java]
----
public abstract class JAXBContext {
static final String JAXB_CONTEXT_FACTORY;
static JAXBContext newInstance(String contextPath);
static JAXBContext newInstance(String contextPath,
ClassLoader contextPathCL);
static JAXBContext newInstance(Class... classesToBeBound);
abstract Unmarshaller createUnmarshaller();
abstract Marshaller createMarshaller();
abstract JAXBIntrospector createJAXBIntrospector();
<T> Binder<T> createBinder(Class<T> domType);
Binder<org.w3c.dom.Node> createBinder();
void generateSchema(SchemaOutputResolver);
}
----
To avoid the overhead involved in creating a
JAXBContext instance, a JAXB application is encouraged to reuse a
JAXBContext instance. An implementation of abstract class JAXBContext is
required to be thread-safe, thus, multiple threads in an application can
share the same JAXBContext instance.
A client application configures a JAXBContext
using the `JAXBContext.newInstance(String contextPath)` factory method.
[source,java,indent=8]
----
JAXBContext jc =
JAXBContext.newInstance( "com.acme.foo:com.acme.bar" );
----
The above example initializes a `JAXBContext`
with the schema-derived Java packages `com.acme.foo` and `com.acme.bar`.
A `jaxb.index` resource file, described in more detail in the javadoc,
list the non-schema-derived classes, namely the java to schema binding,
in a package to register with `JAXBContext`. Additionally, in each
specified directory, if an optional resource filefootnote:pkginfo[Section 7.4.1.1
“Package Annotations” in [JLS\] recommends that file-system-based
implementations have the annotated package declaration in a file called
`package-info.java`.]
containing package level mapping annotations exist, it is incorporated
into the JAXBContext representation.
An alternative mechanism that could be more
convenient when binding Java classes to Schema is to initialize
JAXBContext by passing JAXB-annotated class objects.
[source,java,indent=8]
----
JAXBContext jc =
JAXBContext.newInstance( POElement.class );
----
The classes specified as parameters to
`newInstance` and all classes that are directly/indirectly referenced
statically from the specified classes are included into the returned
`JAXBContext` instance. For each directory of all the classes imported
into JAXBContext, if an optional resource filefootnote:pkginfo[] containing package level
mapping annotations exists, it is incorporated into the JAXBContext
representation.
For example, given the following Java classes:
[source,java,indent=4,subs="+macros"]
----
@XmlRootElement class Foo { Bar b; }footnote:[Program annotations @XmlRootElement and @XmlType are specified in Section 8.0.]
@XmlType class Bar { FooBar fb; }
@XmlType class FooBar { int x; }
----
The invocation of
`JAXBContext.newInstance(Foo.class)` registers Foo and the statically
referenced classes, `Bar` and `FooBar`.
Note that the jaxb.index resource file is not
necessary when an application uses
`JAXBContenxt.newInstances(Class...classesToBeBound)`.
For either scenario, the values of these
parameters initialize the JAXBContext object so that it is capable of
managing the JAXB mapped classes.
See the javadoc for `JAXBContext` for more details on using this class.
[NOTE]
.Design Note
====
JAXBContext class is designed to be immutable and thus thread-safe.
Given the amount of dynamic processing that potentially could take place
when creating a new instance of JAXBContxt, it is recommended
that a JAXBContext instance be shared across threads and reused
as much as possible to improve application performance.
====
[NOTE]
.Note
====
If JAXB-annotated classes or packages referenced in context path
are defined in a Java Platform Module System (JSR 376) module,
they must be open (as specified in javadoc of `java.lang.Module#isOpen()`)
to at least `jakarta.xml.bind` module.
====
=== General Validation Processing
Three identifiable forms of validation exist
within the JAXB architecture include:
* *Unmarshal-time validation* +
This form of validation enables a client
application to be notified of validation errors and warnings detected
while unmarshalling XML data into a Java content tree and is completely
orthogonal to the other types of validation. See
jakarta.xml.bind.Unmarshaller javadoc for a description on how to enable
this feature.
* *On-demand validation* +
This mode of validation is not defined in Jakarta XML Binding Specification.
* *Fail-fast validation* +
This form of validation enables a client
application to receive immediate feedback about a modification to the
Java content tree that violates a type constraint of a Java property. An
unchecked exception is thrown if the value provided to a set method is
invalid based on the constraint facets specified for the basetype of the
property. This style of validation is optional in this version of the
specification. Of the JAXB implementations that do support this type of
validation, it is customization-time decision to enable or disable
fail-fast validation when setting a property.
Unmarshal-time uses an event-driven mechanism
to enable multiple validation errors and warnings to be processed during
a single operation invocation. If the validation or unmarshal operation
terminates with an exception upon encountering the first validation
warning or error, subsequent validation errors and warnings would not be
discovered until the first reported error is corrected. Thus, the
validation event notification mechanism provides the application a more
powerful means to evaluate validation warnings and errors as they occur
and gives the application the ability to determine when a validation
warning or error should abort the current operation (such as a value
outside of the legal value space). Thus, an application could allow
locally constrained validation problems to not terminate validation
processing.
If the client application does not set an
event handler on a `Unmarshaller` or `Marshaller` instance prior to
invoking the `unmarshal` or `marshal` operations, then a default event
handler will receive notification of any errors or fatal errors
encountered and stop processing the XML data. In other words, the
default event handler will fail on the first error that is encountered.
There are three ways to handle validation
events encountered during the unmarshal and marshal operations:
* *Rely on the default validation event handler* +
The default handler will fail on the first error or fatal error
encountered.
* *Implement and register a custom validation event handler* +
Client applications that require sophisticated event processing can
implement the `ValidationEventHandler` interface and register it with
the Validator or Unmarshaller instance respectively.
* *Request an error/warning event list after the operation completes* +
By registering the `ValidationEventCollector` helper, a specialized
event handler, with the `setEventHandler` method, the `ValidationEvent`
objects created during the unmarshal and marshal operations are
collected. The client application can then request the list after the
operation completes.
Validation events are handled differently
depending on how the client application is configured to process them as
described previously. However, there are certain cases where a JAXB
implementation may need to indicate that it is no longer able to
reliably detect and report errors. In these cases, the JAXB
implementation will set the severity of the `ValidationEvent` to
`FATAL_ERROR` to indicate that the `unmarshal` or `validate` operation
should be terminated. The default event handler and
`ValidationEventCollector` helper class must terminate processing after
being notified of a fatal error. Client applications that supply their
own `ValidationEventHandler` should also terminate processing after
being notified of a fatal error. If not, unexpected behavior may occur.
=== Unmarshalling
The `Unmarshaller` class governs the process
of deserializing XML data into a Java content tree, capable of
validating the XML data as it is unmarshalled. It provides the basic
unmarshalling methods:
[source,java]
----
public interface Unmarshaller {
ValidationEventHandler getEventHandler()
void setEventHandler(ValidationEventHandler)
java.lang.Object getProperty(java.lang.String name)
void setProperty(java.lang.String name, java.lang.Object value)
void setSchema(javax.xml.validation.Schema schema)
javax.xml.validation.Schema getSchema()
UnmarshallerHandler getUnmarshallerHandler()
void setListener(Unmarshaller.Listener)
Unmarshaller.Listener getListener()
java.lang.Object unmarshal(java.io.File)
java.lang.Object unmarshal(java.net.URL)
java.lang.Object unmarshal(java.io.InputStream)
java.lang.Object unmarshal(org.xml.sax.InputSource)
java.lang.Object unmarshal(org.w3c.dom.Node)
java.lang.Object unmarshal(javax.xml.transform.Source)
java.lang.Object unmarshal(javax.xml.stream.XMLStreamReader)
java.lang.Object unmarshal(javax.xml.stream.XMLEventReader)
<T> JAXBElement<T> unmarshal(org.w3c.dom.Node,
Class<T> declaredType)
<T> JAXBElement<T> unmarshal(javax.xml.transform.Source,
Class<T> declaredType)
<T> JAXBElement<T> unmarshal(javax.xml.stream.XMLStreamReader,
Class<T> declaredType)
<T> JAXBElement<T> unmarshal(javax.xml.stream.XMLEventReader,
Class<T> declaredType)
}
----
The `JAXBContext` class contains a factory to
create an `Unmarshaller` instance. The `JAXBContext` instance manages
the XML/Java binding data that is used by unmarshalling. If the
`JAXBContext` object that was used to create an `Unmarshaller` does not
know how to unmarshal the XML content from a specified input source,
then the `unmarshal` operation will abort immediately by throwing an
`UnmarshalException`. There are six convenience methods for
unmarshalling from various input sources.
An application can enable or disable
unmarshal-time validation by enabling JAXP validation via the
`setSchema(javax.xml.validation.Schema)` method. The application has the
option to customize validation error handling by overriding the default
event handler using the `setEventHandler(ValidationEventHandler)`. The
default event handler aborts the unmarshalling process when the first
validation error event is encountered. Validation processing options are
presented in more detail in <<General Validation Processing>>.
An application has the ability to specify a
SAX 2.0 parser to be used by the `unmarshal` operation using the
`unmarshal(javax.xml.transform.Source)` method. Even though the JAXB
provider’s default parser is not required to be SAX2.0 compliant, all
providers are required to allow an application to specify their own
SAX2.0 parser. Some providers may require the application to specify the
SAX2.0 parser at binding compile time. See the method javadoc
`unmarshal(Source)` for more detail on how an application can specify
its own SAX 2.0 parser.
The `getProperty`/`setProperty` methods
introduce a mechanism to associate implementation specific
property/value pairs to the unmarshalling process. At this time there
are no standard JAXB properties specified for the unmarshalling process.
==== Unmarshal event callbacks
The `Unmarshaller` provides two styles of
callback mechanisms that allow application specific processing during
key points in the unmarshalling process. In 'class-defined' event
callbacks, application specific code placed in JAXB mapped classes is
triggered during unmarshalling. External listeners allow for centralized
processing of unmarshal events in one callback method rather than by
type event callbacks. The 'class defined' and external listener event
callback methods are independent of each other, both can be called for
one event. The invocation ordering when both listener callback methods
exist is defined in `jakarta.xml.bind.Unmarshaller.Listener` javadoc.
Event callback methods should be written with
following considerations. Each event callback invocation contributes to
the overall unmarshal time. An event callback method throwing an
exception terminates the current unmarshal process.
===== Class-defined
A JAXB mapped class can optionally implement
the following unmarshal event callback methods.
* `private void beforeUnmarshal(Unmarshaller, Object parent)` +
+
This method is called immediately after the
object is created and before the unmarshalling of this object begins.The
callback provides an opportunity to initialize JavaBean properties prior
to unmarshalling.
** *Parameters:* +
`unmarshaller` - unmarshal context. +
`parent` - points to the parent object to which
this object will be set. Parent is null when this object is the root
object.
* `private void afterUnmarshal(Unmarshaller, Object parent)` +
+
This method is called after all the
properties (except IDREF) are unmarshalled for this object, but before
this object is set to the parent object.
** *Parameters:* +
`unmarshaller` - unmarshal context. +
`parent` - points to the parent object to which
this object will be set. Parent is null when this object is the root
object.
These callback methods allow an object to
perform additional processing at certain key point in the unmarshalling
operation.
===== External Listener
The external listener callback mechanism
enables the registration of a `Unmarshaller.Listener` instance with an
`Unmarshaller.setListener(Unmarshaller.Listener)`. The external
listener receives all callback events, allowing for more centralized
processing than per class defined callback methods. The external
listener receives events when unmarshalling to a JAXB element or to JAXB
mapped class.
==== Unmarshalling Modes
There exist numerous use cases requiring the
ability to unmarshal invalid XML content. A flexible unmarshalling mode
is described in this version of the specification to enable predictable
unmarshalling of invalid content. The previous unmarshalling mode
implied by JAXB 1.0 specification is named structural unmarshalling.
This unmarshalling mode was well defined for the unmarshalling of valid
XML content and allowed an implementation to handle invalid XML content
in anyway that it choose to.
Both of these modes have benefits and
drawbacks based on an application’s xml processing needs.
==== Structural Unmarshalling
Some of the XML Schema to Java bindings in
JAXB 1.0 implied that an unmarshaller had to maintain a state machine,
implying that the order of elements had to match up exactly as described
by the schema or unmarshaller would work unpredictably. When this
unmarshalling process detects a structural inconsistency that it is
unable to recover from, it should abort the unmarshal process by
throwing `UnmarshalException`.
For example, it was valid for a Jakarta XML Binding
implementation to rigidly give up unmarshalling an invalid XML document
once it came across an unexpected element/attribute or missed a required
element or attribute. This mode appeals to users who prefer to be
notified that an xml document is deviating from the schema.
XML Schema to Java binding for interfaces and
implementation classes, <<Java Content Interface>>, can implement either structural unmarshalling or flexible
unmarshalling.
==== Flexible Unmarshalling
To address the rigidness of structural
unmarshalling, flexible unmarshalling mode is specified to enable
greater predictability in unmarshalling invalid XML content. It
unmarshals xml content by element name, rather than strictly on the
position of the element within a content model. This allows this mode to
handle the following cases:
* elements being out of order in a content
model
* recovering from required
elements/attributes missing from an xml document
* ignoring unexpected elements/attributes in
an xml document
In order to enable this mode, the following
JAXB 1.0 customized bindings that required state-driven unmarshalling
have been removed from this specification.
* Binding a model group or model group
definition to a Java class. +
Since there is no XML infoset information denoting these schema
components, a model group can only be inferred by applying positional
schema constraints to a valid XML document, tracking position within a
valid content model.
* Multiple occurrences of an element name in
a content model can no longer be mapped to different JAXB properties.
Instead the entire content model is bound to a general content model.
The removal of these bindings greatly assists
the error recovery for structural unmarshalling mode.
Flexible unmarshalling appeals to those who
need to be able to perform best match unmarshalling of invalid xml
documents.
The flexible unmarshalling process is
annotation driven. This process is specified in
<<Runtime Processing>>. Flexible
unmarshalling is required for Jakarta XML Binding annotated classes.
=== Marshalling
The `Marshaller` class is responsible for
governing the process of serializing a Java content tree into XML data.
It provides the basic marshalling methods:
[source,java]
----
interface Marshaller {
string JAXB_ENCODING;
string JAXB_FORMATTED_OUTPUT;
string JAXB_SCHEMA_LOCATION;
string JAXB_NO_NAMESPACE_SCHEMA_LOCATION;
string JAXB_FRAGMENT;
<PROTENTIALLY MORE PROPERTIES...>
java.lang.Object getProperty(java.lang.String name)
void setProperty(java.lang.String name, java.lang.Object value)
void setEventHandler(ValidationEventHandler handler)
ValidationEventHandler getEventHandler()
void setSchema(javax.xml.validation.Schema schema)
javax.xml.validation.Schema getSchema()
void setListener(Unmarshaller.Listener)
Unmarshaller.Listener getListener()
void marshal(java.lang.Object e, java.io.Writer writer)
void marshal(java.lang.Object e, java.io.OutputStream os)
void marshal(java.lang.Object e, org.xml.sax.ContentHandler)
void marshal(java.lang.Object e, javax.xml.transform.Result)
void marshal(java.lang.Object e, org.w3c.dom.Node)
void marshal(java.lang.Object e,
javax.xml.stream.XMLStreamWriter writer)
org.w3c.dom.Node getNode(java.lang.Object contentTree)
}
----
The `JAXBContext` class contains a factory to
create a `Marshaller` instance. Convenience method overloading of the
`marshal()` method allow for marshalling a content tree to common Java
output targets and to common XML output targets of a stream of SAX2
events or a DOM parse tree.
Although each of the marshal methods accepts
a `java.lang.Object` as its first parameter, JAXB implementations are
not required to be able to marshal any arbitrary `java.lang.Object`. If
the first parameter is not a JAXB element, as determined by
`JAXBIntrospector.isElement()` method, the marshal operation must throw
a `MarshalException`. There exist two mechanisms to enable marshalling
an instance that is not a JAXB element. One method is to wrap the
instance as the value of a `jakarta.xml.bind.JAXBElement` instance, and
pass the wrapper element as the first parameter to a `marshal` method.
For java to schema binding, it is also possible to simply annotate the
instance's class with the appropriate program annotation,
`@XmlElementRoot`, specified in Section 8.
The marshalling process can optionally be
configured to validate the content tree being marshalled. An application
can enable or disable marshal-time validation by enabling JAXP
validation via the `setSchema(javax.xml.validation.Schema)` method. The
application has the option to customize validation error handling by
overriding the default event handler using the
`setEventHandler(ValidationEventHandler)`. The default event handler
aborts the marshalling process when the first validation error event is
encountered. Validation processing options are presented in more detail
in <<General Validation Processing>>.
There is no requirement that the Java content
tree be valid with respect to its original schema in order to marshal it
back into XML data. If the marshalling process detects a structural
inconsistency during its process that it is unable to recover from, it
should abort the marshal process by throwing `MarshalException`. The
marshalling process of a JAXB-annotated class is annotation driven. This
process is specified in <<Runtime Processing>>.
==== Marshal event callbacks
The Marshaller provides two styles of
callback mechanisms that allow application specific processing during
key points in the marshalling process. In class-defined event callbacks,
application specific code placed in JAXB mapped classes is triggered
during marshalling. External listeners allow for centralized processing
of marshal events in one callback method rather than by type event
callbacks. The invocation ordering when both listener callback methods
exist is defined in `jakarta.xml.bind.Marshaller.Listener` javadoc.
Event callback methods should be written with
following considerations. Each event callback invocation contributes to
the overall marshal time. An event callback method throwing an exception
terminates the current marshal process.
===== Class-defined
A JAXB mapped class can optionally implement
the following marshal event callback methods.
* `private void beforeMarshal(Marshaller)` +
+
This method is called before the marshalling
of this object starts.
** *Parameters:* +
`marshaller` - marshal context.
* `private void afterMarshal(Marshaller)` +
+
This method is called after the marshalling
of this object (and all its descendants) has finished.
** *Parameters:* +
`marshaller` - marshal context.
These callback methods allow the
customization of an JAXB mapped class to perform additional processing
at certain key point in the marshalling operation. The 'class defined'
and external listener event callback methods are independent of each
other, both can be called for one event.
An event callback method throwing an
exception terminates the current marshal process.
===== External Listener
The external listener callback mechanism
enables the registration of a `Marshaller.Listener` instance with a
`Marshaller.setListener(Marshaller.Listener)`. The external listener
receives all callback events, allowing for more centralized processing
than per class-defined callback methods.
==== Marshalling Properties
The following subsection highlights
properties that can be used to control the marshalling process. These
properties must be set prior to the start of a marshalling operation:
the behavior is undefined if these attributes are altered in the middle
of a marshalling operation. The following standard properties have been
identified:
* `jaxb.encoding` +
output character
encoding. If the property is not specified, it defaults to "UTF-8".
* `jaxb.formatted.output` +
`true` - human readable indented xml data +
`false` - unformatted xml data +
If the property is not specified, it defaults to `false`.
* `jaxb.schemaLocation` +
This property allows the client application to specify an
`xsi:schemaLocation` attribute in the generated XML data.
* `jaxb.noNamespaceSchemaLocation` +
This property allows the client application to specify an
`xsi:noNamespaceSchemaLocation` attribute in the generated XML data.
* `jaxb.fragment` +
Its value must be a java.lang.Boolean. This property determines
whether or not document level events will be generated by the
Marshaller. If this property is not defined, it defaults to `false`.
=== JAXBIntrospector
This class provides access to key XML mapping
information of a JAXB mapped instance.
[source,java]
----
public abstract class JAXBIntrospector {
public boolean isElement(Object jaxbObj);
public QName getElementName(Object jaxbElement);
public static Object getValue(Object jaxbElement);
}
----
The Jakarta XML Binding architecture has two uniquely
different ways to represent an XML element.The XML Schema to Java
binding for an XML element declaration is described in
<<Java Element Representation>>. The Java
to XML Schema binding for an XML element declaration is described in
<<xmlrootelement>>.
Use JAXBInstrospector.isElement(Object)
method to determine if an instance of a JAXB mapped class represents an
XML element. One can get the xml element tag name associated with a JAXB
element using `JAXBIntrospector.getElementName` method. One can an xml
element’s value using getValue method. The getValue method normalizes
access of JAXB element, hiding whether the JAXB element is an instance
of jakarta.xml.bind.JAXBElement or if it is an JAXB element via an
@XmlRootElement class annotation.
=== Validation Handling
Methods defined in the binding framework can
cause validation events to be delivered to the client application’s
`ValidationEventHandler.Setter` methods generated in schema-derived
classes are capable of throwing `TypeConstraintExceptions`, all of
which are defined in the binding framework.
The following list describes the primary
event and constraint-exception classes:
* An instance of a `TypeConstraintException`
subclass is thrown when a violation of a dynamically-checked type
constraint is detected. Such exceptions will be thrown by property-set
methods, for which it would be inconvenient to have to handle checked
exceptions; type-constraint exceptions are therefore unchecked, _i.e_,
this class extends `java.lang.RuntimeException`. The constraint check
is always performed prior to the property-set method updating the value
of the property, thus if the exception is thrown, the property is
guaranteed to retain the value it had prior to the invocation of the
property-set method with an invalid value. This functionality is
optional to implement in this version of the specification.
Additionally, a customization mechanism is provided to control enabling
and disabling this feature.
* An instance of a `ValidationEvent` is
delivered whenever a violation is detected during optionally enabled
unmarshal/marshal validation. Additionally, `ValidationEvents` can be
discovered during marshalling such as ID/IDREF violations and print
conversion failures. These violations may indicate local and global
structural constraint violations, type conversion violations, type
constraint violations, etc.
* Since the unmarshal operation involves
reading an input document, lexical well-formedness errors may be
detected or an I/O error may occur. In these cases, an
`UnmarshalException` will be thrown to indicate that the JAXB provider
is unable to continue the unmarshal operation.
* During the marshal operation, the JAXB
provider may encounter errors in the Java content tree that prevent it
from being able to complete. In these cases, a `MarshalException` will
be thrown to indicate that the marshal operation can not be completed.
=== DOM and Java representation Binding
The Binder class is responsible for
maintaining the relationship between a infoset preserving view of an XML
document with a possibly partial binding of the XML document to a JAXB
representation. Modifications can be made to either the infoset
preserving view or the JAXB representation of the document while the
other view remains unmodified. The binder is able to synchronize the
changes made in the modified view back into the read-only view. When
synchronizing changes to JAXB view back to related xml infoset
preserving view, every effort is made to preserve XML concepts that are
not bound to JAXB objects, such as XML infoset comments, processing
instructions, namespace prefix mappings, etc.
==== Use Cases
* Read-only partial binding. +
+
Application only needs to manipulate a small part of a rather large XML
document. It suffices to only map the small of the large document to the
JAXB Java representation. +
* Updateable partial binding +
+
The application receives an XML document that follows a later version of
the schema than the application is aware of. The parts of the schema
that the application needs to read and/or modify have not changed. Thus,
the document can be read into an infoset preserving representation, such
as DOM, only bind the part of the document that it does still have the
correct schema for into the JAXB Java representation of the fragment of
the document using Binder.unmarshal from the DOM to the JAXB view.
Modify the partial Java representation of the document and then
synchronize the modified parts of the Java representation back to the
DOM view using `Binder.updateXML` method.
* XPATH navigation +
+
Given that binder maintains a relationship between XML infoset view of
document and JAXB representation, one can use JAXP XPATH on the XML
infoset view and use the binder’s associative mapping to get from the
infoset node to JAXB representation.
==== jakarta.xml.bind.Binder
The class `jakarta.xml.bind.Binder` associates
an infoset preserving representation of the entire XML document with a
potentially partial binding to a Java representation. The binder
provides operations to synchronize between the two views that it is
binding.
[source,java]
----
public abstract class Binder<XmlNode> {
// Create two views of XML content, infoset view and JAXB view.
public abstract Object unmarshal(XmlNode xmlNode)
<T> JAXBElement<T> unmarshal(XmlNode xmlNode,
Class<T> declaredType)
public abstract void marshal(Object jaxbObject, XmlNode xmlNode)
// Navigation between xml infoset view and JAXB view.
public abstract XmlNode getXMLNode(Object jaxbObject);
public abstract Object getJAXBNode(XmlNode xmlNode);
// Synchronization methods
public abstract XmlNode updateXML(Object jaxbObject)
public abstract XmlNode updateXML(Object jaxbObject, XmlNode xmlNode)
throws JAXBException;
public abstract Object updateJAXB(XmlNode xmlNode)
throws JAXBException;
// Enable optional validation
public abstract void setSchema(Schema schema);
public abstract Schema getSchema();
public abstract void setEventHandler(ValidationEventHandler handler)
throws JAXBException;
public abstract ValidationEventHandler getEventHandler()
throws JAXBException;
// Marshal/Unmarshal properties
public abstract void setProperty(String name, Object value)
throws PropertyException;
public abstract Object getProperty(String name)
throws PropertyException;
}
----
=== Implementation discovery
To create an instance of JAXBContext,
one of `JAXBContext.newInstance` methods is invoked. JAXB implementation
discovery happens each time `JAXBContext.newInstance` is invoked.
Implementation discovery consists of following steps in the order
specified (first successful resolution applies):
. If the system property `jakarta.xml.bind.JAXBContextFactory` exists,
then its value is assumed to be the provider factory class. This phase
of the look up enables per-JVM override of the Jakarta XML Binding implementation.
. If the property `jakarta.xml.bind.JAXBContextFactory` exists in the `Map<String, ?>`
passed to `JAXBContext.newInstance(Class[], Map)` or to `JAXBContext.newInstance(String, ClassLoader, Map)`,
then its value is assumed to be the fully qualified provider factory class name.
This phase of the look up enables context sensitive selection of the Jakarta XML Binding implementation.
. Provider of `jakarta.xml.bind.JAXBContextFactory` is loaded
using the service-provider loading facilities, as defined by
Java SE Platform, to attempt to locate and load
an implementation of the service.
. Finally, if all of the steps above fail,
then the rest of the look up is unspecified.
Once the provider factory class is discovered, context creation
is delegated to one of its createContext(...) methods.