Examining business objects in WebSphere Process Server

This article focuses on the XML aspects of business objects in WebSphere Process Server. It explains how a business object is defined, what best practices to follow, and how to create and validate a business object.

Larry Tung (ltung@us.ibm.com), Software Engineer, IBM

Larry Tung is a Software Engineer at IBM Burlingame Lab in Burlingame, California. He was one of the developers for the IBM WebSphere Process Server Interface Map component and is currently resolving customer issues.



29 March 2006

Introduction

Business objects are the primary mechanism for representing business entities, enabling everything from a simple basic object with scalar properties to a large complex hierarchy or graph of objects. A business object is a direct corollary to the Service Data Object (SDO) concept, and is a proper subset of the WebSphere Interchange Server business object concept. Rather than go through the SDO specification and the importance of WebSphere Process Server's business object, this article focuses on the XML aspects of the business object. It explains how a business object is defined, what best practices to follow, and how to create and validate a business object.


Defining a business object

We start by examining the sample module containing two simple business objects. You can download the project interchange sample file.

  1. Select File => Import to bring up the Import wizard. Choose Project Interchange and press Next.
    Figure 1. Import Wizard
    Import Wizard
  2. Enable the XML Developer Capability:
    • Select Window => Preferences from the menu bar.
    • Expand the Workbench option and click on Capabilities.
    • Enable the workspace to have full XML Developer capabilities. Click Apply and then OK.
  3. Right-click on one of the business objects and choose Open With => XML Schema Editor.
    Figure 2. XML Schema Editor
    XML Schema Editor

Notice that a business object is a complex type. WebSphere Process Server business objects use a flexible mechanism for defining or importing business objects. Below are three ways WebSphere Process Server defines a business object along with sample schemas:

  1. This is a top level complex type definition.
    <?xml version="1.0" encoding="UTF-8"?>
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    	targetNamespace="http://BO_DevWorks/bo">
    	<xsd:complexType name="ProductType">
    		<xsd:sequence>
    			<xsd:element name="name" type="xsd:string" />
    			<xsd:element name="color" type="xsd:string"
    				maxOccurs="unbounded" />
    			<xsd:element name="description" type="xsd:string"
    				minOccurs="0" />
    		</xsd:sequence>
    	</xsd:complexType>
    </xsd:schema>
  2. This is a top level anonymous complex type definition, similar to WebSphere Interchange Server 4.x. Notice that the complex type is unnamed and embedded inside the "Product" element.
    <?xml version="1.0" encoding="UTF-8"?>
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      targetNamespace="http://BO_DevWorks/bo">
      <xsd:element name="Product">
         <xsd:complexType>
           <xsd:sequence>
                <xsd:element name="name" type="xsd:string" />
                <xsd:element name="color" type="xsd:string"
                 maxOccurs="unbounded" />
                <xsd:element name="description" type="xsd:string"
                minOccurs="0" />
                </xsd:sequence>
          </xsd:complexType>
       </xsd:element>
    </xsd:schema>
  3. This is a top level element that references a named complex type.
    <?xml version="1.0" encoding="UTF-8"?>
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    	targetNamespace="http://BO_DevWorks/bo" tns="http://BO_DevWorks/bo">
    	<xsd:include namespace="ProductType.xsd" />
    	<xsd:element name="Product" type="tns:ProductType" />
    </xsd:schema>

Best practices

WebSphere Integration Developer's Business Object Editor uses the first definition, top-level complex types in the XML schema. It uses the following best practices:

  • Define elements using named types. Try not to use anonymous types in schemas. When possible, do not use the second definition.
  • Do not cohabitate elements and complex type definitions in the same XML Schema or WSDL file.
  • Define complex types in XML Schema files, not WSDL definitions, to create a type library concept.
  • Build element definitions as necessary to reference a single complex type definition. Using this best practice along with the second one discourages you from using the third definition.
  • Use element definitions with the same target namespace as their complex type definition.

Following these best practices lead to greater flexibility and reuse. Thus, when you open a business object, you see complex types. See the Resources section for the link to the javadocs for business object manipulation and a link to the XML schema best practices. In addition, we provide samples to read and dump display the contents of a business object in the ReadAndDump Java component located in /BO_DevWorks/com/ibm/bo/sample/ReadAndDumpImpl.java. You can use the WebSphere Integration Developer's Component Test feature to have the SCA ReadAndDump component read XML from a file and write it to a stream.

Now that you have seen the business object definitions, you might ask about simple types and how attributes are modeled.

Simple types

From the business object definition, simple types cannot be business objects, but business objects can contain simple types. So how can you send a simple type to a Web service? Before answering the question, let us examine what is in WebSphere Integration Developer V6.0.1. Figure 3 shows a simple type named productCode.

Figure 3. Data Types: productCode is a simple type
Data Types: productCode is a simple type

From the Interface Editor, we created a WSDL interface (see /BO_DevWorks/SomeExternalWebService.wsdl) and tried to set the input as productCode. However, we could not find it from the drop-down list of choices (Figures 4 and 5). Note that this problem will be fixed in V6.0.1.1.

Figure 4. Choosing a type in the Interface Editor
Choosing a type in the Interface Editor
Figure 5. Browsing for the simple type - productCode is missing
Browsing for the simple type - productCode is missing

We opened the WSDL interface and modified the parameter to take the productCode. You can right-click the interface and choose Open with => XML Source Page Editor. If you have a customer's WSDL file that has an operation with a single input of a simple type, you can use the code below to send a business object to a Web service, or any SCA component:

Click to see code listing

public void testSimpleType() 
{
        // this call will fail because BO's are taken from COMPLEX types
        try
        {
                // bof is defined earlier and of type BOFactory
                Object simpleType = bof.create("http://BO_DevWorks/bo", "productCode");
                if (simpleType == null) {
                System.out.println("testSimpleType succeeded as productCode is a simpleType and you 
                cannot create it");
                }
                else {
                System.err.println("what just happened? " + simpleType + "; you cannot create business objects 
                from simple types.");
                }
        }
        catch ( Exception e )
        {
            System.err.println(getStackTrace(e));
        }
        // however, you can still send a simple type to a webservice
        // first create the doc-lit "wrapper"
        DataObject dlwWrapper = bof.createByElement("http://BO_DevWorks/SomeExternalWebService", 
        "takeSimpleType");
        // next place a value for the simple type (its base is string)
        dlwWrapper.set("simpleType", "12345678");
        try {
              serializer.writeDataObject(dlwWrapper, "http://BO_DevWorks/SomeExternalWebService",
              "takeSimpleType", System.out);
            } catch (IOException ioe) {
                    System.err.println(getStackTrace(ioe));
            }
}

Here is the output of running the code from System.out:

System.out O testSimpleType succeeded as productCode is a simpleType and you cannot create it
<?xml version="1.0" encoding="UTF-8"?>
<service:takeSimpleType
	xmlns:service="http://BO_DevWorks/SomeExternalWebService">
	<simpleType>12345678</simpleType>
</service:takeSimpleType>

You created a wrapped object, as per the document-literal wrapped WSDL style. This wrapped object has the simple type as one of its properties.

Attributes

When you add an attribute using the Business Object Designer, you see it as an element in a sequence. But, what if you have an existing XML that contain attributes? For example, using the ProductType scenario, what if you have modeled "name" as an attribute?

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	targetNamespace="http://BO_DevWorks/bo">
	<xsd:complexType name="ProductType">
		<xsd:sequence>
			<xsd:element name="color" type="xsd:string"
				maxOccurs="unbounded" />
			<xsd:element name="description" type="xsd:string"
				minOccurs="0" />
		</xsd:sequence>
		<xsd:attribute name="name" type="xsd:string" />
	</xsd:complexType>
</xsd:schema>

In this case, "name" is still a property of the business object. You can use the get/set API along with retrieving it as a property at runtime. For example, if you were to loop through all the properties in a business object, you have code similar to:

// assume productType is the business object we care about
for ( java.util.Iterator propsIter = 
			productType.getType().getProperties.iterator();
	 propsIter.hasNext(); )
	{
		commonj.sdo.Property prop = propsIter.next();
		// code for each property
	}

Mixed content

We have discussed content that has not been mixed. WebSphere Process Server business objects are based on the SDO 1.0 specification. Let's look at a simple complex type of mixed content. Notice the attribute of mixed="true".

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
	targetNamespace="http://BO_DevWorks/bo"
	xmlns:tns="http://BO_DevWorks/bo">
	<xs:complexType name="letter" mixed="true">
		<xs:sequence>
			<xs:element name="name" type="xs:string"/>
			<xs:element name="orderid" type="xs:positiveInteger" 
			 maxOccurs="unbounded"/>
			<xs:element name="shipdate" type="xs:date" />
		</xs:sequence>
		<xs:attribute name="signed" type="xs:string" />
	</xs:complexType>
</xs:schema>

The SDO 1.0 specification did not have accessor methods to determine whether a DataObject was of mixed type (this has been addressed in the SDO 2.01 specification). However, you can determine whether a business object is of mixed content by doing:

// if the business object is not mixed, 
// getSequence throws IllegalArgumentException
commonj.sdo.Sequence seq = bo.getSequence("mixed");
for ( int i = 0; i <seq.size(); ++i ) 
{
	// assume you will do something with the value
	System.out.println( seq.getValue(i) ); 
}

Since there is no accessor in SDO 1.0, you currently have to use the underlying EMF APIs. When business objects move to SDO 2.01 or later, do not use these EMF APIs.

org.eclipse.emf.ecore.EClass ec = (org.eclipse.emf.ecore.EClass)
	((org.eclipse.emf.ecore.sdo.EType) t).getEClassifier();
if ( org.eclipse.emf.ecore.util.ExtendedMetaData.INSTANCE.getContentKind(ec) 
== org.eclipse.emf.ecore.util.ExtendedMetaData.MIXED_CONTENT) {
	// take code snippet (getSequence) from above and place here
}
// below works if the business object uses a mixed content model
// org.eclipse.emf.ecore.EAttribute eAttr = 
// org.eclipse.emf.ecore.util.ExtendedMetaData.INSTANCE.getMixedFeature(ec);

Note that the mixed content will also be seen and retrievable when looking at the properties, bo.getType.getProperties(). You can check for a sequence by doing bo.getProperty("<nameOfProperty>") instanceof commonj.sdo.Sequence.


Creating business objects in XML

There are scenarios in which you want to read XML from a file, or read it from a Java™ Messaging Service (JMS) queue. To test your SCA component, create XML that conforms to a specific XML schema definition. WebSphere Integration Developer can create XML from XSD if you have the XML Developer Capability enabled.

  1. In the Physical Resources View, right-click an XSD and choose Generate, XML File as shown in Figure 6.
    Figure 6. Generating XML from XSD
    Generating XML from XSD
  2. In the Create XML File wizard, you can have WebSphere Integration Developer generate all the required and optional elements and attributes as shown in Figure 7.
    Figure 7. Create XML File Wizard
    Create XML File Wizard
    Note that the wizard does not use a complex algorithm (as of version 6.0.1) and you need to validate the generated XML. For example, facets and restrictions may not necessarily be created properly. In addition, the wizard requires a top-level element. If it is absent, the wizard exits with a popup message stating that the schema has no global element. Thus, from the best practices mentioned earlier, you can have a business object defined as a top level complex type. To use the wizard, you can temporarily create another XML schema and use the include statement, as shown in the third definition.

    Here is the generated XML from ProductElement.xsd:
    <?xml version="1.0" encoding="UTF-8"?>
    <tns:Product xmlns:tns="http://BO_DevWorks/bo"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://BO_DevWorks/bo ../ProductElement.xsd ">
    	<name>ProductElement</name>
    	<color>color</color>
    	<description>description</description>
    </tns:Product>
  3. Notice that the XML generated by the wizard inserts a schemaLocation attribute. Without this attribute, WebSphere Integration Developer cannot validate your XML instance with the proper XML schema. Later, in the Reading XML at runtime section, we discuss the ramifications of having a business object defined as a top level complex type. If the XML instance does not contain a target namespace, use xsi:noNamespaceSchemaLocation="[relative path to schema]" instead of xsi:schemaLocation.
  4. For your reference, you can also use WebSphere Integration Developer to create an XML Schema from an XML instance (in the Physical Resources perspective, right-click an XML file, and choose Generate => XML Schema). However, we discourage you from using this wizard because it uses a simplistic algorithm. It takes your XML, runs an algorithm, and generates a best guess at what the schema could be. Here are some known limitations:
    • The generated XSD does not include restrictions and facets.
    • If you have optional attributes in an element or default values for attributes, the wizard may omit them depending on what is in your XML instance.
    • If the original XSD has elementFormDefault="unqualified", your XSD may not have the correct namespaces for elements.

Validating the XML

To minimize errors at runtime, validate the XML to ensure that it matches with the schema:

  1. If you have not already done so, enable the XML Developer Capability.
  2. Right-click on the XML schema definition and choose Validate => XML File.
    Figure 8. Validating XML
    Validating XML

Reading XML at runtime

Now that the XML has been created and validated, you can use the component test feature to read the XML from a file and write the output to System.out. First, modify the method testReadWrite (/BO_DevWorks/com/ibm/bo/sample/ReadAndDumpImpl.java) to point at the absolute path in your filesystem.

Here is the output of running testReadWrite:

/BO_DevWorks/bo/xml/Product_WICS.xml
<?xml version="1.0" encoding="UTF-8"?>
<bo:Product_WICS_._type xsi:type="bo:Product_WICS_._type"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:bo="http://BO_DevWorks/bo">
	<name>Product_WICS</name>
	<color>color</color>
	<description>description</description>
</bo:Product_WICS_._type>

As of WebSphere Process Server 6.0.1, anonymous types use the parent element name appended by _._type. We discourage you from using this name. In the future, this naming convention could be changed. You can create a business object using the BOFactory.createByElement operation and pass in the element name (in this case, Product_WICS).

 /BO_DevWorks/bo/xml/ProductElement.xml
<?xml version="1.0" encoding="UTF-8"?>
<bo:Product xsi:type="bo:ProductType"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:bo="http://BO_DevWorks/bo">
	<name>ProductElement</name>
	<color>color</color>
	<description>description</description>
</bo:Product>

Note the xsi:type attribute points to the complex type that ProductElement refers too.

/BO_DevWorks/bo/xml/Product.xml
<?xml version="1.0" encoding="UTF-8"?>
<bo:ProductType xsi:type="bo:ProductType"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:bo="http://BO_DevWorks/bo">
	<name>Product</name>
	<color>color</color>
	<description>description</description>
</bo:ProductType>

An important point is that the xsi:type attribute is used to tell WebSphere Process Server how to construct the business object by indicating what complex type you are referring to. ProductElement.xsd was only added such that we could use the WebSphere Integration Developer to create an element and validate it. This is convenient, instead of writing the XML by hand. If you did not deploy ProductElement.xsd to the server (for example, delete it, and then redeploy the module), you get errors such as:

org.eclipse.emf.ecore.xmi.ClassNotFoundException: Class 'Product' not found. (, 4, 68)
at org.eclipse.emf.ecore.xmi.impl.XMLHandler.validateCreateObjectFromFactory
(XMLHandler.java(Compiled Code))

The reason for the error is that WebSphere Process Server did not find an element named Product.

If you added an element into a separate schema file, as done in this sample, after validation, modify it such that xsi:schemaLocation is replaced with the xsi:type attribute and have it point to a complex type in a schema. The top level element should also be a complex type. This follows the best practices stated earlier: only create elements when you need them and keep complex types separated from elements. We recommend using the third sample above if you are reading XML from a file or JMS queue. We are referring to business objects defined in a schema using complex types, the first definition from the Defining business objects section. If you are using business objects defined as an element, you may not need the xsi:type attribute since you are already dealing with elements.

An alternative to using WebSphere Integration Developer's Create wizard is to use the XML read from BOXMLSerializer's writeDataObject method. You can create a simple Java interface with implementation similar to what is provided. Then, using component test, you can send a business object and take the serialized XML as the test data.

You can run the component test feature by right-clicking the appropriate SCA component in the Assembly Diagram and choosing Test Component as shown in Figure 9. You are prompted to choose what operation you want executed along with the arguments to use.

Figure 9. Running Test Component from the Assembly Diagram
Running Test Component from the Assembly Diagram

WebSphere Process Server does not validate XML content for performance reasons. You validate it on the client before sending the data to the server.


Conclusion

In this article, you learned how business objects are defined and the best practices to follow. You learned how to use WebSphere Integration Developer to create and validate XML documents prior to sending them to WebSphere Process Server. By following these recommendations, you will have a stable, flexible, and reusable library of types for your solution.


Download

DescriptionNameSize
Code sampleproject-interchange-file.zip  ( HTTP | FTP | Download Director Help )11 KB

Resources

Learn

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=106815
ArticleTitle=Examining business objects in WebSphere Process Server
publish-date=03292006