Jump to: navigation, search

Difference between revisions of "EclipseLink/Examples/SDO/DynamicAPI"

 
(16 intermediate revisions by 2 users not shown)
Line 1: Line 1:
==Overview==
+
==Creating DataObjects==
 +
===Using DataFactory===
 +
DataObjects can be created by Type using DataFactory:
 +
<source lang="java">
 +
Type customerType = TypeHelper.INSTANCE.getType("http://www.example.org/customer-example", "customer-type");
 +
DataObject customerDO = DataFactory.INSTANCE.create(customerType);
 +
</source>
  
The following example will demonstrate how to use EclipseLink's SDO functionality to:
+
===Using DataObject===
* Define a set of SDO Types from an XML Schema
+
Once you have a DataObject you can use it to create child DataObjects based on its properties:
* Load an XML file and modify its data
+
<source lang="java">
* Monitor changes made to the data
+
DataObject contactInfoDO = customerDO.createDataObject("contact-info");
* Save the modified data to XML
+
DataObject billingAddressDO = contactInfoDO.createDataObject("billing-address");
 +
</source>
  
==Setup==
+
==Getting/Setting Properties==
 
+
An SDO path (similar to XPath) can be used with the String based accessors:
# Ensure that you have EclipseLink correctly installed and configured for your environment.  Please see [[EclipseLink/Installing and Configuring EclipseLink]] for more information.
+
<source lang="java">
# Ensure that you have ANT correctly installed and configured.
+
DataObject billingAddressDO = customerDO.getDataObject("contact-info/billing-address");
# Unzip the Example ZIP file to a new directory.
+
</source>
# Edit the <tt>env.properties</tt> file in the root directory of the example and specify the path to your EclipseLink <tt>jlib</tt> directory:<pre>
+
...
+
# Edit eclipselink.jlib to point to your EclipseLink jlib directory
+
eclipselink.jlib=C:/EclipseLink-1.0/eclipselink/jlib
+
...
+
</pre>
+
# You can compile and run the Example at any time by typing <tt>ant</tt> from the Example directory. 
+
 
+
==Initializing the Types from XML Schema==
+
 
+
The first thing that needs to be done in an SDO application is to set up the metadata for the Types and Properties. This is most commonly done by loading an XML schema, although it may also be done programmatically.
+
 
+
<pre>
+
FileInputStream xsdInputStream = new FileInputStream("Customer.xsd");
+
XSDHelper.INSTANCE.define(xsdInputStream, null);
+
</pre>
+
 
+
==Unmarshalling the XML Document==
+
 
+
With the SDO Types and Properties defined from the schema, we can now load an XML document based on that schema, and then obtain a DataObject and begin modifying its contents.
+
 
+
<pre>
+
FileInputStream xmlInputStream = new FileInputStream("Customer-data.xml");
+
XMLDocument xmlDocument = XMLHelper.INSTANCE.load(xmlInputStream);
+
DataObject customerDO = xmlDocument.getRootObject();
+
</pre>
+
 
+
==Tracking Object Modifications using Change Summary==
+
 
+
SDO's Change Summary provides access to change history information for the DataObjects in a data graph.  A change history covers any modifications that have been made to a data graph starting from the point when logging was activated.
+
 
+
In order to use Change Summary, we have defined an element of type "<tt>sdo:ChangeSummaryType</tt>" on our root complex type:
+
 
+
<pre>
+
<xs:complexType name="customer-type">
+
    <xs:sequence>
+
        ...
+
        <xs:element name="changeSummary" type="sdo:ChangeSummaryType" minOccurs="0"/>
+
 
+
    </xs:sequence>
+
</xs:complexType>
+
</pre>
+
 
+
Before we start modifying our data, we must enable logging:
+
 
+
<pre>
+
customerDO.getChangeSummary().beginLogging();
+
</pre>
+
 
+
From this point on, any modifications to the DataObject will be captured in the Change Summary, until logging is deactivated:
+
 
+
<pre>
+
customerDO.getChangeSummary().endLogging();
+
</pre>
+
 
+
==Modifying the DataObjects==
+
 
+
Below are examples of manipulating the DataObjects using the dynamic APIs.  Note how the dynamic accessors take an XPath instead of just a property name.
+
 
+
Modifying the ShippingAddress ZipCode:
+
<pre>
+
DataObject addressDO = customerDO.getDataObject("contact-info").getDataObject("shipping-address");
+
addressDO.set("zip-code", "27601");
+
</pre>
+
 
+
Adding a new PhoneNumber:
+
<pre>
+
DataObject newPhoneNumberDO = DataFactory.INSTANCE.create("urn:customer-example", "phone-number");
+
newPhoneNumberDO.set("number-type", "home");
+
newPhoneNumberDO.set("value", "(613) 555-3333");
+
customerDO.getList("contact-info/phone-number").add(newPhoneNumberDO);
+
</pre>
+
 
+
Removing all "cell" PhoneNumbers:
+
<pre>
+
ArrayList phoneNumbersToRemove = new ArrayList();
+
List phoneNumbers = customerDO.getDataObject("contact-info").getList("phone-number");
+
Iterator it = phoneNumbers.iterator();
+
while (it.hasNext()) {
+
    DataObject phoneNumberDO = (DataObject) it.next();
+
    if (phoneNumberDO.get("number-type").equals("cell")) {
+
        phoneNumbersToRemove.add(phoneNumberDO);
+
    }
+
}
+
phoneNumbers.removeAll(phoneNumbersToRemove);
+
</pre>
+
 
+
There are general accessors for properties, i.e., <tt>get()</tt> and <tt>set()</tt>, as well as specific accessors for the primitive types and commonly used data types like String, Date, List, BigInteger, and BigDecimal.  For more information see the [http://help.eclipse.org/help32/topic/org.eclipse.emf.ecore.sdo.doc/references/javadoc/commonj/sdo/DataObject.html documentation for DataObject].
+
 
+
==Marshalling the DataObjects==
+
 
+
The following code segment demonstrates how to marshal DataObjects wrapped in a <tt>commonj.sdo.helper.XMLDocument</tt> back to XML.  In this example the stream we are saving to is <tt>System.out</tt>, so the XML text will be printed to the console.
+
 
+
<pre>
+
XMLHelper.INSTANCE.save(xmlDocument, System.out, null);
+
</pre>
+
 
+
==Interpreting the Change Summary==
+
 
+
When the document is saved to <tt>System.out</tt>, we can see the change summary information in the XML:
+
 
+
<pre>
+
<ns1:customer ...>
+
  ...
+
  <changeSummary logging="false" create="#/ns1:contact-info/ns1:phone-number[2]" delete="#/changeSummary/ns1:contact-info/ns1:phone-number[2]" xmlns:sdo="commonj.sdo">
+
      <ns1:contact-info sdo:ref="#/ns1:contact-info">
+
        <ns1:phone-number sdo:ref="#/ns1:contact-info/ns1:phone-number[1]"/>
+
        <ns1:phone-number number-type="cell">(613) 555-2222</ns1:phone-number>
+
      </ns1:contact-info>
+
      <shipping-address sdo:ref="#/ns1:contact-info/shipping-address">
+
        <zip-code>12345</zip-code>
+
      </shipping-address>
+
  </changeSummary>
+
</ns1:customer>
+
</pre>
+
 
+
* For DataObjects with modified data type properties, the Change Summary element contains a copy of the DataObject from the data graph, but containing only the properties which have changed, and showing their old values.&nbsp; In our example, we see a "<tt>shipping-address</tt>" element which references "<tt>#/ns1:contact-info/shipping-address</tt>" (the element that was modified), along with its old value, "<tt>12345</tt>".
+
 
+
* DataObjects which are currently in the data graph, but were not present when logging was started are indicated in the change summary with a "<tt>create</tt>" attribute.  If more than one DataObject had been created, the attribute would contain a space-separated list of references, one for each DataObject.  In our example, we see a "<tt>create</tt>" attribute indicating that "<tt>#/ns1:contact-info/ns1:phone-number\[2\]</tt>" (the second phone number in the XML) is the newly created one.
+
 
+
* DataObjects deleted during logging are flagged with the "<tt>delete</tt>" attribute. In this case the change summary also contains a deep copy of the object which was deleted, as it no longer appears in the data graph.  Here, we see a "<tt>delete</tt>" attribute indicating that "<tt>#/changeSummary/ns1:contact-info/ns1:phone-number\[2\]<tt>" (the second phone number in the ''Change Summary'') is the one that was deleted from the XML.
+
 
+
==Download==
+
 
+
[http://aseng-wiki.us.oracle.com/asengwiki/download/attachments/42829291/org.eclipse.persistence.example.sdo.dynamicapi.zip]
+

Latest revision as of 17:01, 24 February 2009

Creating DataObjects

Using DataFactory

DataObjects can be created by Type using DataFactory:

Type customerType = TypeHelper.INSTANCE.getType("http://www.example.org/customer-example", "customer-type");
DataObject customerDO = DataFactory.INSTANCE.create(customerType);

Using DataObject

Once you have a DataObject you can use it to create child DataObjects based on its properties:

DataObject contactInfoDO = customerDO.createDataObject("contact-info");
DataObject billingAddressDO = contactInfoDO.createDataObject("billing-address");

Getting/Setting Properties

An SDO path (similar to XPath) can be used with the String based accessors:

DataObject billingAddressDO = customerDO.getDataObject("contact-info/billing-address");