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

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

(Interpreting the Change Summary)
 
(10 intermediate revisions by 2 users not shown)
Line 14: Line 14:
 
# Unzip the Example ZIP file to a new directory.
 
# Unzip the Example ZIP file to a new directory.
 
# 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:
 
# 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>
+
<source lang="ini">
 
...
 
...
 
# Edit eclipselink.jlib to point to your EclipseLink jlib directory
 
# Edit eclipselink.jlib to point to your EclipseLink jlib directory
 
eclipselink.jlib=C:/EclipseLink-1.0/eclipselink/jlib
 
eclipselink.jlib=C:/EclipseLink-1.0/eclipselink/jlib
 
...
 
...
</pre>
+
</source>
  
 
You can compile and run the Example at any time by typing <tt>ant</tt> from the Example directory.   
 
You can compile and run the Example at any time by typing <tt>ant</tt> from the Example directory.   
Line 27: Line 27:
 
# From the "File" menu, choose "Import..."
 
# From the "File" menu, choose "Import..."
 
# In the Import dialog, choose "General > Existing Projects into Workspace", and click "Next".
 
# In the Import dialog, choose "General > Existing Projects into Workspace", and click "Next".
# Click "Browse" to select a Root Directory, and point to the folder containing this example.  After selecting the directory, you should see the project name in the "Projects:" list.  Click "Finish".
+
# Click "Browse" to select a root directory, and point to the folder containing this example.  After selecting the directory, you should see the project name in the "Projects" list.  Click "Finish".
  
This project is configured to use a classpath variable, ECLIPSELINK_JLIB, to point to the required JAR files.  After the project is imported, you should define a variable called ECLIPSELINK_JLIB to point to your EclipseLink <tt>jlib</tt> directory.
+
This project is configured to use a classpath variable, <tt>ECLIPSELINK_JLIB</tt>, to point to the required JAR files.  After the project is imported, you should define a variable called <tt>ECLIPSELINK_JLIB</tt> to point to your EclipseLink <tt>jlib</tt> directory.
  
 
==Running the SDO Compiler==
 
==Running the SDO Compiler==
  
 
The SDO compiler can be run to generate Static SDO Java files from an XML Schema:
 
The SDO compiler can be run to generate Static SDO Java files from an XML Schema:
<pre>
+
<source lang="text">
 
<ECLIPSELINK_HOME>/eclipselink/bin/sdo-compiler.sh [-options]
 
<ECLIPSELINK_HOME>/eclipselink/bin/sdo-compiler.sh [-options]
 
<ECLIPSELINK_HOME>\eclipselink\bin\sdo-compiler.cmd [-options]
 
<ECLIPSELINK_HOME>\eclipselink\bin\sdo-compiler.cmd [-options]
Line 46: Line 46:
 
Example:
 
Example:
 
   sdo-compiler.sh -sourceFile config/Customer.xsd -targetDirectory sdo-compiler-output -logLevel 8
 
   sdo-compiler.sh -sourceFile config/Customer.xsd -targetDirectory sdo-compiler-output -logLevel 8
</pre>
+
</source>
  
 
For each complex type in the schema, the compiler will generate both an interface (e.g. <tt>CustomerType.java</tt>), and a concrete implementation which subclasses <tt>org.eclipse.persistence.sdo.SDODataObject</tt> (e.g. <tt>CustomerTypeImpl.java</tt>).  For this example we will only deal with the generated interfaces.
 
For each complex type in the schema, the compiler will generate both an interface (e.g. <tt>CustomerType.java</tt>), and a concrete implementation which subclasses <tt>org.eclipse.persistence.sdo.SDODataObject</tt> (e.g. <tt>CustomerTypeImpl.java</tt>).  For this example we will only deal with the generated interfaces.
Line 56: Line 56:
 
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.
 
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>
+
<source lang="java">
 
FileInputStream xsdInputStream = new FileInputStream("Customer.xsd");
 
FileInputStream xsdInputStream = new FileInputStream("Customer.xsd");
 
XSDHelper.INSTANCE.define(xsdInputStream, null);
 
XSDHelper.INSTANCE.define(xsdInputStream, null);
</pre>
+
</source>
  
 
==Unmarshalling the XML Document==
 
==Unmarshalling the XML Document==
Line 76: Line 76:
  
 
In order to use Change Summary, we have defined an element of type "<tt>sdo:ChangeSummaryType</tt>" on our root complex type:
 
In order to use Change Summary, we have defined an element of type "<tt>sdo:ChangeSummaryType</tt>" on our root complex type:
<pre>
+
<source lang="xml">
 
<xs:complexType name="customer-type">
 
<xs:complexType name="customer-type">
 
     <xs:sequence>
 
     <xs:sequence>
Line 84: Line 84:
 
     </xs:sequence>
 
     </xs:sequence>
 
</xs:complexType>
 
</xs:complexType>
</pre>
+
</source>
  
 
Before we start modifying our data, we must enable logging:
 
Before we start modifying our data, we must enable logging:
<pre>
+
<source lang="java">
 
customer.getChangeSummary().beginLogging();
 
customer.getChangeSummary().beginLogging();
</pre>
+
</source>
  
 
From this point on, any modifications to the DataObject will be captured in the Change Summary, until logging is deactivated:
 
From this point on, any modifications to the DataObject will be captured in the Change Summary, until logging is deactivated:
<pre>
+
<source lang="java">
 
customer.getChangeSummary().endLogging();
 
customer.getChangeSummary().endLogging();
</pre>
+
</source>
  
 
==Modifying the DataObjects==
 
==Modifying the DataObjects==
Line 102: Line 102:
 
Modifying the ShippingAddress ZipCode:
 
Modifying the ShippingAddress ZipCode:
  
<pre>
+
<source lang="java">
 
AddressType address = customer.getContactInfo().getShippingAddress();
 
AddressType address = customer.getContactInfo().getShippingAddress();
 
address.setZipCode("27601");
 
address.setZipCode("27601");
</pre>
+
</source>
  
 
Adding a new PhoneNumber:
 
Adding a new PhoneNumber:
<pre>
+
<source lang="java">
 
PhoneNumber phoneNumber =
 
PhoneNumber phoneNumber =
 
   (PhoneNumber) DataFactory.INSTANCE.create("urn:customer-example", "phone-number");
 
   (PhoneNumber) DataFactory.INSTANCE.create("urn:customer-example", "phone-number");
Line 114: Line 114:
 
phoneNumber.setValue("(613) 555-3333");
 
phoneNumber.setValue("(613) 555-3333");
 
customer.getContactInfo().getPhoneNumber().add(phoneNumber);
 
customer.getContactInfo().getPhoneNumber().add(phoneNumber);
</pre>
+
</source>
  
 
Removing all "cell" PhoneNumbers:
 
Removing all "cell" PhoneNumbers:
<pre>
+
<source lang="java">
 
ArrayList phoneNumbersToRemove = new ArrayList();
 
ArrayList phoneNumbersToRemove = new ArrayList();
 
List phoneNumbers = customer.getContactInfo().getPhoneNumber();
 
List phoneNumbers = customer.getContactInfo().getPhoneNumber();
Line 128: Line 128:
 
}
 
}
 
phoneNumbers.removeAll(phoneNumbersToRemove);
 
phoneNumbers.removeAll(phoneNumbersToRemove);
</pre>
+
</source>
  
 
==Marshalling the DataObjects==
 
==Marshalling the DataObjects==
Line 134: Line 134:
 
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.
 
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>
+
<source lang="java">
 
XMLHelper.INSTANCE.save(xmlDocument, System.out, null);
 
XMLHelper.INSTANCE.save(xmlDocument, System.out, null);
</pre>
+
</source>
  
 
==Interpreting the Change Summary==
 
==Interpreting the Change Summary==
Line 142: Line 142:
 
When the document is saved to <tt>System.out</tt>, we can see the change summary information in the XML:
 
When the document is saved to <tt>System.out</tt>, we can see the change summary information in the XML:
  
<pre>
+
<source lang="xml">
 
<ns1:customer ...>
 
<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">
+
   <changeSummary logging="false" xmlns:sdo="commonj.sdo"
 +
      create="#/ns1:contact-info/ns1:phone-number[2]"  
 +
      delete="#/changeSummary/ns1:contact-info/ns1:phone-number[2]">
 
       <ns1:contact-info sdo:ref="#/ns1:contact-info">
 
       <ns1:contact-info sdo:ref="#/ns1:contact-info">
 
         <ns1:phone-number sdo:ref="#/ns1:contact-info/ns1:phone-number[1]"/>
 
         <ns1:phone-number sdo:ref="#/ns1:contact-info/ns1:phone-number[1]"/>
Line 155: Line 157:
 
   </changeSummary>
 
   </changeSummary>
 
</ns1:customer>
 
</ns1:customer>
</pre>
+
</source>
  
 
* 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>".
 
* 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>".
Line 165: Line 167:
 
==Download==
 
==Download==
  
[http://wiki.eclipse.org/images/d/d7/Org.eclipse.persistence.example.sdo.staticapi.zip org.eclipse.persistence.example.sdo.staticapi.zip]
+
Download the "Examples Zip" from the EclipseLink [http://www.eclipse.org/eclipselink/downloads/ Downloads] page. Code for this example will be found in the <tt>org.eclipse.persistence.example.sdo.staticapi.zip</tt> file.

Latest revision as of 17:45, 11 February 2009

Overview

The following example will demonstrate how to use EclipseLink's SDO functionality to:

  • Generate Java source files from an XML Schema using the SDO Compiler
  • Define a set of SDO Types from an XML Schema
  • Load an XML file and modify its data
  • Monitor changes made to the data
  • Save the modified data to XML

Setup

  1. Ensure that you have EclipseLink correctly installed and configured for your environment. Please see EclipseLink/Installing and Configuring EclipseLink for more information.
  2. Ensure that you have ANT correctly installed and configured.
  3. Unzip the Example ZIP file to a new directory.
  4. Edit the env.properties file in the root directory of the example and specify the path to your EclipseLink jlib directory:
...
# Edit eclipselink.jlib to point to your EclipseLink jlib directory
eclipselink.jlib=C:/EclipseLink-1.0/eclipselink/jlib
...

You can compile and run the Example at any time by typing ant from the Example directory.

For Eclipse IDE users, a .project file is included in the Example directory. To setup this project in Eclipse:

  1. From the "File" menu, choose "Import..."
  2. In the Import dialog, choose "General > Existing Projects into Workspace", and click "Next".
  3. Click "Browse" to select a root directory, and point to the folder containing this example. After selecting the directory, you should see the project name in the "Projects" list. Click "Finish".

This project is configured to use a classpath variable, ECLIPSELINK_JLIB, to point to the required JAR files. After the project is imported, you should define a variable called ECLIPSELINK_JLIB to point to your EclipseLink jlib directory.

Running the SDO Compiler

The SDO compiler can be run to generate Static SDO Java files from an XML Schema:

<ECLIPSELINK_HOME>/eclipselink/bin/sdo-compiler.sh [-options]
<ECLIPSELINK_HOME>\eclipselink\bin\sdo-compiler.cmd [-options]
 
Options:
   -help                        Prints the help message text
   -sourceFile <filename>       The input schema file (required)
   -targetDirectory <dirname>   The directory to generate Java source (optional)
   -logLevel <level>            Specify the integer value of the logging level
                                (8=OFF,7=SEVERE,6=WARNING,5=INFO,4=CONFIG,3=FINE,2=FINER(default),1=FINEST,0=ALL)
Example:
   sdo-compiler.sh -sourceFile config/Customer.xsd -targetDirectory sdo-compiler-output -logLevel 8

For each complex type in the schema, the compiler will generate both an interface (e.g. CustomerType.java), and a concrete implementation which subclasses org.eclipse.persistence.sdo.SDODataObject (e.g. CustomerTypeImpl.java). For this example we will only deal with the generated interfaces.

In this example, the SDO Compiler is run from the "run.sdo.compiler" task in the ANT build file.

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.

FileInputStream xsdInputStream = new FileInputStream("Customer.xsd");
XSDHelper.INSTANCE.define(xsdInputStream, null);

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 CustomerType object and begin modifying its contents.

FileInputStream xmlInputStream = new FileInputStream("Customer-data.xml");
XMLDocument xmlDocument = XMLHelper.INSTANCE.load(xmlInputStream);
CustomerType customer = (CustomerType) xmlDocument.getRootObject();

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 "sdo:ChangeSummaryType" on our root complex type:

<xs:complexType name="customer-type">
    <xs:sequence>
        ...
        <xs:element name="changeSummary" type="sdo:ChangeSummaryType" minOccurs="0"/>
 
    </xs:sequence>
</xs:complexType>

Before we start modifying our data, we must enable logging:

customer.getChangeSummary().beginLogging();

From this point on, any modifications to the DataObject will be captured in the Change Summary, until logging is deactivated:

customer.getChangeSummary().endLogging();

Modifying the DataObjects

Below are examples of manipulating the DataObjects using the static classes. Note that there are JavaBean-type accessors on the static interfaces.

Modifying the ShippingAddress ZipCode:

AddressType address = customer.getContactInfo().getShippingAddress();
address.setZipCode("27601");

Adding a new PhoneNumber:

PhoneNumber phoneNumber =
  (PhoneNumber) DataFactory.INSTANCE.create("urn:customer-example", "phone-number");
phoneNumber.setNumberType("home");
phoneNumber.setValue("(613) 555-3333");
customer.getContactInfo().getPhoneNumber().add(phoneNumber);

Removing all "cell" PhoneNumbers:

ArrayList phoneNumbersToRemove = new ArrayList();
List phoneNumbers = customer.getContactInfo().getPhoneNumber();
Iterator it = phoneNumbers.iterator();
while (it.hasNext()) {
   PhoneNumber phoneNumber = (PhoneNumber) it.next();
   if (phoneNumber.getNumberType().equals("cell")) {
      phoneNumbersToRemove.add(phoneNumber);
   }
}
phoneNumbers.removeAll(phoneNumbersToRemove);

Marshalling the DataObjects

The following code segment demonstrates how to marshal DataObjects wrapped in a commonj.sdo.helper.XMLDocument back to XML. In this example the stream we are saving to is System.out, so the XML text will be printed to the console.

XMLHelper.INSTANCE.save(xmlDocument, System.out, null);

Interpreting the Change Summary

When the document is saved to System.out, we can see the change summary information in the XML:

<ns1:customer ...>
   ...
   <changeSummary logging="false" xmlns:sdo="commonj.sdo"
      create="#/ns1:contact-info/ns1:phone-number[2]" 
      delete="#/changeSummary/ns1:contact-info/ns1:phone-number[2]">
      <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>
  • 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.  In our example, we see a "shipping-address" element which references "#/ns1:contact-info/shipping-address" (the element that was modified), along with its old value, "12345".
  • DataObjects which are currently in the data graph, but were not present when logging was started are indicated in the change summary with a "create" 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 "create" attribute indicating that "#/ns1:contact-info/ns1:phone-number\[2\]" (the second phone number in the XML) is the newly created one.
  • DataObjects deleted during logging are flagged with the "delete" 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 "delete" attribute indicating that "#/changeSummary/ns1:contact-info/ns1:phone-number\[2\]" (the second phone number in the Change Summary) is the one that was deleted from the XML.

Download

Download the "Examples Zip" from the EclipseLink Downloads page. Code for this example will be found in the org.eclipse.persistence.example.sdo.staticapi.zip file.

Back to the top