Creating a business object handler

Creating a business object handler involves the following steps:

Note:
For an introduction to request processing, see "Request processing".. For a discussion of request processing and the implementation of doVerbFor(), see Request processing.

Extending the Java business-object-handler base class

In the Java connector library, the base class for a business object handler is named CWConnectorBOHandler. The CWConnectorBOHandler class provides methods for defining and accessing a business object handler. To implement your own business object handler, you extend this business-object-handler base class to create your own business-object-handler class.

Note:
For general information about the methods of the business-object-handler base class, see "Extending the business-object-handler base class"..

To derive a business-object-handler class for a Java connector, follow these steps:

  1. Create a class that extends the CWConnectorBOHandler class. Name this class:
        connectorNameBOHandler.java
     
    

    where connectorName uniquely identifies the application or technology with which the connector communicates. For example, to create a business object handler for a Baan application, you create a business-object-handler class called BaanBOHandler. If your connector design implements multiple business object handlers, include the name of the handled business objects in the name of the business-object-handler class.

  2. In the business-object-handler-class file, define the package name that contains your connector. A connector package name has the following format:
    com.crossworlds.connectors.connectorName
     
    

    where connectorName is the same as defined in step 1 above. For example, the package name for the Baan connector would be defined in the business-object-handler-class file as follows:

    package com.crossworlds.connectors.Baan;
     
    
  3. Ensure that the business-object-handler-class file imports the following classes:
        com.crossworlds.cwconnectorapi.*;
     com.crossworlds.cwconnectorapi.exceptions.*;
     
    

    If you create several files to hold the business object handler's code, you must import these classes into every file.

  4. Implement the doVerbFor() method to define the behavior of the business object handler. For more information on how to implement this method, see Implementing the doVerbFor() method.
    Note:
    The other methods in the CWConnectorBOHandler class have their implementations provided. The doVerbFor() method is the only method you must implement in the business-object-handler class. For more information, see CWConnectorBOHandler class.

You might need to implement more than one business object handler for your connector, depending on the application and its API. For a discussion of some issues to consider when implementing business object handlers, see "Designing business object handlers"..

Implementing the doVerbFor() method

The doVerbFor() method provides the functionality for the business object handler. When the connector framework receives a request business object, it calls the doVerbFor() method for the appropriate business object handler to perform the action of this business object's verb. For a Java connector, the CWConnectorBOHandler class defines the doVerbFor() method in which you define the verb processing.

Note:
For a general description of the role of the doVerbFor() method, see "Handling the request".. Figure 27 provides the method's basic logic.

However, the actual doVerbFor() method that the connector framework invokes is the low-level version of this method, which the CWConnectorBOHandler class inherits from the BOHandlerBase class of the low-level Java connector library. This low-level version of doVerbFor() calls the user-implemented doVerbFor() method. Therefore, as part of your business-object-handler class (an extension of CWConnectorBOHandler), you must provide an implementation of the doVerbFor() method.

Note:
The low-level doVerbFor() method calls the doVerbFor() method as long as the business object's verb does not contain the CBOH tag in its verb application-specific information. If the CBOH tag exists, the low-level doVerbFor() calls the custom business object handler whose name the CBOH tag specifies. For more information, see Creating a custom business object handler.

The role of the business object handler is to perform the following tasks:

  1. Receive business objects from the connector framework.
  2. Process each business object based on the active verb.
  3. Send requests for operations to the application.
  4. Return status to the connector framework.

Table 62 summarizes the steps in the basic logic for the verb processing that the doVerbFor() method typically performs. Each of the sections listed in the For More Information column provides more detailed information on the associated step in the basic logic.

Table 62. Basic logic of the doVerbFor() method

Business-object-handler step For more information
1. Obtain the active verb from the request business object. "Obtaining the active verb"
2. Verify that the connector still has a valid connection to the application. "Verifying the connection before processing the verb"
3. Branch on the value of the valid active verb. "Branching on the active verb"
4. For a given active verb, perform the appropriate request processing:

  • Perform verb-specific tasks.

"Performing the verb operation"

  • Process the business object.

"Processing business objects"
5. Send the appropriate status to the connector framework. "Sending the verb-processing response"

In addition to the processing steps in Table 62,, this section also provides additional processing information in "Additional processing issues".

Note:
Java connectors must be thread safe. For Java connectors, the connector framework uses separate threads to call into the doVerbFor() and pollForEvents() methods.
WebSphere InterChange Server

If your business integration system uses InterChange Server and collaborations are coded to be multi-threaded, the connector framework might call into doVerbFor() with multiple threads representing request processing.

Obtaining the active verb

To determine which actions to take, the doVerbFor() method must first retrieve the verb from the business object that it receives as an argument. This incoming business object is called the request business object. The verb that this business object contains is the active verb, which must be one of the verbs that the business object definition supports. Table 63 lists the method that the Java connector library provides to retrieve the active verb from the request business object.

Table 63. Method for obtaining the active verb

Java connector library class Method
CWConnectorBusObj getVerb()

Obtaining the active verb from the request business object generally involves the following steps:

  1. Verify that the request business object is valid.

    Before the connector calls getVerb(), it should verify that the incoming request business object is not null. The incoming business object is passed into the doVerbFor() method as a CWConnectorBusObj object.

  2. Obtain the active verb with the getVerb() method.

    Once the request business object is valid, you can use the getVerb() method in the CWConnectorBusObj class to obtain the active verb from this business object.

  3. Verify that the active verb is valid.

    When the connector has obtained the active verb, it should verify that this verb is neither null nor empty.

If either the request business object or the active verb is invalid, the connector should not continue with verb processing. Instead, it should take the steps outlined in Table 64..

Table 64. Handling a verb-processing error

Error-handling step Method or code to use
1. Log an error message to the log destination to indicate the cause of the verb-processing error. CWConnectorUtil.generateAndLogMsg()
2. Instantiate an exception-detail object to hold the exception information. CWConnectorExceptionObject excptnDtailObj = new CWConnectorExceptionObject();
3. Set the status information within an exception-detail object:

  • set a message to indicate the cause of the verb-processing failure

excptnDtailObj.setMsg()

  • set the status to the FAIL outcome status, which the connector framework includes in its response to the integration broker.

excptnDtailObj.setStatus()
4.

Throw a VerbProcessingFailureException exception, which the doVerbFor() uses to tell the connector framework that a verb-processing error has occurred. This exception object contains the exception-detail object you initialized in Step 2.

When the low-level doVerbFor() method catches this exception object, it copies the message and status from the exception-detail object into the return-status descriptor that it returns to the connector framework, which in turn returns it to the integration broker.

throw new VerbProcessingFailureException( excptnDtailObj);
Note:
For information on the exception and exception-detail objects, see "Exceptions".

Figure 59 contains a fragment of the doVerbFor() method that obtains the active verb with the getVerb() method. This code uses the try and catch statements to ensure that the request business object and its active verb are not null. If either of these conditions exists, the code fragment throws the VerbProcessingFailedException exception, which the connector framework catches.

Figure 59. Obtaining the active verb

public int doVerbFor(CWConnectorBusObj theBusObj) 
    throws VerbProcessingFailedException, ConnectionFailureException
 {
    CWConnectorExceptionObject cwExcpObj = 
       new CWConnectorExceptionObject();
  
    //make sure that the incoming business object is not null
    if (theBusObj == null) {
       CWConnectorUtil.logMsg(3456,
          CWConnectorLogAndTrace.XRD_ERROR);
       cwExcpObj.setMsg(
          "doVerbFor(): Invalid business object passed in");
       cwExcpObj.setStatus(CWConnectorConstant.FAIL);
       throw new VerbProcessingFailedException(cwExcpObj);
    }
  
    // obtain the active verb
    String busObjVerb = theBusObj.getVerb();
  
    // make sure the active verb is neither null nor empty
    if (busObjVerb == null || busObjVerb.equals("")){
       cwExcpObj.setMsgNumber(6548);
       cwExcpObj.setMsgType(CWConnectorLogAndTrace.XRD_ERROR);
       cwExcpObj.setMsg("doVerbFor: Invalid active verb");
       cwExcpObj.setStatus(CWConnectorConstant.FAIL);
       throw new VerbProcessingFailedException(cwExcpObj);
    }
    try {
       // perform verb processing here
       ...
  
    } catch (SampleException se) {
       throw new VerbProcessingFailedException(cwExcpObj);
 }
 

Verifying the connection before processing the verb

When the agentInit() method in the connector class initializes the application-specific component, one of its most common tasks is to establish a connection to the application. The verb processing that doVerbFor() performs requires access to the application. Therefore, before the doVerbFor() method begins processing the verb, it should verify that the connector is still connected to the application. The way to perform this verification is application-specific. Consult your application documentation for more information.

A good design practice is to code the connector application-specific component so that it shuts down whenever the connection to the application is lost. If the connection has been lost, the connector should not continue with verb processing. Instead, it should take the following steps to notify the connector framework of the lost connection:

  1. Log an error message to the log destination to indicate the cause of the error.

    The connector logs a fatal error message so that email notification is triggered if the LogAtInterchangeEnd connector configuration property is set to True.

  2. Set the exception-detail object with:
    • a message to indicate the cause of the connection failure

    CWConnectorExceptionObject.setMsg()
    • the status of the APPRESPONSETIMEOUT outcome status, which the connector framework includes in its response to the integration broker.

    CWConnectorExceptionObject.setStatus()

    This exception-detail object is part of the exception object that doVerbFor() throws. For information on these methods, see "Exceptions".

  3. Throw a ConnectionFailureException exception, which the doVerbFor() uses to tell the connector framework that a verb-processing cannot continue because the connection to the application has been lost. This exception object contains the exception-detail object you initialized in step 2..

    When the low-level doVerbFor() method catches this exception object, it copies the message and status from the exception-detail object into the return-status descriptor that it returns to the connector framework. If you have not set the status in the ConnectionFailureException exception-detail object, the connector framework sets the status to APPRESPONSETIMEOUT. The connector framework includes this return-status descriptor as part of its response to the integration broker. The integration broker can check the return-status descriptor to determine that the application is not responding.

After it has sent the return-status descriptor, the connector framework stops the process in which the connector runs. A system administrator must fix the problem with the application and restart the connector to continue processing events and business object requests.

Branching on the active verb

The main task of verb processing is to ensure that the application performs the operation associated with the active verb. The action to take on the active verb depends on whether the doVerbFor() method has been designed as a basic method or a metadata-driven method:

Basic verb processing

For verb-processing that is not metadata-driven, you branch on the value of the active verb to perform the verb-specific processing. Your doVerbFor() method must handle all verbs that the business object supports.

Note:
You can obtain a list of business object's supported verbs with the getSupportedVerbs() method of the CWConnectorBusObj class.
Table 65 shows the verb constants that the Java connector library provides for comparing with the active verb.

Table 65. The Java verb constants

Verb Constant Active Verb
VERB_CREATE Create
VERB_RETRIEVE Retrieve
VERB_UPDATE Update
VERB_DELETE Delete
VERB_EXISTS Exists
VERB_RETRIEVEBYCONTENT RetrieveByContent

All verb constants in Table 65 are defined in the CWConnectorConstant class. If your connector handles additional verbs, IBM recommends that you define your own String constants as part of your extended CWConnectorBOHandler class.

Note:
As part of the verb-branching logic, make sure you include a test for an invalid verb. If the request business object's active verb is not supported by the business object definition, the business object handler must take the appropriate recovery actions to indicate an error in verb processing. For a list of steps to handle a verb-processing error, see Table 64..

Figure 60 shows a code fragment of doVerbFor() that branches off the active verb's value for the Create and Update verbs. For each verb your business object supports, you must provide a branch in this code.

Figure 60. Branching on the active verb's value

// handle the Create verb
 if(busObjVerb.equals(CWConnectorConstant.VERB_CREATE)){
    CWConnectorUtil.initAndValidateAttributes(theBusObj);
    status=doCreate(theBusObj);
    // where doCreate() inserts new row into Sample Apps database
    // using data from theBusObj
    }
  
 // handle the Update verb
 else if (objVerb.equals(CWConnectorConstant.VERB_UPDATE)){
    status=doUpdate(theBusObj);
    // where doUpdate() locates existing row and updates it with
    // information from theObj
  
 // notify connector framework of invalid verb
 } else {
    CWConnectorUtil.logMsg(3456, CWConnectorLogAndTrace.XRD_ERROR);
    cwExcpObj.setMsg("doVerbFor(): Invalid verb passed in");
    cwExcpObj.setStatus(CWConnectorConstant.FAIL);
    throw new VerbProcessing FailedException(cwExcpObj);
 }
 

The code fragment in Figure 60 is modularized; that is, it puts the actual processing of each supported verb into a separate verb method: doCreate() and doUpdate(). Each verb method should meet the following minimal guidelines:

This modular structure greatly simplifies the readability and maintainability of the doVerbFor() method.

Metadata-driven verb processing

For metadata-driven verb processing, the application-specific information for the verb contains metadata, which provides processing instructions for the request business object when that particular verb is active. Table 66 lists the method that the Java connector library provides to obtain application-specific information for the verb of a business object.

Table 66. Method for retrieving the verb's application-specific information

Java connector library class Method
CWConnectorBusObj getVerbAppText()

The following call to getVerbAppText() extracts the verb's application-specific information:

String verbAppInfo = theBusObj.getVerbAppText(busObjVerb);
 

The verb application-specific information can contain the name of the method to call to process the request business object for that particular verb. In this case, the doVerbFor() method does not need to branch off the value of the active verb because the processing information resides in the verb's application-specific information.

Note:
Another use of verb application-specific information can be to specify the application's API method to call to update the application entity for the particular verb.

Performing the verb operation

Table 67 lists the standard verbs that a doVerbFor() method can implement, as well as an overview of how each verb operation processes the request business object. For more information on how to process business objects, see "Processing business objects".

Table 67. Performing the verb operation

Verb Use of request business object For more information
Create
  • Use any application-specific information in the business object definition to determine in which application structure to create the entity (for example, a database table).
  • Use any application-specific information for each attribute to determine in which application substructure to add the attribute values (for example, a database column).
  • Use attribute values as values to save in new application entity.

If the application generates key values for the new entity, save the new key values in the request business object, which should then be included as part of the verb-processing response.

"Handling the Create verb"
Retrieve
  • Use any application-specific information in the business object definition to determine from which application structure (for example, a database table) to retrieve the entity.
  • Use attribute key value (or values) to identify which application entity to retrieve.

If the application finds the requested entity, save its values in the request business object's attributes. The request business object should then be included as part of the verb-processing response.

"Handling the Retrieve verb"
Update
  • Use any application-specific information of the business object definition to determine in which application structure (for example, a database table) to update the entity.
  • Use any application-specific information for each attribute to determine which application substructure to update with the attribute values (for example, a database column).
  • Use attribute key value (or values) to identity which application entity to update.
  • Use the attribute values as values to update the existing application entity.

If the application is designed to create an entity if the one specified for update does not exist, save the new entity values in the request business object's attributes. The request business object should then be included as part of the verb-processing response.

"Handling the Update verb"
Delete
  • Use any application-specific information in the business object definition to determine from which application structure (for example, a database table) to delete the entity.
  • Use attribute key value (or values) to identify which application entity to delete.

The request business object should then be included as part of the verb-processing response so that InterChange Server can perform any required cleanup of relationship tables.

"Handling the Delete verb"

Processing business objects

Most verb operations involve obtaining information from the request business object. This section provides information about the steps your doVerbFor() method needs to take to process the request business object.

Note:
These steps assume that your connector has been designed to be metadata-driven; that is, they describe how to extract application-specific information from the business object definition and attributes to obtain the location within the application associated with each attribute. If your connector is not metadata-driven, you probably do not need to perform any steps that extract application-specific information.

Table 68 summarizes the steps in the basic program logic for deconstructing a request business object that contains metadata.

Table 68. Basic logic for processing a request business object with metadata

Step For more information
1. Obtain the business object definition for the request business object. "Accessing the business object definition"
2. Obtain the application-specific information in the business object definition to obtain the application structure to access. "Extracting business object application-specific information"
3. Obtain the attribute information. "Accessing the attributes"
4. For each attribute, get the attribute application-specific information in the business object definition to obtain the application substructure to access. "Extracting attribute application-specific information"
5. Make sure that processing occurs only for those attributes that are appropriate. "Determining whether to process an attribute"
6. Obtain the value of each attribute whose value needs to be sent to the application entity. "Extracting attribute values from a business object"
7. Notify the application to perform the appropriate verb operation. "Initiating the application operation"
8. Save any attribute values in the request business object that are required for the verb-processing response. "Saving attribute values in a business object"
Accessing the business object definition

For a Java connector, the doVerbFor() method receives the request business object as an instance of the CWConnectorBusObj class. To begin verb processing, the doVerbFor() method often needs information from the business object definition. The CWConnectorBusObj class provides access to the business object, its business object definition, and its attributes. Therefore, a Java doVerbFor() method does not need to instantiate a separate object for the business object definition; it can obtain information in the business object definition directly from the CWConnectorBusObj object passed into doVerbFor().

The business object definition includes the information shown in Table 69.. For a complete list of CWConnectorBusObj methods, see CWConnectorBusObj class.

Table 69. Methods for obtaining information from the business object definition

Business object definition information CWConnectorBusObj method
The name of the business object definition getName()
A verb list--contains the verbs that the business object supports isVerbSupported(), getSupportedVerbs()
A list of attributes--for each attribute, the business object definition defines: getAttrCount()
  • attribute name

getAttrName()
  • attribute data type

getTypeName(), getTypeNum()
  • position in the list of attributes

getAttrIndex()
  • other properties

For a complete list, see Table 71..
Application-specific information:
  • business object definition

getAppText(), getBusObjASIHashtable()
  • attribute

getAppText(), getAttrASIHashtable()
  • verb

getVerbAppText()

A business object handler typically uses the business object definition to get information on the business object's attributes or to get the application-specific information from the business object definition, attribute, or verb.

Extracting business object application-specific information

Business objects for metadata-driven connectors are usually designed to have application-specific information that provides information about the application structure. For such connectors, the first step in a typical verb operation is to retrieve the application-specific information from the business object definition associated with the request business object. Table 70 lists the methods that the Java connector library provides to retrieve application-specific information from the business object definition.

Table 70. Methods for obtaining business object application-specific information

Java connector library class Method
CWConnectorBusObj getAppText() (with no arguments)

getBusObjASIHashtable()

As Table 70 shows, the connector can use either of the following methods to obtain the application-specific information for the business object definition:

For a table-based application, the business objects are often designed to have application-specific information provide the verb operations with information about the application structure (For more information, see Table 43). The application-specific information in a business object definition can contain the name of the database table associated with the business object.

Accessing the attributes

For a Java connector, the CWConnectorBusObj class provides access to the business object, its business object definition, and its attributes. When the doVerbFor() method needs information about attributes in the business object, it can obtain this information directly from the request business object. Therefore, a Java doVerbFor() method does not need to instantiate a separate object for an attribute.

The connector can use attribute methods in the CWConnectorBusObj class (see Table 71) to obtain information about an attribute, such as its cardinality or maximum length. Methods that access attribute properties provide the ability to access an attribute in of two ways:

Table 71 lists the methods that the Java connector library provides to retrieve information about an attribute. For a complete list of methods that access attribute information, see CWConnectorBusObj class.

Table 71. Methods for obtaining attribute information

Attribute property CWConnectorBusObj method
Name getAttrName(), hasName()
Type getTypeNum(), getTypeName(), hasType(), isObjectType(), isType()
Key isKeyAttr()
Foreign key isForeignKeyAttr()
Max Length getMaxLength()
Required isRequiredAttr()
Cardinality getCardinality(), hasCardinality(), isMultipleCard()
Default Value getDefault(), getDefaultboolean(), getDefaultdouble(), getDefaultfloat(), getDefaultint(), getDefaultlong(), getDefaultString()
Attribute application-specific information getAppText()
Extracting attribute application-specific information

If business objects for metadata-driven connectors are designed to have application-specific information that provides information about the application structure, the next step after extracting the application-specific information from the business object definition is to extract the application-specific information from each attribute in the request business object. Table 72 lists the methods that the Java connector library provides to retrieve application-specific information from each attribute.

Table 72. Methods for obtaining attribute application-specific information

Java connector library class Method
CWConnectorBusObj getAttrCount()

getAppText() (with the position or name of the attribute as an argument)

getAttrASIHashtable()

As Table 72 shows, the connector can use either of the following methods to obtain the application-specific information for an attribute:

If business objects have been designed to have application-specific information provide information for a table-based application, the application-specific information for the attribute can contain the name of the application table's column associated with this attribute (For more information, see Table 43). After extracting the application-specific information from the business object definition, the next step is to determine what columns in the application table are associated with the attributes in the request business object.

A verb operation can call getAppText(), passing it the position or name of the attribute, to obtain the name of the column within the database table to access. To obtain the application-specific information for each attribute, the verb operation must loop through all attributes in the business object definition. Therefore, it must determine the total number of attributes in the business object definition. The most common syntax for looping through the attributes is a for statement that uses the following limits on the loop index:

Within the for loop, the Java connector can use the getAppText() method to obtain each attribute's application-specific information:

for (i = 0; i < theBusObj.getAttrCount() - 1; i++) {
    colName = theBusObj.getAppText(i);
  
    // process the attribute associated with the column in
    // 'colName'
 }
 
Determining whether to process an attribute

Up to this point, the verb processing has been using the application-specific information to obtain the application location for each attribute of the request business object. With this location information, the verb operation can begin processing the attribute.

As the verb operation loops through the business object attributes, you might need to confirm that the operation processes only certain attributes. Table 73 lists some of the methods that the Java connector library provides to determine whether an attribute should be processed.

Table 73. Methods for determining attribute processing

Attribute test CWConnectorBusObj method
An attribute is a simple attribute and not an attribute that represents a contained business object. isObjectType()
The value of the attribute is not the special value of Blank (a zero-length string) or Ignore (a null pointer). isIgnore(), isBlank()
The attribute is not a place-holder attribute. Place-holder attributes are used in business object definitions to separate attributes that contain child business objects. getAppText()

Using the methods in Table 73,, a verb operation can determine that an attribute is one that the operation wants to process:

Extracting attribute values from a business object

Once the verb operation has confirmed that the attribute is ready for processing, it usually needs to extract the attribute value:

Table 74 lists the methods that the Java connector library provides to obtain attribute values from a business object.

Table 74. Methods for obtaining attribute values

Java connector library class Method
CWConnectorBusObj getTypeName(),, getTypeNum(),, getbooleanValue(),, getBusObjValue(),, getdoubleValue(),, getfloatValue(),, getintValue(),, getlongValue(),, getLongTextValue(),, getStringValue()

As Table 74 shows, the CWConnectorBusObj class provides type-specific methods for obtaining attribute values. These methods remove the need to cast the attribute value to match its type. You can choose which type-specific method to use by checking the attribute's data type with the getTypeName() or getTypeNum() method.

Initiating the application operation

Once the verb operation has obtained the information it needs from the request business object, it is ready to send the application-specific command so that the application performs the appropriate operation. The command must be appropriate for the verb of the request business object. For a table-based application, this command might be an SQL statement or a JDBC call. Consult your application documentation for more information.

Important:
Your doVerbFor() method must ensure that the application operation completes successfully. If this operation is unsuccessful, the doVerbFor() method must return the appropriate outcome status (such as FAIL) to the connector framework. For more information, see "Sending the verb-processing response".
Saving attribute values in a business object

Once the application operation has completed successfully, the verb operation might need to save new attribute values retrieved from the application into the request business object:

Table 75 lists the methods that the Java connector library provides to save attribute values in a business object.

Table 75. Methods for saving attribute values

Java connector library class Method
CWConnectorBusObj setAttrValues(),, setbooleanValue(),, setBusObjValue(),, setdoubleValue(),, setfloatValue(),, setintValue(),, setLongTextValue(),, setStringValue()

As Table 75 shows, the CWConnectorBusObj class provides the following ways to save attribute values:

Sending the verb-processing response

The Java connector must send a verb-processing response to the connector framework, which in turn sends a response to the integration broker. This verb-processing response includes the following information:

The following sections provide additional information about how a Java connector provides each of the pieces of response information. For general information about the connector response, see "Indicating the connector response"..

Returning the outcome status

The doVerbFor() method provides an integer outcome status as its return code. As Table 76 shows, the Java connector library provides constants for the outcome-status values that doVerbFor() is mostly likely to return.

Important:
The doVerbFor() method must return an integer outcome status to the connector framework.

Table 76. Outcome-status values for a Java doVerbFor()

Condition in doVerbFor() Java outcome status
The verb operation succeeded. CWConnectorConstant.SUCCEED
The verb operation failed. CWConnectorConstant.FAIL
The application is not responding. CWConnectorConstant. APPRESPONSETIMEOUT
At least one value in the business object changed. CWConnectorConstant.VALCHANGE
The requested operation found multiple records for the same key value. CWConnectorConstant.VALDUPES
The connector finds multiple matching records when retrieving using non-key values. The connector will only return the first matching record in a business object. CWConnectorConstant.MULTIPLE_HITS
The connector was not able to find matches for Retrieve by non-key values. CWConnectorConstant. RETRIEVEBYCONTENT_FAILED
The requested business object entity does not exist in the database. CWConnectorConstant. BO_DOES_NOT_EXIST
Note:
The CWConnectorConstant class provides additional outcome-status constants for use by other connector methods. For a complete list of outcome-status constants, see "Outcome-status constants"..

The outcome status that doVerbFor() returns depends on the particular active verb it is processing. Table 77 lists the tables in this manual that provide possible return values for the different verbs.

Table 77. Return values for different verbs

Verb For more information
Create Table 35
Retrieve Table 36
RetrieveByContent Table 37
Update Table 39
Delete Table 41
Exists Table 42

Using the outcome status that doVerbFor() returns, the connector framework determines its next action:

Populating the return-status descriptor

The return-status descriptor is a structure that holds additional information about the state of the verb processing. When the connector framework invokes a business object handler, it actually calls the low-level version of the doVerbFor() method, inherited from the BOHandlerBase class of the low-level Java connector library. To this low-level doVerbFor() method, the connector framework passes in an empty return-status descriptor as an argument. The low-level doVerbFor() then calls the user-implemented doVerbFor() method, which is the version for which the connector developer provides an implementation as part of the CWConnectorBOHandler business-object-handler class. The user-implemented doVerbFor() performs the actual verb processing.

When this user-implemented doVerbFor() method exits, the low-level doVerbFor() updates its return-status descriptor with status information about the verb processing, as follows:

When the low-level doVerbFor() exits, this updated return-status descriptor is accessible by the connector framework. The connector framework then includes the return-status descriptor in the response it sends to the integration broker.

WebSphere InterChange Server

If your business integration system uses InterChange Server, the connector framework returns the response to the connector controller, which routes it to the collaboration. This response includes the return-status descriptor populated by the low-level doVerbFor() method. The collaboration can access the information in this return-status descriptor to obtain the status of its service call request.

Updating the request business object

The connector framework passes in the request business object as an argument to doVerbFor(). The doVerbFor() method can update this business object with attribute values. This updated business object is then accessible by the connector framework when doVerbFor() exits.

The connector framework uses the outcome status to determine whether to return a business object as part of its response to the integration broker, as follows:

Important:
The outcome status that the doVerbFor() method returns affects what the connector framework sends to the integration broker. If the value is VALCHANGE or MULTIPLE_HITS, the connector framework returns the request business object. You must ensure that the request business object is updated as appropriate for the returned outcome status.

Additional processing issues

This section provides information on the following issues related to processing a business object:

Handling the Blank and Ignore values

In addition to a regular attribute value, simple attributes in business objects can have either of the special values shown in Table 78..

Table 78. Special attribute values for simple attributes

Special attribute value Represents
Blank An "empty" zero-length string value
Ignore An attribute value that the connector should ignore
WebSphere InterChange Server
Important:
If your business integration system uses InterChange Server, in the third-party maps, the string CxIgnore represents an Ignore value, and the string CxBlank represents a Blank value. These strings should be used only in maps. They should not be stored in business objects as attribute values because they are reserved keywords in the IBM WebSphere InterChange Server system.

The connector can call Java connector library methods to determine whether a business object attribute is set to a special value:

When a connector creates a new business object, all attribute values are set to Ignore internally. A connector must set appropriate values for attributes, since all unset attribute values remain defined as Ignore. To set attribute values to the special Ignore or Blank values, you use the methods in Table 83 (defined in the CWConnectorUtil class) to obtain a special attribute value and then assign the results of these methods directly to the attribute.

Table 83. Methods for obtaining special attribute values

Special attribute value CWConnectorUtil method
Blank value getBlankValue()
Ignore value getIgnoreValue()

Once a method in Table 83 retrieves the desired special attribute value, you can pass it to one of the "set" methods for the attribute value (see Table 75), as the following code fragment shows:

attrName = theBusObj.getAttrName(i);
 theBusObj.setdoubleValue(attrName, 
    CWConnectorUtil.getIgnoreValue());
 
Accessing child business objects

As discussed in "Processing hierarchical business objects",, a Java connector uses the methods of the Java connector library shown in Table 75 to access child business objects.

Table 84. Methods for accessing child business objects

Java connector library class Method
CWConnectorBusObj isObjectType(),, isMultipleCard(),,

getObjectCount(),, getBusObjValue()

CWConnectorAttrType OBJECT attribute-type constant

The verb processing in the doVerbFor() method uses the isObjectType() method to determine if the attribute contains a business object (its attribute type is set to the OBJECT attribute-type constant). When a verb operation finds an attribute that is a business object, the method checks the cardinality of the attribute using isMultipleCard(). Based on the results of isMultipleCard(), the method takes one of the following actions:

The Java verb method can access individual business objects by calling CWConnectorBusObj.getObjectCount() to get the number of child business objects in the array. As it iterates through the business object array, the verb method can get each individual child object within the business object array using the CWConnectorBusObj.getBusObjValue(index) method, where index is the array element index. This method returns a CWConnectorBusObj that contains the a child business object. Figure 61 shows the Java code to access child business objects.

Figure 61. Accessing child business objects in a Java connector

// For all attributes in the business object
 for (int i=0; i<theBusObj.getAttrCount()-1; i++ ){
    if ( theBusObj.isObjectType(i) ){
       // cardinality N
       if(theBusObj.isMultipleCard(i)){
          for (int i=0; i < theBusObj.getObjectCount(); i++) {
             CWConnectorBusinessObject childBusObj = 
                theBusObj.getBusObjValue(i);
             status = doVerbMethod(childBusObj);
          } // end for i to getObjectCount()
       } else { 
          // Cardinality 1 child
             CWConnectorBusObj childBusObj = null;
          childBusObj = theBusObj.getBusObjValue(i);
          status = doVerbMethod(childBusObj);
       } // end else 1 cardinality
    } // end isObjectType()
 } // end for i to getAttCount()-1
 

Creating a custom business object handler

The connector framework calls the doVerbFor() method in the CWConnectorBOHandler class (which implements the business object handler) for all verbs that a particular business object supports.Therefore, all verbs in a business object are processed in one standard way (although they can initiate different actions within the application). However, if your connector supports a business object that requires different processing for some particular verb, you can create a custom business object handler to handle that verb for the business object.

Creating a custom business object handler involves the following steps:

Creating the class for the custom business object handler

To create a custom business object handler, you must create a class that implements the CWCustomBOHandler interface. The CWCustomBOHandler interface provides the doVerbForCustom() method, which you must implement to define a custom business object handler. Follow these steps to create a custom-business-object-handler class for a Java connector:

  1. Create a class that implements the CWCustomBOHandler interface. A suggested name this class is:
        connectorNameCustomBOHandlerverbName.java
     
    

    where connectorName uniquely identifies the application or technology with which the connector communicates and verbName identifies the verb (or verbs) that this custom business object handler processes. For example, to create a custom business object handler for the Retrieve verb in a Baan application, you create a custom-business-object-handler class called BaanCustomBOHandlerRetrieve.

  2. In the custom-business-object-handler-class file, define the package name that contains your connector. A connector package name has the following format:
    com.crossworlds.connectors.connectorName
     
    

    where connectorName is the same as defined in step 1 above. For example, the package name for the Baan connector would be defined in the custom-business-object-handler-class file as follows:

    package com.crossworlds.connectors.Baan;
     
    
  3. Ensure that the custom-business-object-handler-class file imports the following classes:
        com.crossworlds.cwconnectorapi.*;
     com.crossworlds.cwconnectorapi.exceptions.*;
     
    

    If you create several files to hold the business object handler's code, you must import these classes into every file.

  4. Implement the doVerbForCustom() method to define the behavior of the business object handler. For more information on how to implement this method, see Implementing the doVerbForCustom() method.

Implementing the doVerbForCustom() method

The doVerbForCustom() method provides the functionality for the custom business object handler. As discussed in Implementing the doVerbFor() method, the connector framework calls the low-level doVerbFor() method (defined in the BOHandlerBase class) for the appropriate business object handler when it receives a request business object. This low-level doVerbFor() method determines which business object handler to call as follows:

The implementation of the doVerbForCustom() method must handle the verb processing of the verb for which its class is specified. You can refer to Implementing the doVerbFor() method for information on the verb processing that the doVerbFor() method usually provides. However, you must customize the behavior of doVerbForCustom() to meet the special processing needs of your business object's verb.

Note:
Unlike the doVerbFor() method, the doVerbForCustom() method is not invoked directly by the connector framework. Instead, the connector framework invokes the low-level doVerbFor(), which in turn invokes doVerbForCustom(). Therefore, doVerbForCustom() cannot include calls to any methods in the CWConnectorBOHandler class.

The low-level doVerbFor() method handles return values and exceptions from doVerbForCustom() as follows:

Adding the verb application-specific information

For the connector framework to call a custom business object handler for a particular business object, the verb of this business object must have the CBOH tag in its verb application-specific information. The CBOH tag has the following format:

CBOH=connectorPackageName.CustomBOHandlerClassName
 

In this format, the connectorPackageName is as follows:

com.crossworlds.connectors.connectorName
 

with connectorName the name of the connector. The CustomBOHandlerClassName is the name of the class that implements the CWCustomBOHandlerInterface interface.

For example, the following CBOH tag specifies a class called BaanCustomBOHandlerRetrieve:

CBOH=com.crossworlds.connectors.Baan.BaanCustomBOHandlerRetrieve
 

Copyright IBM Corp. 1997, 2003