Client Application Developer's Guide

     Previous  Next    Open TOC in new window    View as PDF - New Window  Get Adobe Reader - New Window
Content starts here

Data Programming Model and Update Framework

BEA AquaLogic Data Services Platform implements the Service Data Objects (SDOs) as its data client-application programming model. SDO is an architecture and set of APIs for working with data objects while disconnected from their source. In AquaLogic Data Services Platform, SDOs — whether typed or untyped data objects — are obtained from data services through Mediator APIs or through Data Service controls. (See Introducing Service Data Objects (SDO).)

Client applications manipulate the data objects as required for the business process at hand, and then submit changed objects to the data service, for propagation to the underlying data sources. Although the SDO specification does not define one, it does discuss the need for mediator services, in general, that can send and receive SDOs; the specification also discusses the need for handling updates to data sources, again, without specifying an implementation: The SDO specification leaves the details up to implementors as to how mediator services are implemented, and how they should handle updates to data objects.

As discussed in Update Frameworks and the Data Service Mediator, AquaLogic Data Services Platform's Mediator is the process that not only handles the back-and-forth communication between client applications and data services, it also facilitates updates to the various data sources that comprise any data service.

This chapter includes information about AquaLogic Data Services Platform's implementation of the SDO data programming model, as well as its update framework.

 


Data Services Platform and Service Data Objects (SDOs)

When you invoke a data service's read or navigation function (through the Data Service Mediator API or from a Data Service control), the data service returns a data graph comprising one or more data objects. Data objects and data graphs are two fundamental artifacts of the SDO data programming model. As shown in Figure 2-1, a data graph comprises:

Each of these can be described in more detail, as follows:

Table 2-2 summarizes the various SDO data programming artifacts and lists an example of each (as shown in Figure 2-1).

Table 2-2 Data Graph Artifacts and Examples
Data Graph and Related Artifacts
Example
DataGraph
CUSTOMERDataGraph
DataObject
CUSTOMER0, ORDERS
Root Object
CUSTOMERDocument
ChangeSummary
CHANGESUMMARY
Property
CUSTOMERID, LAST_NAME
Simple Type
CUSTOMERID
Complex Type
ORDERS
Metadata
<CUSTOMER>
<LAST_NAME></LAST_NAME>
<EMAIL_ADDRESS/>
</CUSTOMER>

Static and Dynamic Data APIs

SDO specifies both static (typed) and dynamic (untyped) interfaces for data objects:

The dynamic data API can be used with data types that have not yet been deployed at development time.

Table 2-3 summarizes the advantages of each approach.

Table 2-3 Static and Dynamic Data APIs
Data Model
Advantages...
Static Data API
  • Easy-to-implement interface; code is easy to read and maintain.
  • Compile-time type checking.
  • Enables code-completion in BEA WebLogic Workshop Source View.
Dynamic data API
  • Dynamic; allows discovery.
  • Runtime type checking.
  • Allows for a general-purpose coding style.

Static Data API

SDO's static data API is a typed Java interface generated from a data service's XML schema definition. It is similar to JAXB or XMLBean static interfaces. The interface files, packaged in a JAR, are typically generated by the data service developer using WebLogic Workshop, or by using one of the provided tools (see Developing Static Web Service Clients for more information).

The generated interfaces extend both the dynamic data API (specifically, the DataObject interface) and the XmlObject interface. Thus, the generated interfaces provide typed getters and setters for all properties of the XML datatype.

An interface is also generated for each complex property (such as CREDIT and ORDER shown in Figure 2-4), with getters and setters for each of the properties that comprise the complex type.

In addition, for properties that may have multiple occurrences, getters and setters are also generated for manipulating arrays and array elements. A multiple-occurring property is an XML schema element that has its maxOccurs attribute set to either unbounded or greater than one. In the DSP Console Metadata Browser, such elements are flagged with an asterisk—for example, ORDER* and POITEM* (see Figure 2-4) indicate that an array or order data objects (ORDERS[ ]) will be returned. For results involving repeating objects, you can cast the root element to an array of returned objects (datatypename[])

Note: In prior releases of Data Services Platform, an "ArrayOf..." schema element was created to serve as a container for array types returned as part of a Data Graph. Some references to the ArrayOf mechanism may remain in code samples and documentation.

As an example of how static data APIs get generated, given the CUSTOMER data type shown in Figure 2-4, generating typed client interfaces results in:

When you develop Java client applications that use SDO's static data APIs, you will import these XMLBeans-generated typed interfaces into your Java client code. For example:

import appDataServices.AddressDocument;

The SDO API interfaces use XMLBeans for object serialization and deserialization. As a client application developer, you rarely need to know such details. However, developers who are integrating AquaLogic Data Services Platform with WebLogic Integration workflow components (JPDs, or Java process definitions) will need to modify the default serialization-deserialization in their JPD code that uses data objects. For more information, see Using Workflow with AquaLogic Data Services Platform-Based Applications.

Since AquaLogic Data Services Platform uses XMLBeans, many features of the underlying XMLBeans technology are available in SDO as well. For example, DataObjects can be cast to Strings using the XmlObjects toString( ) method, for printing to output.

Table 2-5 lists static data API getters and setters.

Table 2-5 Static (Typed) Data API Getters and Setters
Static Data API (Generated)
Description
Examples
Type getPropertyName()
Returns the value of the property. A static getPropertyName( ) method is generated for each attribute or element that has a single occurrence.
getCUSTOMER(),
getCUSTOMERNAME(), getCREDITRATING(), getCREDITSCORE()
Type[] getPropertyNameArray()
For multiple occurrence elements, returns all PropertyName elements.
getCREDITArray()
Type getPropertyNameArray( int PropertyIndex)
Returns the PropertyName child element at the specified index.
getCREDITArray(int),
setCREDITSCORE(int)
void setPropertyName(Type newValue)
Sets the value of the property to the newValue. Generated when PropertyName is an attribute or an element with single occurrence.
setCUSTOMER(CUSTOMER),
setCUSTOMERNAME(String), setCREDITRATING(String)
void setPropertyNameArray( Type[] newValue)
Sets all PropertyName elements.
setCREDITArray(CREDIT[])
void setPropertyNameArray( Type newValue, int PropertyIndex)
Sets the PropertyName child element at the specified index.
setCREDITArray(int, CREDIT)
boolean isSetPropertyName()
Determines whether the PropertyName element or attribute exists in the document. Generated for optional elements and attributes. (An optional element has a minOccurs attribute set to 0; an optional attribute has a use attribute set to optional.)
isSetCustomerStreetAddress2()
void insertPropertyName(int index, PropertyNameType newValue)
Inserts the specified PropertyName child element at the specified index.
insertNewCREDIT(int)
int sizeOfPropertyNameArray()
Returns the current number of property child elements.
sizeOfCREDITArray()
void unSetPropertyName()
Removes the element or attribute of PropertyName from the document. Generated for elements and attributes that are optional. In schema, and optional element has an minOccurs attribute set to 0; an optional attribute has a use attribute set to optional.
unSetCustomerStreetAddress2()
void removePropertyName(int PropertyIndex)
Removes the PropertyName child element at the specified index.
removeCREDIT(int)
void addPropertyName( PropertyNameType newValue)
Adds the specified PropertyName to the end of the list of PropertyName child elements.
addNewCREDIT(),
addNewCUSTOMER()
boolean isSetPropertyNameArray(int PropertyIndex)
Determines whether the PropertyName element at the specified index is null.
isSetCustomerArray(3)
void unsetPropertyNameArray( int PropertyIndex)
Sets the value of PropertyName element at the specified index to null.

Note: After you call unset and then call set, the return value is false.

unSetCustomerArray(3)

XML Schema-to-Java Type Mapping Reference

AquaLogic Data Services Platform client application developers can use the Data Services Platform Console to view the XML schema types associated with data services (see Figure 2-4, CUSTOMER Return Type Displayed in DSP Console's Metadata Browser, on page 2-6). The Return Type tab indicates the data type of each element—string, int, or complex type, for example. The XML schema data types are mapped to data objects in Java using the data type mappings shown in Table 2-6.

Table 2-6 XML Schema to Java Data Type Mapping 
XML Schema Type
SDO Java Type
XML Schema Type
SDO Java Type
xs:anyType
commonj.sdo.DataObject
xs:integer
java.math.BigInteger
xs:anySimpleType
String
xs:language
String
xs:anyURI
String
xs:long
long
xs:base64Binary
byte[]
xs:Name
String
xs:boolean
boolean
xs:NCName
String
xs:byte
byte
xs:negativeInteger
java.math.BigInteger
xs:date
java.util.Calendar (Date)
xs:NMTOKEN
String
xs:dateTime
java.util.Calendar
xs:NMTOKENS
String
xs:decimal
java.math.BigDecimal
xs:nonNegativeInteger
java.math.BigInteger
xs:double
double
xs:nonPositiveInteger
java.math.BigInteger
xs:duration
String
xs:normalizedString
String
xs:ENTITIES
String
xs:NOTATION
String
xs:ENTITY
String
xs:positiveInteger
java.math.BigInteger
xs:float
float
xs:QName
javax.xml.namespace.QName
xs:gDay
java.util.Calendar
xs:short
short
xs:gMonth
java.util.Calendar
xs:string
String
xs:gMonthDay
java.util.Calendar
xs:time
java.util.Calendar
xs:gYear
java.util.Calendar
xs:token
String
xs:gYearMonth
java.util.Calendar
xs:unsignedByte
short
xs:hexBinary
byte[]
xs:unsignedInt
long
xs:ID
String
xs:unsignedLong
java.math.BigInteger
xs:IDREF
String
xs:unsignedShort
Int
xs:IDREFS
String
xs:keyref
String
xs:int
int
   

Dynamic Data API

The dynamic data API has generic property getters and setters, such as set( ) and get( ), as well as getters and setters for specific Java data types (String, Date, List, BigInteger, and BigDecimal, for example). Table 2-7 lists representative APIs from SDO's dynamic data API. The propertyName argument indicates the name of the property whose value you want to get or set; propertyValue is the new value. The dynamic data API also includes methods for setting and getting a DataObject's property by indexValue. This includes methods for getting and setting properties as primitive types, which include setInt( ), setDate( ), getString( ), and so on.

Unlike the static data API, which eliminates underscores in method names generated from types that might include such characters ("LAST_NAME" results in a getLASTNAME( ) method, for example), the dynamic data API requires that field names be referenced precisely, as in get("LAST_NAME"). As an example, assuming that you have a reference to a CUSTOMER data object, you can use the dynamic data API to get the LAST_NAME property as follows:

String lastName = (String) customer.get("LAST_NAME");

For a complete reference of the dynamic data API, see the AquaLogic Data Services Platform Javadoc ( AquaLogic Data Services Platform Mediator API Javadoc on page 1-13). For documentation on the SDO 1.0 API see the DataObject interface in the commonj.sdo package. It is available at:


http://dev2dev.bea.com/technologies/commonj/sdo/index.jsp

Table 2-7 lists dynamic data API getters and setters.

Table 2-7 Dynamic (Untyped) Data API Getters and Setters
Dynamic Data API
Description
Example
get(int PropertyIndex)
Returns the PropertyName child element at the specified index.
get(5)
set(int PropertyIndex, Object newValue)
Sets the value of the property to the newValue.
set(5, CUSTOMER3)
set(String PropertyName, Object newValue)
Sets the value of the PropertyName to the newValue.
set("LAST_NAME", "Nimble")
set(commonj.sdo.Property PropertyName, Object newValue)
Sets the value of PropertyName to the NewValue
set(LASTNAME, "Nimble")
getType(String PropertyName)
Returns the value of the PropertyName. Type indicates the specific data type to obtain.
getBigDecimal("CreditScore")
unset(int PropertyIndex)
Sets the value of PropertyName element at the specified index to null.
unset(5)
unset(commonj.sdo.Property PropertyName)
Sets the value of the specified PropertyName to null.
unset(LASTNAME)
unset(String PropertyName)
Sets the value of the specified PropertyName to null.
unset("LAST_NAME")
createDataObject(commonj.sdo.Property PropertyName)
Returns a new DataObject for the specified containment property.
createDataObject(LASTNAME)
createDataObject(String PropertyName)
Returns a new DataObject for the specified containment property.
createDataObject("LAST_NAME")
createDataObject(int PropertyIndex)
Returns a new DataObject for the specified containment property.
createDataObject(5)
createDataObject(String PropertyName, String namespaceURI, String typeName)
Returns a new DataObject for the specified containment property.
createDataObject("LAST_NAME","http://namespaceURI_here", "String")
delete()
Removes the object from its container and unsets all writeable properties.
delete(CUSTOMER)

XPath Support in the Dynamic Data API

One of the benefits of AquaLogic Data Services Platform's use of XMLBeans technology is support for XPath in the dynamic data API. XPath expressions give you a great deal of flexibility in how you locate data objects and attributes in the dynamic data API's accessors. For example, you can filter the results of a get( ) method invocation based on data elements and values:

	company.get("CUSTOMER[1]/POITEMS/ORDER[ORDERID=3546353]")

The SDO implementation goes beyond basic XPath 1.0 support by adding zero-based array index notation (".index_from_0") to XPath's standard bracketed notation ([n]). As an example, Table 2-8 compares the XPath standard and SDO augmented notations to refer to the same element, the first ORDER child node under CUSTOMER (Table 2-8).

Table 2-8 XPath Standard and SDO Augmented Notation
XPath Standard Notation
SDO Augmented Notation
get("CUSTOMER/ORDER[1]");
get("CUSTOMER/ORDER.0");

Zero-based indexing is convenient for Java programmers who are accustomed to zero-based counters, and may want to use counter values as index values without adding 1.

AquaLogic Data Services Platform fully supports both the traditional index notation and the augmented notation. However, note that the SDO pre-processor transparently replaces the zero-based form with one-based forms, to avoid conflicts with elements whose names include dot numbers, such as <myAcct.12>.

Keep in mind these other points regarding AquaLogic Data Services Platform's XPath support:

Note: For more examples of using XPath expressions with SDOs, see Step 2: Accessing Data Object Properties.
Obtaining Type Information about Data Objects

The dynamic data API returns generic data objects. To obtain information about the properties of a data object, you can use methods available in SDO's Type interface. The Type interface (located in the commonj.sdo package) provides several methods for obtaining information, at runtime, about data objects, including a data object's type, its properties, and their respective types.

According to the SDO specification, the Type interface (see Table 2-9) and the Property interface (see Table 2-10) comprise a minimal metadata API that can be used for introspecting the model of data objects. For example, the following obtains a data object's type and prints a property's value:

DataObject o = ...; 
Type type = o.getType();
if (type.getName().equals("CUSTOMER") {
System.out.println(o.getString("CUSTOMERNAME")); }

Once you have an object's data type, you can obtain all its properties (as a list) and access their values using the Type interface's get Properties() method, as shown in Listing 2-1.

Listing 2-1 Using SDO's Type Interface to Obtain Data Object Properties
public void printDataObject(DataObject dataObject, int indent) {
Type type = dataObject.getType();
List properties = type.getProperties();
for (int p=0, size=properties.size(); p < size; p++) {
if (dataObject.isSet(p)) {
Property property = (Property) properties.get(p);
// For many-valued properties, process a list of values
if (property.isMany()) {
List values = dataObject.getList(p);
for (int v=0; count=values.size(); v < count; v++) {
printValue(values.get(v), property, indent);
}
else { // Forsingle-valued properties, print out the value
printValue(dataObject.get(p), property, indent);
}
}
}
}

Table 2-9 lists other useful methods in the Type interface.

Table 2-9 Type Interface Methods
Method
Description
java.lang.Class getInstanceClass()
Returns the Java class that this type represents.
java.lang.String getName()
Returns the name of the type.
java.lang.List getProperties
Returns a list of the properties of this type.
Property getProperty(
java.lang.String propertyName)
Returns from among all Property objects of the specified type the one with the specified name. For example, dataObject.get("name") or dataObject.get(dataObject.getType().getProperty("name"))
java.lang.String getURI()
Returns the namespace URI of the type.
boolean isInstance(
java.lang.Object object)
Returns True if the specified object is an instance of this type; otherwise, returns false.

Table 2-10 lists the methods of the Property interface.

Table 2-10 Property Interface Methods
Method
Description
Type getContainingType()
Returns the containing type of this property.
java.lang.Object getDefault()
Returns the default value this property will have in a data object where the property hasn't been set
java.lang.String getName()
Returns the name of the property.
Type getType()
Returns the type of the property.
boolean isContainment()
Returns True if the property represents by-value composition.
boolean isMany()
Returns True if the property is many-valued.

Role of the Mediator and SDOs

In AquaLogic Data Services Platform, data graphs are passed between data services and client applications: when a client application invokes a read function on a data service, for example, a data graph is sent to the client application. The client application modifies the content as appropriate—adds an order to a customer order, for example—and then submits the changed data graph to the data service. The Data Service Mediator is the process that receives the updated data objects and propagates changes to the underlying data sources.

The Data Service Mediator is the linchpin of the update process. It uses information from submitted SDOs (change summary, for example) in conjunction with other artifacts to derive an update plan for changing underlying data sources. For relational data sources, updates are automatic. The artifacts that comprise AquaLogic Data Services Platform's update framework, including the Mediator, and how the default update process works, are described in more detail in the Building Queries and Data Views Handling Updates Through Data Services chapter.


  Back to Top       Previous  Next