Java SDO Overview Java SDO Overview Kelvin Goodson sdo

The Tuscany SDO Java Project

This document proves a high-level overview of the Java SDO (Service Data Objects) subproject of the Apache Tuscany incubator project.

To get started with Java SDO, follow the downloads link and pick up either a binary or source distribution. If you are working from a source distribution, you can follow the general instructions for building the whole of the Tuscany java projects, or you can follow the intructions within the SDO Java overview to build and explore just SDO java.

SDO Java Documents

SDO Specification for Java V2.01 The Service Data Objects specification for Java. Describes the data programming interfaces of SDO in the Java language.
SDO White Paper A white paper that explains the SDO programming model

The SDO Java project is a subproject of the Apache Tuscany incubator project is intended to provide a Java implementation of the SDO 2 specification.

The project's code base includes the following:

The Tuscany wiki contains an area for raw thoughts and clarifications on SDO that will eventually make it into well crafted documentation.

Build Environment Setup

Tuscany Build Environment Setup

SDO 2 is a subproject of the Tuscany project. If you check out and build the whole Tuscany Java project, you will have also built the SDO 2 subproject. If you want to work with the SDO 2 project, without the rest of Tuscany, skip to the next section.

To build the whole Tuscany project follow these instructions.

SDO Java Build Environment Setup

There are two motivations for building SDO from source and two well tested approches to doing so. You may be wanting to build a binary release distribution from source code. Alternatively you may be wishing to establish a development environment in order to futher the development of the code. The two tested approaches are either to use maven 2 commandline builds or to java source code create projects in the Eclipse SDK.

If you simply want to create a source code distribution, then even if you are an Eclipse user its best to just follow the instructions in the BUILDING.txt file at the top of the source code distribution and run a maven command line build (since the route to establishing an Eclipse environment requires installing maven anyway). Note that SDO for Java is distributed as two source code distributions. You'll need to download two archives, one for the SDO API, and one for the Tuscany implementation of that API.

If you want to work with the SDO projects alone, without the rest of Tuscany, proceed with the following steps.

  1. Set up your environment using the instructions for building the whole of Tuscany, but only download and install Java 5, Maven and Svn (note that only one file, Interface2JavaGenerator.java, has a Java 5 dependency, if you want to work with Java 1.4.2 then just delete this file before building).

  2. Make sure 'mvn' and 'svn' commands are in your PATH environment variable.

  3. Check out the SDO open source projects from Apache.

  1. Run "mvn" under <local tuscany dir>/java directory to install POM files from the root project to the local repository

  1. Build, or rebuild, the individual SDO projects

    • sdo.spec project

      Commands:

      • cd <local tuscany dir>/java/spec/sdo-api
        mvn
        mvn -Peclipse eclipse:eclipse (optional: Run this command if you are using Eclipse for development.)

      sdo.impl project

      Commands:

      • cd <local tuscany dir>/java/sdo/impl
        mvn
        mvn -Peclipse eclipse:eclipse (optional: Run this command if you are using Eclipse for development.)

      sdo.tools project

      Commands:

      • cd <local tuscany dir>/java/sdo/tools
        mvn
        mvn -Peclipse eclipse:eclipse (optional: Run this command if you are using Eclipse for development.)

      sdo.samples project

      Commands:

      • cd <local tuscany dir>/java/sdo/sample
        mvn
        mvn -Peclipse eclipse:eclipse (optional: Run this command if you are using Eclipse for development.)

SDO Project Structure

The SDO project is divided into five parts:

  1. sdo.spec contains the SDO (commonj) interfaces defined and provided by the SDO 2 specification.

  2. sdo.impl provides the runtime implementation of the SDO interfaces.

  3. sdo.tools contains import and generator tools.

  4. sdo.sample contains sample sdo code.

  5. sdo.plugin contains code to configure the way in which SDO is build by maven.

The main source code in each of these subprojects is located in the directory src/main/java, and if applicable, test (example) classes are located in src/test/java. The directory src/test/resources contains any data files needed by the test programs.

sdo.spec

( https://svn.apache.org/repos/asf/incubator/tuscany/java/spec/sdo-api)

This project contains the interfaces provided with the SDO 2 specification. It is essentially an unzipped copy of the SDO Java API sources zip file available at http://ftpna2.bea.com/pub/downloads/SDO_20_Source.zip, but with some errata corrections and a Tuscany-specific implementation of class HelperProvider.

The abstract class, HelperProvider, is used to obtain specific default helpers and other implementation-specific objects used by the Java implementation of SDO. In the Tuscany implementation of this class, there are two ways to specify the implementation of the HelperProvider class.

  1. Set a System Property named "commonj.sdo.impl.HelperProvider" equal to the fully qualified class name of the implementation class (e.g. "commonj.sdo.impl.HelperProvider=org.apache.tuscany.sdo.help.HelperProviderImpl").

  2. In your own jar file, create a text file called "META-INF/services/commonj.sdo.impl.HelperProvider". In this text file, specify the fully qualified custom HelperProvider implementation class (e.g. org.apache.tuscany.sdo.help.HelperProviderImpl).

In the event that both 1 and 2 are specified, the System Property will take precedence over the text file.

The Tuscany default helper provider implementation class is org.apache.tuscany.sdo.helper.HelperProviderImpl (in the sdo.impl project) and is registered using the second technique (services file), as described in the following section.

sdo.impl

( https://svn.apache.org/repos/asf/incubator/tuscany/java/sdo/impl)

The sdo.impl subproject contains a test package under src/test/java (see the section below entitled Static Code Generator for details) and the following implementation packages under src/main/java:

package org.apache.tuscany.sdo

package org.apache.tuscany.sdo.helper

package org.apache.tuscany.sdo.impl

package org.apache.tuscany.sdo.util

sdo.tools

This project will contain (command line) tools, such as SDO model importers and generators (Java code, XML schema, etc.). Currently however, there is only a single tool, a Java code generator implemented in class org.apache.tuscany.sdo.generate.XSD2JavaGenerator. This generator can be used to generate static SDO data objects and is described in more detail in below.

The sdo.tools project also contains a test program and sample generated model located in src/test/java and src/test/resources respectively (see the tests section below for more details).

Dependency Jars

The sdo.impl project requires the following EMF (Eclipse Modeling Framework - www.eclipse.org/emf) runtime jars to build:

The sdo.tools project also requires the EMF code generator framework jars:

These are simply Maven-friendly versions of corresponding jar files/plugins obtained from Eclipse. SNAPSHOT maps to an EMF weekly integration build (for example, I200602160000). Note that if you are building SDO for a released source code distribution then the dependency jars will not be snapshot jars, but will instead themselves be released versions of the dependencies.

Runtime Implementation

The primary SDO runtime implementation classes are located in the package org.apache.tuscany.sdo.impl and consist of the following:

  1. DataObject implementation classes

  2. Implementation of the SDO metamodel interfaces: Type and Property

  3. ChangeSummary and DataGraph implementations

The implementation of the SDO runtime is based on and leverages the EMF runtime model (i.e., EObject and the Ecore metamodel - refer to documentation at www.eclipse.org/emf). It subclasses and specializes the Ecore metamodel, and provides its own DataObject-tuned implementation(s) of the EObject interface. The design is described in more detail in the following sections.

DataObject implementation classes

SDO provides several DataObject implementation classes as shown in the following diagram:

do_uml.png

Class DataObjectImpl is the most important. It provides a complete base implementation of the SDO DataObject interface. It extends from the EMF base class BasicEObjectImpl, which provides the "scaffolding" needed to easily implement an EObject, but without allocating any storage itself.

DataObjectImpl provides the DataObject implementation while allocating only the minimum storage overhead needed to be a data object (e.g., container pointer and feature, change recorder). It does not, however, allocate any storage for the actual properties of the data object. It instead requires subclasses for this purpose. For example, statically generated SDOs (see the generator section below) directly or indirectly extend from this class, providing their own storage in generated instance variables.

The subclass, DynamicDataObjectImpl serves as a concrete implementation class for dynamic data objects. It is the default implementation class used when creating dynamic data objects using the DataFactory.create() method, for example. DynamicDataObjectImpl provides efficient data storage using a dynamically allocated settings array.

StoreDataObjectImpl and DynamicStoreDataObjectImpl provide a delegating implementations for DataObjects that implement their own storage management using a store (see EMF's EStore interface) implementation class. StoreDataObjectImpl is used in conjuction with the "-storePattern" generator option (see section 4), while DynamicStoreDataObjectImpl, as its name implies, is used for dynamic store-based instances.

Type and Property implementation classes

The SDO implementation provides three implementations of the interface Type, one for each of the following three kinds of types: classes, simple data types, and enumerations.

  1. class ClassImpl extends EClassImpl implements Type

  2. class DataTypeImpl extends EDataTypeImpl implements Type

  3. class EnumImpl extends EEnumImpl implements Type

For example, class org.apache.tuscany.sdo.impl.ClassImpl extends form the corresponding Ecore class, EClassImpl, and mixes in the SDO interface commonj.sdo.Type. All the Type methods are implemented by calls to super.

With this approach, a data object's Type, returned from DataObjectImpl.getType(), and its EClass, returned by DataObjectImpl.eClass(), are the same underlying meta object. This allows the SDO implementation to leverage any appropriate base functionality without any performance overhead. The arrangement is shown in the following diagram:

meta.png

The implementation of the SDO Property interface follows a similar pattern. Two implementation classes, subclasses of corresponding Ecore classes, mix in the Property interface:

  1. class AttributeImpl extends EAttributeImpl implements Property

  2. class ReferenceImpl extends EReferenceImpl implements Property

As with the Type implementation classes, these classes call methods on super to implement the mixed-in Property methods.

The following diagram illustrates the design:

meta2.png

As shown, the getProperties() method in ClassImpl (i.e., of the SDO Type interface) returns a set of properties whose implementation classes also implement EAttribute or EReference, and since ClassImpl, extends EClassImpl (as shown in the previous diagram), these are in fact the same objects as those returned by the EClass.getEAllStructuralFeatures() method. The two metamodels are one and the same, making the implementation of many of the SDO APIs trivial calls to the base class.

ChangeSummary and DataGraph implementation classes

TBD.

Static Code Generator

The SDO static code generator is a command line tool for generating Java source code (static SDOs) for DataObjects defined in an XML Schema. It is implemented by the class org.apache.tuscany.sdo.generate.XSD2JavaGenerator in the sdo.tools project. The generator is used as follows:

Usage arguments:

 [ -targetDirectory <target-root-directory> ]
 [ -javaPackage <base-package-name> ]
 [ -prefix <prefix-string> ]
 [ -sparsePattern | -storePattern ]
 [ -noInterfaces ] [ -noContainment ] [ -noNotification ] [ -arrayAccessors ] [ -noUnsettable ] [-noEMF] 
 <xsd-file> | <wsdl-file>

For example:

java XSD2JavaGenerator somedir/somefile.xsd

Options:

Generator Patterns

The DataObject interface generation pattern is as described in the SDO specification (see Java Interface Specification section). The SDO specification does not define a factory pattern for efficient construction of static SDOs, which is however provided by the Tuscany implementation. The generated SDO Factory interface conforms to the following pattern:

public interface <prefix>Factory {
  <Type1> create<Type1>();
  <Type2> create<Type2>();
  ...
  <prefix>Factory INSTANCE = <default_factory_impl>;
}

A generated factory corresponds to an SDO Type namespace uri (see commonj.sdo.Type.getURI) with one create() method for each SDO Type in the namespace. The <prefix> of the factory name is derived from the uri. An instance of the factory is available using the INSTANCE field in the interface.

Using the static factory, a DataObject might be created as follows:

Quote aQuote = StockFactory.INSTANCE.createQuote();
... // do something with aQuote

The generated implementation of each create() method simply constructs an instance of the corresponding type like this:

  public Quote createQuote() {
    QuoteImpl quote = new QuoteImpl();
    return quote;
  }

In addition to these generated type-specific create<Type>() methods, the generated factory implementation class also includes a generated reflective create() method that, given an SDO Type, efficiently dispatches to the correct type-specific create() method. The reflective create() method is called by the implementation of the SDO commonj.sdo.helper.DataFactory interface.

Test/Example Programs

The SDO project does not include any proper sample programs at this time (any volunteers?) but it does include a number of JUnit test cases, some of which serve as good examples of how to use SDO APIs to perform various tasks.

The following tests are particularly good SDO examples included in the sdo.impl project:

The following is in the sdo.tools project: