Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

EclipseLink/UserGuide/MOXy/Runtime/Bootstrapping/Single Project/From sessions.xml using DynamicEntities

< EclipseLink‎ | UserGuide‎ | MOXy‎ | Runtime‎ | Bootstrapping‎ | Single Project
Revision as of 11:47, 29 November 2010 by Rick.barkhouse.oracle.com (Talk | contribs) (New page: == Bootstrapping from an EclipseLink Project == Dynamic MOXy also supports bootstrapping from an EclipseLink <tt>Project</tt> specified in <tt>sessions.xml</tt> <div style="margin-left:4...)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Bootstrapping from an EclipseLink Project

Dynamic MOXy also supports bootstrapping from an EclipseLink Project specified in sessions.xml

Note.png
The key thing to remember when bootstrapping from an EclipseLink project is that your project will only specify Java class names, and not actual Java classes. Keep in mind that you are mapping "imaginary" classes to XML, and these classes will be dynamically generated in memory when the DynamicJAXBContext is built.

CORRECT:

customerDescriptor.setJavaClassName("mynamespace.Customer");
...
addressMapping.setReferenceClassName("mynamespace.Address");

INCORRECT:

customerDescriptor.setJavaClass(mynamespace.Customer.class);
...
addressMapping.setReferenceClass(mynamespace.Address.class);


Once you have your EclipseLink Project, you will need to include it in your EclipseLink sessions.xml file (for more information on sessions.xml please see the EclipseLink documentation). (*** TODO: Add Link Here ***) You can then pass the Session's name to DynamicJAXBContextFactory to create your DynamicJAXBContext using the following API:

/**
 * Create a <tt>DynamicJAXBContext</tt>, using an EclipseLink <tt>sessions.xml</tt> as the metadata source.
 * The <tt>sessionNames</tt> parameter is a colon-delimited list of session names within the
 * <tt>sessions.xml</tt> file.  <tt>Descriptors</tt> in this session's <tt>Project</tt> must <i>not</i>
 * have <tt>javaClass</tt> set, but <i>must</i> have <tt>javaClassName</tt> set.
 *
 * @param sessionNames
 *      A colon-delimited <tt>String</tt> specifying the session names from the <tt>sessions.xml</tt> file.
 * @param classLoader
 *      The application's current class loader, which will be used to first lookup
 *      classes to see if they exist before new <tt>DynamicTypes</tt> are generated.  Can be
 *      <tt>null</tt>, in which case <tt>Thread.currentThread().getContextClassLoader()</tt> will be used.
 * @param properties
 *      Map of properties to use when creating a new <tt>DynamicJAXBContext</tt>.  Can be null.
 *
 * @return
 *      A new instance of <tt>DynamicJAXBContext</tt>.
 *
 * @throws JAXBException
 *      if an error was encountered while creating the <tt>DynamicJAXBContext</tt>.
 */
public static DynamicJAXBContext createContext(String sessionNames, ClassLoader classLoader, 
   Map<String, ?> properties) throws JAXBException



Example

Here is an example of an EclipseLink MOXy Project in code. Notice that we have customizations that are made:

  • We have specified that the package name of the generated classes should be com.mypackage. If importing from XSD, we would have used the default namespace to build the package name instead, which would result in a package name of mynamespace.
  • We have specified that the first-name element in XML should be mapped to a field called fName in Java. If importing from XSD we would have generated a field called firstName.
  • We have specified that a null address will be represented by xsi:nil="true" in XML.
package mynamespace;
 
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLDescriptor;
 
import org.eclipse.persistence.oxm.mappings.XMLDirectMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;
 
public class CustomerProject extends org.eclipse.persistence.sessions.Project {
 
   public CustomerProject() {
      super();
 
      NamespaceResolver nsResolver = new NamespaceResolver();
      nsResolver.put("ns0", "mynamespace");
      nsResolver.put("xsi", XMLConstants.SCHEMA_INSTANCE_URL);
 
      XMLDescriptor customerDescriptor = new XMLDescriptor();
      customerDescriptor.setJavaClassName("mynamespace.Customer");
      customerDescriptor.setDefaultRootElement("customer");
      customerDescriptor.setNamespaceResolver(nsResolver);
 
      XMLDirectMapping firstNameMapping = new XMLDirectMapping();
      firstNameMapping.setAttributeName("fName");
      firstNameMapping.setXPath("first-name/text()");
      customerDescriptor.addMapping(firstNameMapping);
      // ...
 
      XMLCompositeObjectMapping addressMapping = new XMLCompositeObjectMapping();
      addressMapping.setAttributeName("address");
      addressMapping.setXPath("address");
      addressMapping.setReferenceClassName("mynamespace.Address");
      addressMapping.getNullPolicy().setNullRepresentedByXsiNil(true);
      addressMapping.getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL);
      customerDescriptor.addMapping(addressMapping);
 
      XMLDescriptor addressDescriptor = new XMLDescriptor();
      addressDescriptor.setJavaClassName("mynamespace.Address");
      // ...
 
      this.addDescriptor(customerDescriptor);
      this.addDescriptor(addressDescriptor);
   }
 
}

Next, here is an example sessions.xml that includes our Project:

<?xml version="1.0" encoding="US-ASCII"?>
<sessions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ...>
   <session xsi:type="database-session">
      <name>MyCustomerProject</name>
      <primary-project xsi:type="class">mynamespace.CustomerProject</primary-project>
   </session>
</sessions>

Finally, we can now instantiate a DynamicJAXBContext using the session name, and begin working with our DynamicEntities:

DynamicJAXBContext dContext = DynamicJAXBContextFactory.createContext("MyCustomerProject", null, null);
 
DynamicEntity newCustomer = dContext.newDynamicEntity("com.mypackage.Customer");
newCustomer.set("fName", "Bob");
...
dContext.createMarshaller().marshal(newCustomer, System.out);
Idea.png
You may specify multiple Session names when bootstrapping from an EclipseLink Project. For example,
DynamicJAXBContextFactory.createContext("ProjectA:ProjectB", null, null);
would create a single DynamicJAXBContext that is aware of Mappings and Descriptors from both Projects.


Back to the top