SDO data binding for SCA applications
Service Data Objects (SDO) is a framework for data application development that provides an architecture and APIs. Product support for Service Component Architecture (SCA) includes an implementation of SDO 2.1.1 interfaces. To work with SDO in SCA Java clients and implementations, it is helpful to understand SDO data binding concepts.
The product supports SDO for both OSOA and OASIS specifications, unless otherwise stated in this topic.
The SDO data binding support consists of the following concepts:
- Scope management
- Wire format serialization or deserialization
- Top-down and bottom-up development
- Schema registration
- Shared scopes
- JAX-WS based programming model
Scope management
In SDO, a scope typically corresponds to a commonj.sdo.helper.HelperContext instance. This scope sets visibility boundaries for SDO types. In the product runtime environment, the SCA layer defines HelperContext objects on SCA application boundaries, which are meaningful boundaries from an SCA perspective. Together, SCA and SDO define a default HelperContext for a given application and enable the SCA application to access the HelperContext programmatically.
In the product runtime environment, the primary SCA application scope is tied to the deployable composite. There is a 1-1 relationship between a deployable composite and an SCA default HelperContext that is managed in the runtime environment. To determine the default HelperContext of an SCA component, you must identify the deployable composite which defines this component to the SCA domain.
Wire format serialization or deserialization
An important use of SDO is to serialize or deserialize application data to and from the data format "on the wire" (the "wire format") for the various binding configurations. The SCA runtime environment uses the default HelperContext with its registered schema definitions to perform this serialization or deserialization. This process is relevant for serializing or deserializing input argument values and return values of SCA service interfaces when the client or implementation uses the SDO data binding.
Top-down and bottom-up development
Both top-down (starting from WSDL and XSD files) and bottom-up (starting from Java files) approaches can be used with SDO in SCA applications. This section briefly explains three different usage patterns. We can combine aspects of all three patterns in a single application.
- Top-down, strongly typed
In this usage pattern, start with a composite definition file that uses the <interface.wsdl> element in describing a component service interface; for example:
<service > <interface.wsdl > Refers to WSDL with updateAccountThe doc-lit-wrapped WSDL and XSD definition uses a specific type, and not xsd:anyType:
<element name="updateAccount"> <complexType> <sequence> <element name="person" type="p:Person"/>This definition maps to a Java method; for example:
void updateAccount(DataObject person)
With this usage pattern, we can write the Java code so that is reusable, even later with types other than p:Person. We can potentially reuse the same dynamically typed Java code with multiple strongly typed interfaces, without having to regenerate any Java code.
We can also write the Java code so that the SDO usage is tightly coupled with a specific XSD type. Further, we can mix the tightly coupled and dynamically typed programming styles in the same SCA Java application.
- Top-down, weakly typed
In this usage pattern, start with a composite definition file that uses the <interface.wsdl> element; for example:
<service > <interface.wsdl > Refers to WSDL with updateAccountThe doc-lit-wrapped WSDL and XSD definition uses xsd:anyType:
<element name="updateAccount"> <complexType> <sequence> <element name="arg0" type="xsd:anyType"/>This definition maps to a Java method; for example:
void updateAccount(DataObject arg0)
This usage pattern is like top-down, strongly-typed. With the top-down, weakly typed usage pattern both WSDL and XSD files map to equivalent Java code. However, you might write the Java code to enable it to handle any type of data, as opposed to the top-down, strongly-typed usage pattern where you expect a specific type, even though you work with it through the dynamic SDO APIs.
- Bottom-up
In this usage pattern, you start with a Java interface method such as:
void updateAccount(DataObject arg0)
The method maps to a WSDL or XSD definition such as:
<element name="updateAccount"> <complexType> <sequence> <element name="arg0" type="xsd:anyType"/>Depending on the bindings, you might view or work directly with the WSDL and XSD files to which the Java object maps. When mapping from Java to XSD, the SCA runtime environment maps commonj.sdo.DataObject to xsd:anyType.
We cannot use java.lang.Object as a dynamic, generic interface method parameter or return type, instead of commonj.sdo.DataObject. The SCA runtime environment relies on introspection of the method type to signal that it uses SDO, and not JAXB, to work with this type; for example, to construct the argument values upon deserializing data on the wire.
In each of the usage patterns, we can mix styles within a single operation. For example, suppose we have the following doc-lit-wrapped WSDL definition:
<element name="updateAccount"> <complexType> <sequence> <element name="arg0" type="xsd:anyType"/> <element name="id" type="xsd:string"/>The WSDL definition maps to the following Java method:
void updateAccount(DataObject arg0, String id)
The arg0 field is dynamically typed by DataObject, while the id field is statically typed by String.
Schema registration
The SCA runtime environment provides mechanisms to register schema definitions from the SCA application (for example, in WSDL and XSD files packaged with the application) to the default HelperContext of the SCA application. All schema definitions packaged within the same contribution JAR file as the one the deployable composite is contributed within are registered with the default HelperContext of that deployable composite.
Schema registration is important because it affects the exact details of the application SDO programming model. For example, the DataFactory.create() methods can be used to create DataObject instances of the corresponding schema definitions that are registered in the runtime environment, without having to reference or load the XSD files containing these schema definitions in application code.
Some styles of interface definition and programming result in DataObject instances of unknown type. Within the SDO type system, the XSD type of such an object is the SDO-equivalent of xsd:anyType. Methods might return different values depending on whether the instance is of a known, specific type or the anyType-equivalent.
For example, SDO API calls such as the following might return different results depending on whether the object instances are recognized in the SDO type system as instances of a registered XSD type. For the following call, get(int propertyIndex) returns a List for xsd:anyType:
dataObjectInstance.get(1);
The following call returns an empty List for xsd:anyType:
dataObjectInstance.getType().getDeclaredProperties();
Shared scopes
Shared scopes are only supported for applications based on OSOA specifications.
SCA contribution support enables convenient packaging of WSDL and XSD definition files used by multiple SCA application composites using the contribution import and export mechanism. The common WSDL and XSD files can be packaged into a single contribution JAR file, which is like a shared library.
The SDO data binding function further uses the SCA contribution support by enabling you to establish a shared scope (HelperContext) for your SDO types. This reduces the memory footprint involved in loading schema definitions from large WSDL and XSD files used across the application and in constructing the corresponding SDO Type definitions from them.
The shared scope is maintained at the level of a business-level application. For any business-level application, all references to an SDO Type that correspond to a schema definition from an XSD or WSDL file imported from a shared contribution resolve to a single SDO Type instance in a single scope (HelperContext).
For shared scopes, there are two restrictions:
- A contribution that exports schema definitions cannot, in turn, import other schema definitions from another contribution.
- We cannot divide namespaces across more than one contribution. That is, we cannot package schema definitions in a given target namespace in one contribution and then import others in that same target namespace from a second contribution.
JAX-WS based programming model
In the product, the mapping between a WSDL operation and Java method is defined by JAX-WS. Within that operation-level mapping, it is the mapping between specific XSD types and the corresponding Java parameter types defined by the particular data binding (SDO in this case, rather than JAXB). Other than the type mapping, the programming model is independent of the choice of data binding.
One consequence of this capability is that the JAX-WS annotations such as @RequestWrapper, @ResponseWrapper, @WebParam, @WebResult are significant in SCA applications using SDO.
Another important consequence is that the product uses JAX-WS to define the mapping between a Java exception that occurs in Java clients and implementations, and the fault bean that is serialized on the wire. Thus, the fault bean can be an SDO (of type commonj.sdo.DataObject). In which case, SDO is used to serialize or deserialize the fault bean to or from the wire format.
Related concepts
Data access with Service DataObjects, API versions 1.0 and 2.01
Related tasks
Use business exceptions with SCA interfaces Use SDO 2.1.1 in SCA applications Create and accessing SDO HelperContext objects
Related information:
JSR 235: Service Data Objects OASIS Service Data Objects (SDO) TC