Loading
Developing JAXB Applications Using EclipseLink MOXy, Release 2.4
  Go To Table Of Contents
Contents
 Search
Other Searches
 PDF
PDF
Comments
Comments

Bootstrapping

EclipseLink MOXy offers several options when creating your JAXBContext. You have the option of bootstrapping from:

Using the JAXBContext API

The methods on JAXBContext (shown in Example 2-1) are used to create new instances.

Example 2-1 JAXBContext Methods

public static JAXBContext newInstance(Class... classesToBeBound) throws JAXBException

public static JAXBContext newInstance(Class[] classesToBeBound, Map<String,?> properties) throws JAXBException

public static JAXBContext newInstance(String contextPath) throws JAXBException

public static JAXBContext newInstance(String contextPath, ClassLoader classLoader) throws JAXBException

public static JAXBContext newInstance(String contextPath, ClassLoader classLoader, Map<String,?> properties) throws JAXBException

JAXBContext accepts the following options:

  • classesToBeBound – List of Java classes to be recognized by the new JAXBContext

  • contextPath – List of Java package names (or EclipseLink session names) that contain mapped classes

  • classLoader – The class loader used to locate the mapped classes

  • properties – A map of additional properties.

The APIs in Example 2-1 expect to find a jaxb.properties file in your Java package/context path. For more information see "Specifying the EclipseLink Runtime".

Bootstrapping from Classes

If you have a collection of Java classes annotated with JAXB annotations, you can provide a list of these classes directly:

JAXBContext context = JAXBContext.newInstance(Company.class, Employee.class);

Other classes that are reachable from the classes in the array (for example, referenced classes, super class) will automatically be recognized by the JAXBContext. Subclasses or classes marked as @XmlTransient will not be recognized.

Bootstrapping from a Context Path

Another way to bootstrap your JAXBContext is with a String, called the context path. This is a colon-delimited list of package names containing your mapped classes:

JAXBContext context = JAXBContext.newInstance("example");

Using this approach, there are a few different ways that EclipseLink will discover your model classes:

Using a jaxb.index File

The context path could contain a file named jaxb.index, which is a simple text file containing the class names from the current package that will be brought into the JAXBContext:

src/example/jaxb.index:

Example 2-2 Sample jaxb.index File

Employee
PhoneNumber

Other classes that are reachable from the classes in list (for example, referenced classes, super class) will automatically be recognized by the JAXBContext. Subclasses or classes marked as @XmlTransient will not be recognized.

Using an ObjectFactory

The context path could also contain a class called ObjectFactory, which is a special factory class that JAXB will look for. This class contains create() methods for each of the types in your model. Typically the ObjectFactory will be generated by the JAXB compiler, but one can be written by hand as well.

src/example/ObjectFactory.java:

Example 2-3 Sample ObjectFactory

@XmlRegistry
public class ObjectFactory {
private final static QName _Employee_QNAME = new QName("", "employee");
private final static QName _PhoneNumber_QNAME = new QName("", "phone-number");
public ObjectFactory() {
}
public EmployeeType createEmployeeType() {
return new EmployeeType();
}
@XmlElementDecl(namespace = "", name = "employee")
 public JAXBElement<EmployeeType> createEmployee(EmployeeType value) {
        return new JAXBElement<EmployeeType>(_Employee_QNAME, EmployeeType.class, null, value);
    }
     public PhoneNumberType createPhoneNumberType() {
        return new PhoneNumberType();
    }
 
    @XmlElementDecl(namespace = "", name = "phone-number")
    public JAXBElement<PhoneNumberType> createPhoneNumber(PhoneNumberType value) {
        return new JAXBElement<PhoneNumberType>(_PhoneNumber_QNAME, PhoneNumberType.class, null, value);
    }
 
}

Using MetadataSource

EclipseLink MOXy also has the ability to retrieve mapping information from an implementation of EclipseLink's MetadataSource. Using this approach, you are responsible for creating your own XmlBindings.

Example 2-4 Sample Metadata Source

package org.eclipse.persistence.jaxb.metadata;
public interface MetadataSource {
 
    /**
     * @param properties – The properties passed in to create the JAXBContext
     * @param classLoader – The ClassLoader passed in to create the JAXBContext
     * 
     * @return the XmlBindings object representing the metadata
     */
    XmlBindings getXmlBindings(Map<String, ?> properties, ClassLoader classLoader);
 
}

For information on using a MetadataSource, see "Using MetadataSource".

Bootstrapping from EclipseLink XML Bindings

To have more control over how your classes will be mapped to XML, you can bootstrap from an EclipseLink XML bindings document. Using this approach, you can take advantage of EclipseLink's robust mappings framework and customize how each complex type in XML maps to its Java counterpart.

Links to the actual documents are passed in via the properties parameter, using a special key, JAXBContextProperties.OXM_METADATA_SOURCE:

Example 2-5 Using an EclipseLink Bindings Document

InputStream iStream = myClassLoader.getResourceAsStream("example/xml-bindings.xml");
 
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, iStream);
 
JAXBContext context = JAXBContext.newInstance(new Class[]{ Customer.class }, properties);

For more information on the XML Bindings format, see "Using XML Bindings".

Combining Annotated Classes and XML Bindings

When bootstrapping from annotated classes, additional mapping information can be provided with an EclipseLink XML bindings document. For instance, you might annotate your model classes with JAXB-spec-only annotations, and put your EclipseLink-specific mapping customizations into an XML bindings document (negating the need to import EclipseLink annotations in your model classes).

For example, review the annotated Employee class in Example 2-6.

Example 2-6 Sample Java Class

package example;
 
import javax.xml.bind.annotation.*;

@XmlRootElement

@XmlAccessorType(XmlAccessType.FIELD)
public class Employee {
   @XmlElement(name="phone-number")
   private PhoneNumber phoneNumber;
   ...
}

You can customize the Employee to use an EclipseLink XMLAdapter for marshalling/unmarshalling PhoneNumbers by using the XML Bindings in Example 2-7.

Example 2-7 Using an XML Bindings Document

<?xml version="1.0" encoding="US-ASCII"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm">
  <java-types>
    <java-type name="example.Employee">
      <java-attributes>
        <xml-element java-attribute="phoneNumber">
          <xml-java-type-adapter value="example.util.PhoneNumberProcessor"/>
        </xml-element>
      </java-attributes>
    </java-type>
  </java-types>
</xml-bindings>

Finally, pass both the list of annotated classes and the link to the XML Bindings to the JAXBContext, as shown in Example 2-8.

Example 2-8 Sample Application Code

InputStream iStream = myClassLoader.getResourceAsStream("example/xml-bindings.xml");
 Map<String, Object> properties = new HashMap<String, Object>();
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, iStream);
 
Class[] classes = new Class[] { Company.class, Employee.class };
JAXBContext context = JAXBContext.newInstance(classes, properties);
Comments powered by Disqus