Previous     Contents     Index     DocHome     Next     
iPlanet Unified Integration Framework Developer's Guide



Chapter 4   Programming Concepts


This chapter describes concepts to use the UIF API in your servlets or EJBs.

This chapter contains the following sections:



Programming Model

To execute a transaction from a servlet, your servlet must perform the following actions:

  • Acquiring the UIF runtime object

  • Create a service provider object

  • Create a function object

  • Setting up and executing the function object

The following sections provide examples of how to perform these actions.


Acquiring the UIF Runtime Object

The runtime object is the entry point into UIF. It is both the object factory and the access point for creating other objects.

The following sample shows how to acquire a runtime object:

private IBSPRuntime getRuntime()

{

com.kivasoft.IContext _ctx = ((com.netscape.server.servlet.platformhttp.PlatformServletContext)
getServletContext()).getContext();

   IBSPRuntime ibspruntime = access_cBSPRuntime.getcBSPRuntime
         (_ctx, null, null);
   return ibspruntime;   

}


Service Provider Object Creation

The service provider is a logical representation of a connection to a backend system. Typically, the service provider is not bound to a physical connection until it is absolutely necessary. A service provider must be enabled before it can be used. For an example, see Setting Up and Executing the Function Object.

The following sample shows how to create a service provider object:

private IBSPServiceProvider getServiceProvider(IBSPRuntime runtime)

{

   if (runtime != null)
      return runtime.createServiceProvider("CICS", "CICS_sp1");
   else

   return null;

}

where, "CICS" is the datasource name and "CICS_sp1" is the service provider name defined for that datasource.


Function Object Creation

A function object is a group of related operations that share a common state. In UIF, a function object needs to be set up and associated with a service provider before the function object can be executed. For an example, see Setting Up and Executing the Function Object.

The following sample shows how to create a function object:

IBSPFunctionObject fn = null;

...
{

   fn = runtime.createFunctionObject("CICS", "phonebook");

}

where, "CICS" is the datasource name and "phonebook" is the FunctionObject name in the Repository.


Setting Up and Executing the Function Object

To execute a function object, your servlet must perform the following actions:

  1. Create and enable the service provider

  2. Create the function object and assoicate it to the service provider

  3. Prepare the function object and set the input parameters in the datablock

  4. Execute the function object

  5. Retrieve the output parameters from the function block

  6. Disable the service provider

The following sample shows how to set up and execute a function object.

IBSPDataOataObject getCustomerDetail(String custId)

{

IContext ctx = null;

IBSPServiceProvider sp = null;

IBSPRuntime runtime = null;

IBSPDataObject result = null;

try {

   // Get context

   ctx = ((com.netscape.server.servlet.platformhttp.PlatformServletContext)g etServletContext()).getContext();

   // Get UIF runtime

   runtime = access_cBSPRuntime.getcBSPRuntime(ctx, null, null);

   // Create ServiceProvider 'conn' under datasource 'HR'

   sp = runtime.createServiceProvider("HR", "conn");

   // Enable the ServiceProvider

   IBSPDataobject config = sp.getConfig();

   config.setAttrString("WebUserId", m_UserId);

   sp.enable();

   // Create the target FunctionObject 'getCustomerDetail'

   IBSPFunctionObject fn = runtime.createFunctionObject("HR", "getCustomerDetail");

   // Associate the FunctionObject with the ServiceProvider

   fn.useServiceProvider(sp);

   // Prepare the FunctionObject for execution of operation 'doit'

   fn.prepare("doit");

   // Set inputs in datablock

   IBSPDataObject data = fn.getDataBlock();

   data.setAttrString("INPUT.custId", custId);

   // Execute the FunctionObject

   fn.execute();

   // Retreive outputs from datablock

   result = data.getAttr("OUTPUT.custDetail");

}

// Catch any exception which may be thrown

catch (Exception e)

{

   // Exception actions

}

// Disable the ServiceProvider (regardless of whether an exception was thrown)

finally

{

if (sp != null)

   sp.disable();

}

return result;

}


Executing Multiple Function Objects

An application may need to execute several functions objects or repeatedly execute a single function object within a servlet or EJB. To repeatedly execute a function object, follow these steps:

  1. Prepare the function object

  2. Set the input parameters

  3. Execute the function object

  4. Retrieve the results

  5. Loop as many times as needed

To execute several function objects, the application can create and associate multiple function objects with the same service provider at any point and execute them. Some connectors support transactions (started/terminated by connector specific FunctionObject operations). For these connectors, a transaction context is associated with the service provider instance. All function objects using this service provider instance will execute as part of the transaction assoicated with the service provider at that time



Data Objects



UIF allows you to access data through the data object interface. The data object interface:

  • Presents a unified representation of backend data types

  • Represents complex data

  • Supports most primitive data types

Data objects are built from primitive data types. In general, a primitive data object contains a primitive value, such as an integer or string. A list, array, or data object structures (a complex data object).

Data objects represent data in a hierarchal fashion and circular references are not allowed. UIF only prevents you from adding a data object as an attribute of itself, you are responsible for preventing indirect circular references. If a circular reference is made via another object, it is not discovered when the reference time is established. If a circular reference is used at runtime, unpredictable results occur.

The following diagram shows two primitive data type objects as well as a structure, list, and array object:




Primitive Objects

A primitive data type object contains a single value of one of the following types:

  • Integer, float, double

  • Fixed length string, variable length string

  • Fixed size byte array, variable size byte array

  • Integer, float, and double data type objects hold a value whose type corresponds to the Java data type.

When a primitive data object is assigned to a list, array, or structure, the data object is unwrapped and its value is copied into the list, array, or structure. The data object itself is not used. When a primitive value is obtained by using an untyped get method, such as getField(), getElem(), getAttr(), or getCurrent(), the returned value is wrapped in a primitive data object. In this case, the value is copied, modifying the returned primitive data object does not change the source object.

Strings correspond to the Java String data type. A fixed length string has a maximum length, whereas a variable length string has no length restriction. A fixed size byte array has a maximum size, whereas a variable size byte array has no size restriction.

In general, when a new value is replaces an old value, the old value is released. Thus, when a new value is assigned to a variable length string or a variable size byte array, the old value is released. When a new value is assigned to a fixed length string or a fixed size byte array, the new value is copied over the old one. For a fixed length string, the copied string is truncated to fit if necessary. For a fixed size byte array, a shorter array is zero filled on the right and a longer array is truncated to fit.

The maximum length of a fixed length string and the maximum size of a fixed size byte array are set when they are first set. For example, when you set a list element to contain a fixed length string, the string's maximum size is set when you add the value. In the following example, the maximum length of the fixed length string set to an element in a list is 4 characters:

list.addElemFString("abcd");

If you attempt to replace the string with a five character string ("abcde"), the last character ("e") is truncated.



Note The length of the fixed length string is its maximum length; not its current length, because its current length may be less than its maximum length. The size of a byte array is its maximum size; not its current size, because the byte array may not be filled to capacity.




Structure Objects

Structure objects contain other data objects or primitive values as fields. Each object within the structure object is referred to by a string that represents the field name. Field names have a maximum length of 32 characters. A structure's fields are heterogeneous.


List Objects

A list object contains data objects or primitive values as elements in the list. These elements can be heterogeneous. Each element within a list object is referred to by an integer that specifies its position in the list object.


Array Objects

An array object, like a list object, contains data objects or primitive values as elements in the object. Array objects inherit from list objects. The difference between an array object and a list object is that the array's elements must be homogeneous. Each element within the array object is referred to by an integer that specifies its position in the array object.


Type Info Objects

Type info objects are structure objects that contain the type information of a data object. For example, a type info object might define the fields in a structure and their corresponding data types. Instances of data objects can be created of type info objects. These instances each contain a reference to a type info object. Many data objects can share the same type info object.

DataObjectInfo type

Target object

BSPDataObjectPrimitiveInfo describes the type number, size of value (if type is string or binary), and default value.

IBSPDataObjectPrimitive

IBSPDataObjectStructureInfo describes the type info of all fields of the target structure. The type info of each field is in tern described by a type info object.

IBSPDataObjectStructure

IBSPDataObjectListInfo describes the initial capacity and maximal element count of the target list.

IBSPDataObjectList

IBSPDataObjectArrayInfo describes the initial capacity, maximal element count and the type info of elements of the target array.

IBSPDataObjectArray


API Naming Conventions

Most methods in the API conform to a naming convention that specifies

  • kind of operation: typically, get or set

  • target: a list, structure, and so on

  • type of target: an int, string, and so on

For example, the method that sets an list element from a string is setElemString(). The following table shows the possible combinations:

Operation

Target

Type

get

set

NONE (Primitive)

Attr (complex DataObject, such as a list, array, or structure); uses path to address attribute

Elem (List/Array); uses index to address element

Field (Structure); uses name to address field

Current (Itr); addresses object iterator is currently on.

Int

Float

Double

String

FString

Binary

VBinary

DataObject

NONE


Attributes and Paths

In the API, methods of the IBSPDataObject interface do not distinguish between an element in a list or an array, or a field in a structure. In this case, the element or field is referred to as an attribute.

The path to an element is its element number, beginning with 0. The path to a field is its field name. You may combine element numbers and field names to create paths to attributes in complex data objects. For example, a structure field containing a list of elements. In these cases, you specify the path as the individual attributes separated by dots (.). For example, use "field1.[0]" to identify the first list element at field1 in the structure.


Changing Data Types

If an attribute's type is primitive, it cannot change. For example, the following code causes an error because it tries to change the primitive type from an integer to a float:

list.addElemInt(100); // assume 100 is added to element 1
list.setElemFloat(1, 3.14); // fails because the type of element 1 is int

You can change the data type of a non-primitive data, as in the following example:

list.addElemDataObject(aStruct); // add a structure is to element 1
list.setElemDataObject(1, array); // change to array succeeds


Interface Hierarchy

The following diagram shows the interface hierarchy for data object interfaces:




Previous     Contents     Index     DocHome     Next     
Copyright © 2000 Sun Microsystems, Inc. Some preexisting portions Copyright © 2000 Netscape Communications Corp. All rights reserved.

Last Updated June 08, 2000