This chapter provides an overview of XML projects and their components.
This chapter includes the following section:
For information on project concepts and features common to more than one type of TopLink projects, see Chapter 15, "Introduction to Projects".
Use an XML project for nontransactional, nonpersistent (in-memory) conversions between Java objects and XML documents using JAXB (see Section 47.1.1, "TopLink Support for Java Architecture for XML Binding (JAXB)" and Section 47.1.2, "JAXB Validation"
). Both Oracle JDeveloper TopLink Editor and TopLink Workbench provide complete support for creating XML projects.
The TopLink runtime performs XML data conversion based on one or more XML schemas. In an XML project, TopLink Workbench directly references schemas in the deployment XML, and exports mappings configured with respect to the schemas you specify. For information on how to use TopLink Workbench with XML schemas, see Section 5.6, "Using XML Schemas". For information on how TopLink supports XML namespaces, see Section 15.4, "XML Namespaces Overview"
.
Table 47-1 describes the components of an XML project.
Table 47-1 XML Project Components
Component | Supported Types |
---|---|
Data Source |
None |
Descriptors |
For more information, see Section 50.1, "XML Descriptor Concepts" |
Mappings |
For more information, see the following: |
Note:
In an XML project, you do not use TopLink queries and expressions.JAXB defines annotations to control the mapping of Java objects to XML, but it also defines a default set of mappings. Using the defaults, TopLink can marshall a set of objects into XML, and unmarshall an XML document into objects. JAXB provides a standard Java object-to-XML API. For more information, see http://java.sun.com/xml/jaxb/index.html
.
TopLink provides an extra layer of functions on top of JAXB. It allows for the creation and subsequent manipulation of mappings (in the form of a TopLink runtime project or TopLink Workbench project) from an existing object model, without requiring the recompilation of the JAXB object model.
An essential component of this function is the TopLink JAXB compiler. Using the TopLink JAXB compiler, you can generate both a TopLink XML project and JAXB-compliant object model classes from your XML schema.
The TopLink JAXB compiler simplifies JAXB application development with TopLink by automatically generating (see Section 48.2, "Creating an XML Project from an XML Schema") both the required JAXB files (see Section 47.1.1.2, "Working with JAXB-Specific Generated Files"
) and the TopLink files from your XML schema (XSD) document.
For more information on using the JAXB and TopLink-specific run-time classes, see Section 47.1.1.3, "Using TopLink JAXB Compiler-Generated Files at Run Time".
For information on marshalling POJOs with JAXB, see http://www.oracle.com/technology/products/ias/toplink/preview/how-to/JAXBwithPOJOs.html
.
The TopLink JAXB compiler generates a TopLink project and an XML schema using JAXB annotations that Table 47-2 lists.
Table 47-2 JAXB Annotations Supported by TopLink
Annotation | Description | Level |
---|---|---|
|
Indicates that a class should be mapped to a root-level element in a schema. The element name and namespace are specified in this annotation. |
Class |
|
Indicates that a particular attribute on a Java class should be mapped to an XML element in the schema. The name and namespace can be specified by this annotation. |
Field |
|
Indicates that the Java attribute should map to an XML attribute in the schema. Name and namespace should be provided. |
Field |
|
Specifies a wrapper element around another element or attribute. You can use this annotation to create a grouping element around a collection. |
Field |
|
Indicates that a collection property should map to a space-separated list in XML. |
Field |
|
Defines the complex-type for a class. Using this annotation's |
Class |
|
Indicates that a mapping should not be generated for a particular field. This is a marker annotation. |
Field |
|
Specifies the target namespace for a schema. You can also use this annotation to configure namespace prefix mappings with the |
Package |
|
Appears only in an |
Package |
|
Maps an attribute to a text node under the parent class (for example, an Xpath of "text( )"). Also indicates that the owning class should map to either a |
Field |
|
Indicates that a JDK 1.5 The base schema type is specified on this annotation. |
Field |
|
Lets you specify the enumeration facets to be used in the schema, if they are to be different from the string values of the Enum constants specified in Java. |
Field |
|
Specifies how the classes' attributes should be processed. The following are valid values:
|
Package or class |
|
Specifies the order in which properties are to be processed. The following are valid values:
|
Package or class |
|
If specified at a property level, indicates the schema type that should be used in schema generation. If used as part of an |
Property or package |
|
Contains a collection of |
Package |
|
Specifies that a |
Field |
For more information, see Chapter 8 of JAXB 2.0 Specification at http://jcp.org/aboutJava/communityprocess/pfd/jsr222/index.html
Note:
The TopLink project is generated from a collection of annotated Java classes with support for relationships, collection-style mappings, and JDK 1.5 enumerations.The schema is generated from a set of annotated Java classes with support for relationships.
The TopLink JAXB compiler generates the following JAXB-specific files from your XSD:
The JAXB runtime uses these files as specified by the JAXB specification.
All JAXB-specific files are generated in the output directory you define, and in the subdirectories implied by the target package name you define. For more information about TopLink JAXB binding compiler options, see Section 48.2, "Creating an XML Project from an XML Schema".
Before you compile your generated classes, be sure to configure your IDE classpath to include <
ORACLE_HOME
>\lib\xml.jar
. For an example, see Chapter 7, "Using an Integrated Development Environment".
All implementation classes are named according to the content, element, or implementation name attribute defined in the XSD.
The generated implementation classes are simple domain classes, with private attributes for each JAXB property, and public get
and set
methods that return or set attribute values.
At run time, you can access the TopLink JAXB compiler-generated files by doing the following:
Using TopLink XMLContext
(see Section 47.1.1.3.1, "How to Use TopLink XMLContext")
Using TopLink XMLBinder
(see Section 47.1.1.3.3, "How to Use TopLink XMLBinder")
Using TopLink JAXBContext
(see Section 47.1.1.3.4, "How to Use JAXBContext")
TopLink provides an oracle.toplink.ox.XMLContext
class using which you can create instances of TopLink XMLMarshaller
, XMLUnmarshaller
, XMLBinder
(see Section 47.1.1.3.3, "How to Use TopLink XMLBinder"), and
XMLValidator
.
The XMLContext
is thread-safe. For example, if multiple threads accessing the same XMLContext
object request an XMLMarshaller
, each will receive their own instance of XMLMarshaller
, so any state that the XMLMarshaller
maintains will be unique to that process. By using the XMLContext
, you can use TopLink XML in multithreaded architectures, such as the binding layer for Web services.
Create the XMLContext using its constructor method and by passing in the session name defined in the sessions.xml
file, as the following example shows:
XMLContext context = new XMLContext("mysession");
You can also create the XMLContext from multiple sessions using a colon separated list of session names, as the following example shows:
XMLContext context = new XMLContext("session1:session2:session3");
Use the XMLContext
to create a TopLink XMLMarshaller
, XMLUnmarshaller
, XMLBinder
, and XMLValidator
, as follows:
XMLMarshaller marshaller = context.createMarshaller(); marshaller.marshal(myObject, outputStream); marshaller.setFormattedOutput(true); XMLUnmarshaller unmarshaller = context.createUnmarshaller(); Employee emp = (Employee)unmarshaller.unmarshal(new File("employee.xml")); XMLBinder binder = context.createBinder(); Address add = (Address)binder.unmarshal(myElement); XMLValidator validator = context.createValidator(); boolean isValid = validator.validate(emp);
Using the XMLContext
getDocumentPreservationPolicy
method, you can retrieve this context's document preservation policy in a form of the DocumentPreservationPolicy
object. This object's API lets you specify the position of newly added to the node elements, as well as disable the addition of new elements.
You can provide TopLink XMLMarshaller
and XMLUnmarshaller
with additional functionality at run time by registering them with a listener to handle specific event callbacks. This allows for extra processing on a business object either immediately before, or immediately after an object is written to or read from XML.
There are two types of event callbacks that you can handle in two different ways:
To handle listener-based callbacks, set an event handler on an instance of XMLMarshaller
or XMLUnmarshaller
that implements a required interface, such as XMLMarshalListener
or XMLUnmarshalListener
. The events are triggered on the marshaller or unmarshaller's listener for any classes being marshalled or unmarshalled.
To handle class-specific callbacks, you need to provide the required callback methods on your business objects.
Note:
If you specify both the listener and the business object callbacks, the class-specific method will be invoked before the listener event.Example 47-1 shows how to create your custom event listeners.
Example 47-1 Implementing the TopLink XMLMarhsalListener and XMLUnmarhsalListener Interfaces
public class EmployeeMarshalListener implements XMLMarshalListener { public void beforeMarshal(Object target) { // do something } public void afterMarshal(Object target) { // do something } ) public class EmployeeUnmarshalListener implements XMLUnmarshalListener { public void beforeUnmarshal(Object target, Object parent) { // do something } public void afterUnmarshal(Object target, Object parent) { // do something } )
Example 47-2 and Example 47-3
show how to use the listeners in your application.
XMLBinder
is a run-time class that allows you to preserve a document that you have unmarshalled, as well as to resynchronize that document with the unmarshalled objects at any time.
Note:
This functionality is based on the JAXB binder API (javax.xml.bind.Binder<XmlNode>
). This is an addition to the design-time method of document preservation.When the XMLBinder
unmarshalls XML nodes into mapping objects, and then performs an update operation, it preserves not only the order of elements, but also the comments from an original XML document using the cached value. This way, both the returned node and the cached node are identical and reflect the preserved document. When adding new elements, TopLink XMLBinder
places them at the correct location (relative to other mapped content) in the node.
When unmarshalling a document that contains only unmapped content, setting some values and then marshalling, the XMLBinder
adds new elements before existing unmapped data, such as comments and processing instructions.
Example 47-4 demonstrates how you can unmarshall a document using an instance of an
XMLBinder
.
Example 47-4 Unmarshalling a Document Using XMLBinder
XMLContext conext = new XMLContext(myProject); XMLBinder binder = context.createBinder(); Employee emp = (Employee) binder.unmarshal(myDocument);
In the preceding example, emp
is the root object that was unmarshalled from the provided document. The binder maintains references to the original XML document as well as objects generated during the unmarshall operation.
Example 47-5 demonstrates how you can make changes to the object (
Employee
) and update the XML document using an instance of an XMLBinder
.
Example 47-5 Making Changes to an Object and to Updating XML Using XMLBinder
... emp.setPhoneNumber("123-4567"); binder.updateXML(emp);
In the preceding example, the updateXML
method will update the cached node in the binder. Note that the cached node preserves the document, including comments, as the following example shows:
<employee> <!--comment1 --> <name>John Smith </name> <phone-number>123-4567</phone-number> <!--comment2 --> </employee>
Example 47-6 demonstrates how you can obtain an associated node for a subobject (
Address
) of the Employee
using an instance of an XMLBinder
.
Example 47-6 Obtaining an Associated Node Using XMLBinder
... Address addr = emp.getAddress(); Node addressNode = binder.getXMLNode(addr);
In the preceding example, the returned node (addressNode
) is the XML node in the original XML document that was used to build this employee's Address
object.
Example 47-7 demonstrates how you can make changes to an XML node and update objects (
Address
) of the Employee
using an instance of an XMLBinder
.
Example 47-7 Making Changes to an XML Node and Updating Objects Using XMLBinder
... addressNode.setAttribute("apt-no", "1527"); Address updatedAddressNode = binder.updateObject(addressNode);
In the preceding example, the address returned from the binder operation is the original Address object created during the unmarshall operation, but now it contains the updated apartment number information from the XML document.
You can create an instance of JAXBContext
from a collection of classes that are to be bound to XML. This will generate a TopLink project from the classes dynamically at run time.
Using the instance of JAXBContext
you can obtain Marshaller
and Unmarshaller
instances to operate on those classes, as Example 47-8 demonstrates. Note that this example assumes that you configure your application classpath to include your domain object class files.
Example 47-8 Creating and Using JAXBContext
Class[] classes = {Employee.class, Address.class, Department.class}; JAXBContext jaxbContext = JAXBContext.newInstance(classes); Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.marshal(myEmployee, myOutput);
Note:
TheJAXBContext
object is thread-safe.TopLink lets you marshal to and unmarshall from JAXBElement
types. The javax.xml.bind.JAXBElement
class provides access to the following basic properties of an XML element:
its qualified name, which is composed of {target namespace}
and {name}
its value, which is an instance of the Java class binding of its {type definition}
whether or not the element's content is {nillable}
TopLink supports the following JAXB element marshal API defined in the Marshaller
:
marshal(java.lang.Object jaxbElement, java.io.Writer writer)
marshal(java.lang.Object jaxbElement,
java.io.OutputStream os)
marshal(java.lang.Object jaxbElement,
org.xml.sax.ContentHandler)
marshal(java.lang.Object jaxbElement,
javax.xml.transform.Result)
marshal(java.lang.Object jaxbElement, org.w3c.dom.Node)
marshal(java.lang.Object jaxbElement,
javax.xml.stream.XMLStreamWriter writer)
Note:
If the first parameter is not aJAXBElement
, the marshal operation will throw an oracle.toplink.exceptions.XMLMarshalException.MARSHAL_EXCEPTION
.TopLink provides implementation of the following JAXB element unmarshall API defined in the Unarshaller
:
<T> JAXBElement<T> unmarshal(
org.w3c.dom.Node node, Class<T> declaredType)
<T> JAXBElement<T> unmarshal(
javax.xml.transform.Source source,
Class<T> declaredType)
<T> JAXBElement<T> unmarshal(
javax.xml.stream.XMLStreamReader streamReader,
Class<T> declaredType)
<T> JAXBElement<T> unmarshal(
javax.xml.stream.XMLEventReader eventReader,
Class<T> declaredType)
TopLink can validate both complete object trees and subtrees against the XML schema that was used to generate the implementation classes. In addition, TopLink will validate both root objects (objects that correspond to the root element of the XML document) and nonroot objects against the schema used to generate the object's implementation class.
When validating an object tree, TopLink performs the following checks (in order):
Check that element appears in the document at the specified location.
If maxOccurs or minOccurs is specified, check number of elements.
If type is specified, check that element value satisfies the type constraints.
If a fixed value is specified, check that the element value matches it.
If restrictions (length, patterns, enumerations, and so on) are specified, check that the element value satisfies it.
If an ID type is specified during a validateRoot
operation, check that the ID value is unique in the document.
If an IDREF type is specified during a validateRoot
operation, check that the ID referenced exists in the document.
If validation errors are encountered, TopLink stops validating the object tree and creates a Validation
object, according to the JAXB specification. If an error occurs in a subobject, TopLink will not validate further down that object's subtree.
For more information on using TopLink XML to perform validation, see Section 47.1.1.3, "Using TopLink JAXB Compiler-Generated Files at Run Time".
For additional information on JAXB and validation, refer to the JAXB specification at http://java.sun.com/xml/jaxb/
.