IBM BPM, V8.0.1, All platforms > Authoring services in Integration Designer > Services and service-related functions > Access external services with adapters > Configure and using adapters > IBM WebSphere Adapters > Adapter Toolkit > Implementing code from the IBM WebSphere Adapter Toolkit

Data and metadata

Adapter Foundation Classes (AFC) implement DESPI APIs and support two data formats, service data objects (SDO) and JavaBeans.

The data format-specific implementations are provided in the AFC and are abstracted from the adapters which use the DESPI APIs to process data in a format-independent way.


XSD and JavaBeans structure relationship to DESPI

SDO Structure:


JavaBeanRecord Structure:

The JavaBeanRecord data structure is derived from the XML schema defining the SDO. Adapter foundation classes provide an implementation of RecordGenerator which generates JavaBeanRecords for a given SDO/XML schema.

The RecordGenerator class is used by the adapter enterprise metadata to generate the required artifacts for JavaBeans Record data format. See Enterprise metadata implementation details on how to update the adapter enterprise metadata (EMD) implementation to use the RecordGenerator class.

Type mappings: Bean properties map to the attributes of a given complex type. The types of the simple attributes are derived from the XML built-in data types defined in the input schema for each subelement of the complex type. The subelements containing n-cardinality child objects are always defined as an array of the child type while single cardinality subelements are represented as a JavaBeans property with the type of the subelement.

The table below details the mapping between the built-in XML Schema Definition (XSD) types and bean properties generated by the RecordGenerator implementation in the AFC.

Mapping between built-in XSD schema and JavaBeans properties
Header Header
Boolean boolean
String String
Int int
Integer Integer
Decimal BigDecimal
Double double
Float float
Long long
Short short
hexBinary byte[] (byte array)
Byte byte
dateTime Calendar
Date Calendar
Time Calendar
anySimpleType String
Any String

There are cases in which a simple XML data type must be mapped to the corresponding Java™ wrapper class for the Java primitive type:

The examples of each is as follows:

The element/attribute declarations for code, code2, code3 are all mapped to the java.lang.Integer type.

JavaBeans Metadata ASI format: The metadata is derived mostly from the structure of the bean. Other metadata, such as containedType and maxLength are not normal parts of a JavaBeans structure, so they must be part of the annotation maps.


Annotation maps:

Annotations are not normally part of a JavaBeans structure, so JavaBeanRecords must contain annotations in a specific format to be usable by the metadata API.

The JavaBeanRecord must implement the BeanMetadata interface.

public interface BeanMetadata {
	public  Map getObjectAnnotations();
	public  Map getPropertyAnnotations();
	public  Set getSetAttributes();}

Each property (if it needs metadata) can have its own Map, which is stored in the propertyAnnotations map, using the property name as key.

Reserved keys in the propertyAnnotations map:

The notion of whether a property is set is critical to processing null values or values that have not been set in the adapter. If a property has been explicitly set to null, the adapter must be able to detect this and set the associated property to null in the EIS.

If the property has not been set, it might still have a null value, but the adapter ignores the value and not set it in the EIS system.

A list of bean properties for which the setter is called is returned when getSetAttributes() is called. This enables the DESPI implementation to determine if a particular attribute has been set.


Property order:

The notion of property order is critical, because the adapter may need to iterate over the properties in the same order that they appear in the EIS system.

Since JavaBeans APIs cannot detect the order present in the class file, there must be a string array called "propertyOrder" in the bean, containing the names of all properties in the preferred order.

public static final String[] propertyOrder = {"property1","property2"};

SDO to JavaBeanRecord ASI Mappings: Annotations from the SDO/XML schema are read and stored in a Map structure in the bean. Here is a description of how the RecordGenerator would populate annotation maps. For each element in the metadata annotation, the generator would create an entry in the Map with the name of the element as the key.

Here is an example of how the object level metadata annotation would look like in an SDO schema:

<annotation>
<appinfo source=
"http://www.ibm.com/xmlns/prod/websphere/j2ca/sap/metadata">
<sapasi:sapBAPIBusinessObjectTypeMetadata xmlns:sapasi=
"http://www.ibm.com/xmlns/prod/websphere/j2ca/sap/metadata">
	<sapasi:Type>BAPI</sapasi:Type>
	<sapasi:Operation>
		<sapasi:MethodName>BAPI_CUSTOMER_CREATEFROMDATA1</sapasi:MethodName>
		<sapasi:Name>Create</sapasi:Name>
	</sapasi:Operation>
	<sapasi:Operation>
		<sapasi:MethodName>BAPI_CUSTOMER_CHANGEFROMDATA1</sapasi:MethodName>
		<sapasi:Name>Updatewithdelete</sapasi:Name>
	</sapasi:Operation>
</sapasi:sapBAPIBusinessObjectTypeMetadata>
</appinfo>
</annotation>

As defined in the sapBAPIBusinessObjectTypeMetadata schema "Operation" is an n-cardinality complex type. The "MethodName" element of the operation type is a simple type with multiple cardinality:

<complexType name="sapBAPIBusinessObjectTypeMetadata">
		<sequence>
			<element name="Type" type="string"/>
<element name="Operation" type="sapasi:sapBAPIOperationTypeMetadata" 
minOccurs="0" maxOccurs="unbounded"/>
<element name="ErrorConfiguration" type=
"sapasi:sapRFCErrorConfigurationMetadata" minOccurs="0" maxOccurs="1"/> 
		</sequence>
	</complexType>

	<complexType name="sapBAPIOperationTypeMetadata">
		<sequence maxOccurs="1" minOccurs="0">
			<element name="Name" type="string" minOccurs="0" maxOccurs="1"/>
<element name="MethodName" minOccurs="0" maxOccurs="unbounded" type="string"/>
		</sequence>
	</complexType>
	<complexType name="sapRFCErrorConfigurationMetadata">
		<sequence maxOccurs="1" minOccurs="0">
<element name="ErrorParameter" type="string" minOccurs="0" maxOccurs="1"/>
<element name="ErrorCode" minOccurs="0" maxOccurs="1" type="string"/>
<element name="ErrorDetail" minOccurs="0" maxOccurs="1" type="string"/>
		</sequence>
	</complexType>

For the above metadata, the object level annotations map generated for the JavaBeanRecord would look like the following:

public static LinkedHashMap objectAnnotations = new LinkedHashMap();

static {
	objectAnnotations.put("Type","BAPI");

	LinkedList operationAnnotation = new LinkedList();
	
	LinkedList methodnameList;
	LinkedHashMap createOperationMap = new LinkedHashMap();
	
	createOperationMap.put("Name", "Create");
	methodnameList = new LinkedList();
	methodnameList.add("wbiCustomerCreate)";
	createOperationMap.put("MethodName", methodnameList);
	operationAnnotation.add(createOperationMap);	

	LinkedHashMap updateOperationMap = new LinkedHashMap();
	updateOperationMap.put("Name", "Update");
	methodnameList = new LinkedList();
	methodnameList.add("wbiCustomerUpdate)";
	updateOperationMap.put("MethodName", methodnameList);
	operationAnnotation.add(updateOperationMap);	

	objectAnnotations.put("Operation",operationAnnotation);} 

ObjectAnnotations:Object level metadata in the annotations is read and stored in the 'objectAnnotations' Map. Following diagram shows the structure of objectAnnotations.


The Metadata API

Advanced implementations of adapters are metadata-driven. This implies that the adapter is not hard-coded for each object type in the system, but rather has a form of discovery in which a representation of the object (the metadata) in the EIS is constructed at build time, then at runtime the adapter uses this metadata, along with the data, to process the object. Metadata can be in a preexisting format, such as a standardized schema. Standard metadata includes such information as property name, property type, maximum length, cardinality, and anything else that can be described in a standard schema. Metadata may also be in a format decided by the adapter. This form of metadata is called "Application Specific Information", or ASI. ASI can occur in three places.

In order for the adapters to handle multiple representations of metadata; specifically SDO and JavaBeans, the Foundation classes provide an API for the adapters and abstracts the metadata representation. The intention of this Metadata API is to present both structural and application-specific metadata to the adapter, so the adapter is insulated from the metadata format.

For example, a JavaBeans or an SDO may be used as metadata, but the adapter can use the same metadata APIs to walk over the structure and to extract the required information from it.

Adapter implementations should use the following interfaces when retrieving metadata. Adapters should never cast to an implementation of these interfaces. These interfaces may contain more helper methods than are listed here, see the Javadoc for the additional helpers.


Factory classes


Class TypeFactory:

TypeFactory creates an instance of an implementation of Type. The TypeFactory is also capable of detecting whether SDO version 2, SDO version 1, or neither is present in the class path, allowing it to make decisions about what implementation to use.


Class SDOFactory:

SDOFactory creates an SDO instance, the implementation of which will depend on what version of SDO is in the class path.


Interfaces


Interface Type:

The interface type allows access to object-level metadata, including properties, object-level annotations and key properties.

String getName()retuns the name of the type.

Iterator getPropertyIterator() 
Returns an iterator to allow iteraton over the properties in this type. 
 
List getProperties()
Returns a list of properties for this type.  

Property getProperty(String propertyName)
Returns the property object for this property name.

Map getAnnotations(String source) 
Returns the object-level annotations for this type.  You must pass
in the "source" of the annotations, which corresponds to the "source" 
attribute of the "appinfo" tag of the XML Schema representing this 
object.  Annotations will be returned as a Map, and this Map may contain
other maps if the annotation structure is nested.  

Map getAnnotationsForOperation(String source, String operation)
Often operation-specific object metadata is needed. 

For example, for Create operation there is a specific sequence of APIs that have to be executed, this set could be different for Update and Delete operations. This method returns the metadata for a given operation name as a Map of name - value pairs. List getKeyProperties(String source) Returns the list of key properties in this type.


Interface Type:

Type getContainingType() 
Returns the type containing this property.

Object getDefault() 
Returns the default value for this property.

String getName() 
Returns the name of this property.

Class getPropertyClass() 
Returns the Class represented by this property.

For example, if the property is of String type, this method will return String.class. boolean isContainment() Returns whether or not the property contains a Type (complex object). boolean isMany() Returns whether or not the property contains a List or Array. int getMaxLength() Returns the max length of the property. Map getAnnotations(String source) Returns the annotations for this property. boolean isKey(String source) Returns true if this property is a key, and false if not. Type getType()

If the property is containment, this method will return the contained type.


Enterprise metadata implementation


Selection of artifact types

WebSphere adapters can run against multiple brokers (server run times).

Each broker might require different types of artifacts. The adapter foundation classes can generate artifacts in support of multiple brokers.

The following artifact types are supported by adapter foundation classes:

  1. Data Bindings

    Data Binding classes generated by enterprise metadata discovery to support IBM BPM runtime.

  2. Generated Records

    JavaBeans records generated from SDO to support clients that work with JavaBeans.

  3. Generic Records

    Other DESPI implementations.

The table below provides a matrix for artifact type and their supported server run times.

Artifact types and supported run times
  Run times
Artifact types IBM BPM WebSphere Application Server Other DESPI implementations
DataBindings X    
GeneratedRecords   X  
GenericRecords     X

While running the external service discovery wizard, adapter users can choose which artifact to generate depending on their runtime environment. Users can select more than one artifact.

Support for GeneratedRecords artifact type: WebSphere adapters may support JavaBeanRecord data representation along with SDO 1.0 and SDO 2.0 data objects. As part of the support for JavaBeans data representation, the adapter foundation classes provides a JavaBeans record generator class that can generate DataBindingDescriptions for the object types discovered and selected through the enterprise metadata discovery (EMD) process.

Each adapter enterprise metadata discovery provides a list of artifact types it supports, allowing the user to select an artifact type that is appropriate for their environment.

For example, to enable the adapters on run times where SDO implementations are not available, users will run the ESD wizards to generate the adapter artifacts for GeneratedRecords type. When the user selects a Generated Records artifact type in the enterprise metadata discovery process, the external service discovery wizard will look for a databinding generator class name on the EMD DataDescription and invokes that class to generate the JavaBeans records.

All adapter enterprise metadata discovery that support the generated records artifact type would need to set the data binding generator class name (on the DataDescription) to the generator implementation provided in the AFC. Here is a code snippet showing how the record generator is set in the service description implementation of an adapter EMD.

WBISingleValuedPropertyImpl property = 
(WBISingleValuedPropertyImpl) selectionProperties.getProperty
(EMDConstants.ARTIFACTS_SUPPORTED);
WBIMetadataConnectionImpl.getToolContext().getProgressMonitor()
.setIf ("Business object definitions created");
String namespace = getNameSpace();
//Change made for making BG Optional if (property.getValue().equals(EMDConstants.DATA_BINDINGS)) {
dataDescription.setName(WBIDataDescriptionImpl.convertNamespaceToUri(namespace + "/"
+ metadataObj.getBOName().toLowerCase() + "bg" ), metadataObj.getBOName() + "BG");
dataDescription.setDataBindingGeneratorClassName
("com.ibm.j2ca.sample.<AdapterPrefixName>emd.runtime.
<AdapterPrefixName>DataBindingGenerator");
dataDescription.setGenericDataBindingClassName(null);} else if (property.getValue().equals(EMDConstants.GENERATED_RECORDS)) {
dataDescription.setName(WBIDataDescriptionImpl.convertNamespaceToUri(namespace + "/"
+ metadataObj.getBOName().toLowerCase()), metadataObj.getBOName());
dataDescription.setDataBindingGeneratorClassName
("com.ibm.j2ca.extension.dataexchange.bean.generator.RecordGenerator");
dataDescription.setGenericDataBindingClassName(null);} else {
//Generic Record Scenario
dataDescription.setName(WBIDataDescriptionImpl.convertNamespaceToUri(namespace + "/"
+ metadataObj.getBOName().toLowerCase()), metadataObj.getBOName());
dataDescription.setGenericDataBindingClassName
("com.ibm.j2ca.sample.<AdapterPrefixName>StructuredRecord");

New property types supported from WebSphere Adapter Toolkit V6.1:

TableProperty: A property representing a table with rows and columns. Each column is represented by the PropertyDescriptor instance and each cell corresponding to a given row and column is represented by a SingleValuedProperty implementation.

TreeProperty: A property representing a tree of selectable nodes. Each node is represented by a NodeProperty implementation which can be selected, highlighted and can have configuration properties represented by a PropertyGroup instance.

Implementing code from the IBM WebSphere Adapter Toolkit