Previous Contents Index DocHome Next |
iPlanet Application Server Enterprise Connector for PeopleSoft Developer's Guide |
Chapter 3 Programming for the PeopleSoft Connector
To program for PeopleSoft Enterprise connector, you must know how to acquire Unified Integration Framework (UIF) objects and execute functions by using function objects. You also need to know how to use servlets with the iPlanet Application Server Enterprise Connector for PeopleSoft to access functions on a PeopleSoft EIS. This chapter includes the following information:
About Data Objects
About Data Objects
Data objects contain data and metadata, which you can access through the data object interface. The UIF data object interface features:
Present a unified representation of backend data types
Data objects are built from primitive types like integer or string. Arrays and structures are complex data objects.The types of data objects are:
Primitive Objects
UIF data objects represent data in a hierarchal fashion. Circular references are not allowed because the iPlanet Application Server for PeopleSoft prevents a data object from being used as an attribute of itself. Indirect circular references are not checked by iPlanet Application Server for PeopleSoft and can cause unpredictable results at runtime.
Primitive Objects
A primitive data type object contains a single value of one of the following types:
Integers, floats, and doubles
Figure 3-1    Primitive Object ![]()
Integers, floats, and doubles
Integer, float, and double data type objects hold values whose types corresponds to the same 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. 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 with a primitive data object. In this case, the value is copied, thus, modifying the returned primitive data object.
Fixed length strings and variable length strings
Strings correspond to the Java string data type. A fixed length string has a maximum length, whereas a variable length string has no restrictions on its length.
Fixed size byte arrays and variable size byte arrays
A fixed size byte array has a maximum size, whereas a variable size byte array has no restriction on its size.When a new value 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. In the case of a fixed length string, the copied string is truncated to fit, if necessary. In the case of a fixed size byte array, a shorted 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 the string's initial value is specified; for example, it is four characters in the following example:
If you use a five character value, the value is truncated to four characters.
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 64 characters. A structure's fields are heterogeneous.
Figure 3-2    Structure Object ![]()
Array Objects
An array 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.
Figure 3-3    Array Object ![]()
Type Information Objects
Type information objects are structured objects that contain the type information of a data object. For instance, a type information object might define the fields in a structure and their corresponding data types. Instances of data objects can be created of type information objects. Each of these instances contain a reference to a type of information object. Numerous data types can share the same type information object.
UIF Naming Conventions
Methods in the Unified Integration Framework API conform to a naming convention that specifies:For instance, in the following example:
Operation
There are many types of operations but the two most commonly used are:
None (primitive)
Attr (complex DataObject such as a list, array, or structure), which uses a path to address the attribute.
Elem (list/array), which uses index to address element
Field (structure), which uses name to address field
Current (itr), which addresses object iterator is currently on
Type
The types of operations are:
Attributes and Paths
In the API, methods of the IBSPDataObject interface do not distinguish between an element in an array and 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 from zero. 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, such as a field of a structure that contains a list of elements. In this case, you specify the path as the individual attributes separated by periods (.); i.e. use "field1.[01]" to identify the first element of a list 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 type of a primitive 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 is int
You can change the data type of non-primitive, as in the following example:
list.addElemDataObject(aStruct) ; // add a structure is to element 1
list.setElemDataObject (1, array) ; // change to array succeeds
Working with Servlet Samples
The following procedures are required to execute a PeopleSoft transaction from a servlet:
Acquiring the UIF Runtime Object and Mapping it to the Connector
Acquiring the UIF Runtime Object and Mapping it to the Connector
The runtime object is the entry point into UIF. It is both the object factory and the point for creating other objects. Following is an example of how to acquire a runtime object.
Creating the Service Provider Object
The service provider is the 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 you can use it.A service-provider type represents a connection to a backend PeopleSoft system. It contains configuration information such as the kinds of data required to create a connection, like, host, port, username, and password. A service provider type may also specify additional information it requires to manage a connection. The following diagram shows the fields of a service provider template
Figure 3-4    Service Provider Types
Following is a code sample that illustrates how to create a service provider object.
Note that in the following code line from the example,
return runtime.createServiceProvider("PSFT", "connection");
the first parameter, PSFT, is the data source name and the second parameter, connection, is the service provider name.
Creating a Function Object
A function object is a group of related operations that share a common state. In the PeopleSoft connector, a function object must be set up and associated with a service provider before you can use the function object.A function item type represents the logical business functions that are available on a data source like, a stored procedure, a prepared query for a relational database data source, or a transaction in a PeopleSoft system. A function object type defines one or more operations on a transaction. Each operation represents an action you can execute on the backend system. The function object type specifies the service provider type it requires for execution.
The following diagram shows the parts of a function object type.
Figure 3-5    Function Object Type
The following is a code example of how to create a function object.
Note that in the following code line from the example,
fn = runtime.createFunctionObject("PSFT", "UpdateEmployeeDetails.DisplayEmployeeDetails.SearchDialog")
the first parameter, PSFT, is the data source name and the parameter, "UpdateEmployeeDetails.DisplayEmployeeDetails.SearchDialog", is the service provider name.
Running a Function Object
You must perform the following steps to use a function object:
Specify and enable the service provider.
The following code sample illustrates these steps.Initialize the function object by creating the property set and input parameters.
Employee Details Sample
The Employee Details Sample consists of PeopleSoft programs that access Oracle databases. You can run this sample on the Windows NT or Sun Solaris platforms. However, before you run the samples that come with the PeopleSoft Enterprise Connector, you must build the message definition, described in Building Message Definitions.
To run the Employee Details Sample on NT
From the Start menu, select Programs > iPlanet Application Server 6.0 > PEOPLESOFT Connector -Start Worker Process.
To run the Employee Details Sample on Solaris
From <iPlanet Install directory>/ias/APPS/bin, type:
Press Enter.
Click on: To Start The ProcessMsg Demo link
- The PSFT Employee Details Samples appears, showing links to the ProcessMsg and SearchDialog samples.
To start the demo click on the link: To Start The ProcessMsg Demo.
Type in the information in the text fields and click on Execute.
![]()
After the data finishes processing the ProcessMsg End Form appears.
![]()
To Start the SearchDialog Demo
Code Samples
Following are the code listings for the Process Message and Search Dialog samples.
Code Example 3-7 SearchDialog Execute.Java package SearchDialog; import java.io.*; import java.util.*; import javax.naming.*; import netscape.bsp.*; import netscape.bsp.runtime.*; import netscape.bsp.dataobject.*; public class Execute { private TestDebug deb = new TestDebug("Execute"); public com.kivasoft.IContext _ctx=null; //SELECTED OPERATION public String DataSourceName=""; public String FunctionName=""; public String ServiceProviderName=""; public String OperationName=""; public String PropertiesPath=""; //DATA public class cINPUT { public String EMPLID = null; public String NAME = null; public String LAST_NAME_SRCH = null; public String SETID_DEPT = null; public String DEPTID = null; public String NAME_AC = null; } public cINPUT INPUT=new cINPUT(); public class cOUTPUT { public class cPERSON_SRCH { public String EMPLID = null; public Integer EMPL_RCD = null; public String NAME = null; public String LAST_NAME_SRCH = null; public String SETID_DEPT = null; public String DEPTID = null; public String NAME_AC = null; } public cPERSON_SRCH[] PERSON_SRCH=null; public void add_PERSON_SRCH_elements(int attrCount) { PERSON_SRCH=new cPERSON_SRCH[attrCount]; for(int i=0;i<attrCount;i++) PERSON_SRCH[i]=new cPERSON_SRCH(); } } public cOUTPUT OUTPUT=new cOUTPUT(); public class cPropertySet { public class cProcessingMessages { public String ACTIVITY = null; public String MsgDefinition = null; public Integer MAXRECORDS = null; public Integer OperationType = null; public String RecordName = null; } public cProcessingMessages ProcessingMessages=new cProcessingMessages(); } public cPropertySet PropertySet=new cPropertySet(); public Execute(String path) throws Exception , BspException { //read properties file PropertiesPath=path; FileInputStream propertiesFile=new FileInputStream(PropertiesPath+"//SearchDialog//Execute.properties"); Properties properties=new Properties(); properties.load(propertiesFile); FunctionName= properties.getProperty("FunctionName"); deb.println("FunctionName="+FunctionName); OperationName= properties.getProperty("OperationName"); deb.println("OperationName="+OperationName); String LocalServiceProviderName= properties.getProperty("LocalServiceProviderName"); deb.println("LocalServiceProviderName="+LocalServiceProviderName); FileInputStream sp_propertiesFile=new FileInputStream(PropertiesPath+"//"+LocalServiceProviderName+".properties"); Properties sp_properties=new Properties(); sp_properties.load(sp_propertiesFile); DataSourceName= sp_properties.getProperty("DataSourceName"); deb.println("DataSourceName="+DataSourceName); ServiceProviderName= sp_properties.getProperty("ServiceProviderName"); deb.println("ServiceProviderName="+ServiceProviderName); } private IBSPRuntime getRuntime() throws BspException { deb.println(" before access_cBSPRuntime.getcBSPRuntime "); IBSPRuntime ibspruntime = access_cBSPRuntime.getcBSPRuntime(_ctx, null, null); deb.println(" after access_cBSPRuntime.getcBSPRuntime "); return ibspruntime; } private IBSPServiceProvider getServiceProvider(IBSPRuntime runtime) throws BspException { deb.println("Before createServiceProvider()"); if (runtime != null) return runtime.createServiceProvider(DataSourceName, ServiceProviderName); else deb.println("runtime is null"); return null; } public void execute () throws Exception , BspException { IBSPFunctionObject fn = null; IBSPDataObject data = null, prop = null; IBSPServiceProvider sp =null; int hr = 1; try { deb.println("Before sendRequest "); deb.println(" Before getRuntime()"); IBSPRuntime runtime = getRuntime(); deb.println("After getRuntime()"); if( runtime != null ) { deb.println("Before getServiceProvider()"); sp = getServiceProvider(runtime); deb.println("After getServiceProvider()"); if( sp != null ) { deb.println("Before createFunctionObject()"); fn = runtime.createFunctionObject(DataSourceName, FunctionName); deb.println("After createFunctionObject()"); hr = sp.enable(); deb.println("After enable(), hr = "+hr); if(hr!=0) return; deb.println("After enable(), hr = "+hr); if( fn != null ) { hr = fn.useServiceProvider(sp); deb.println("After useServiceProvider(), hr = "+hr); if(hr!=0) return; hr = fn.prepare(OperationName); deb.println("After prepare(), hr = "+hr); if(hr!=0) return; data = fn.getDataBlock(); deb.println("After getDataBlock()"); if( data != null ) setInputData(data); prop = fn.getProperties(); deb.println("After getProperties()"); if( prop != null ) setInputProperties(prop); deb.println("Before execute()"); hr = fn.execute(); deb.println("After execute(), hr = "+hr); if( hr == 0 ) { data = fn.getDataBlock(); deb.println("After getDataBlock()"); if(data != null ) getOutputData(data); prop = fn.getProperties(); deb.println("After getProperties()"); if(prop != null) getOutputProperties(prop); } // if(hr == 0) else deb.println("Execute Failed"); } // if(fn != null) else deb.println("Create function object Failed"); } // if( sp != null ) else deb.println("Create service provider Failed"); hr = sp.disable(); deb.println("After disable(), hr = "+hr); } else deb.println("Create runtime Failed"); deb.println("after sendRequest "); } catch(BspException BspError) { if(sp!=null) { hr = sp.disable(); deb.println("After disable(), hr = "+hr); } throw (BspError); } catch(Exception ex) { if(sp!=null) { hr = sp.disable(); deb.println("After disable(), hr = "+hr); } throw (ex); } return; } public void setInputData(IBSPDataObject data) throws BspException { if(INPUT.EMPLID != null) data.setAttrFString("INPUT.EMPLID",INPUT.EMPLID); if(INPUT.NAME != null) data.setAttrFString("INPUT.NAME",INPUT.NAME); if(INPUT.LAST_NAME_SRCH != null) data.setAttrFString("INPUT.LAST_NAME_SRCH",INPUT.LAST_NAME_SRCH); if(INPUT.SETID_DEPT != null) data.setAttrFString("INPUT.SETID_DEPT",INPUT.SETID_DEPT); if(INPUT.DEPTID != null) data.setAttrFString("INPUT.DEPTID",INPUT.DEPTID); if(INPUT.NAME_AC != null) data.setAttrFString("INPUT.NAME_AC",INPUT.NAME_AC); } public void getOutputData(IBSPDataObject data) throws BspException { IBSPDataObjectArray outputArray=(IBSPDataObjectArray )(data.getAttrDataObject("OUTPUT.PERSON_SRCH")); int attrCount=outputArray.getAttrCount(); OUTPUT.add_PERSON_SRCH_elements(attrCount); for(int i=0;i<attrCount;i++) { deb.println("before get element"+i); OUTPUT.PERSON_SRCH[i].EMPLID = data.getAttrFString("OUTPUT.PERSON_SRCH.["+i+"].EMPLID"); OUTPUT.PERSON_SRCH[i].EMPL_RCD = new Integer(data.getAttrInt("OUTPUT.PERSON_SRCH.["+i+"].EMPL_RCD")); OUTPUT.PERSON_SRCH[i].NAME = data.getAttrFString("OUTPUT.PERSON_SRCH.["+i+"].NAME"); OUTPUT.PERSON_SRCH[i].LAST_NAME_SRCH = data.getAttrFString("OUTPUT.PERSON_SRCH.["+i+"].LAST_NAME_SRCH"); OUTPUT.PERSON_SRCH[i].SETID_DEPT = data.getAttrFString("OUTPUT.PERSON_SRCH.["+i+"].SETID_DEPT"); OUTPUT.PERSON_SRCH[i].DEPTID = data.getAttrFString("OUTPUT.PERSON_SRCH.["+i+"].DEPTID"); OUTPUT.PERSON_SRCH[i].NAME_AC = data.getAttrFString("OUTPUT.PERSON_SRCH.["+i+"].NAME_AC"); deb.println("after get element"+i); } } public void setInputProperties(IBSPDataObject prop) throws BspException { if(PropertySet.ProcessingMessages.ACTIVITY != null) prop.setAttrFString("ProcessingMessages.ACTIVITY",PropertySet.ProcessingMessag es.ACTIVITY); if(PropertySet.ProcessingMessages.MsgDefinition != null) prop.setAttrFString("ProcessingMessages.MsgDefinition",PropertySet.ProcessingM essages.MsgDefinition); if(PropertySet.ProcessingMessages.MAXRECORDS != null) prop.setAttrInt("ProcessingMessages.MAXRECORDS",PropertySet.ProcessingMessages .MAXRECORDS.intValue()); if(PropertySet.ProcessingMessages.OperationType != null) prop.setAttrInt("ProcessingMessages.OperationType",PropertySet.ProcessingMessa ges.OperationType.intValue()); if(PropertySet.ProcessingMessages.RecordName != null) prop.setAttrFString("ProcessingMessages.RecordName",PropertySet.ProcessingMess ages.RecordName); } public void getOutputProperties(IBSPDataObject prop) throws BspException { PropertySet.ProcessingMessages.ACTIVITY = prop.getAttrFString("ProcessingMessages.ACTIVITY"); PropertySet.ProcessingMessages.MsgDefinition = prop.getAttrFString("ProcessingMessages.MsgDefinition"); PropertySet.ProcessingMessages.MAXRECORDS = new Integer(prop.getAttrInt("ProcessingMessages.MAXRECORDS")); PropertySet.ProcessingMessages.OperationType = new Integer(prop.getAttrInt("ProcessingMessages.OperationType")); PropertySet.ProcessingMessages.RecordName = prop.getAttrFString("ProcessingMessages.RecordName"); } } Search Dialog Demo Code Examples">
Building Message Definitions
Message Definitions are the metadata, which describe the format of data associated with a particular PeopleSoft panel. This section includes procedures for building your own message definitions. Follow these to create the message definition that you must use to run the sample that is provided with the Peoplesoft Enterprise Connector.For more information on PeopleSoft application development, go to the PeopleSoft web site at:
http://www.peoplesoft.com/en/tools_technology/index.html
You build message definitions by using the following procedures:
To create a project
To define a new employee record field
To add existing fields to your project
To define a panel group for this panel
Select Start > Programs > PeopleSoft 7.5 > Application Designer.
Type in your Operator ID and Password and click on the OK button.
Select File > New.
Select Tool > Options.
Select When Object is modified and saved from the Insert Object into Project radio button group.
Select Do not insert related objects with current object radio button from the Related Objects Options radio button group.
To define a new employee record field
You must include the new field, EMPL_RCD, to run the samples.
Select File > Open > Field.
Select Number from the drop-down list and click OK.
Dismiss the dialog box.
Select File > Save As and type EMPL_RCD in the Save Name As field of the dialog box. .
![]()
Click OK to save the new field.
Select File > Save Project As.
Type DEMO_PROJECT in the Save Name As text box and then click OK.
![]()
To add existing fields to your project
Select File > Open > Field.
Type EMPLID into the Name text field.
Double-click a field to open the field definition dialog box.
- A list of all fields that start with that prefix appear. If there is only one field with the prefix, the field definition dialog box opens.
![]()
Press <F7> to insert the currently selected object into the project.
Select each of the following fields to insert into the project.
Select File > New > Record.
Drag the fields to the new record.
![]()
Select File > Save As.
Type in the new record name and click the OK button.
![]()
Select View > Use Display to see the new record.
Select the EMPLID field, click the right mouse button, and select Record Field Properties from the drop-down menu.
![]()
Mark the following checkboxes:
Click the OK button.
Check the appropriate boxes for each field, according to the following table.
Table 3-2 Message Definition Options
EMPLID
EMPL_RCD
OPRCLASS
ACCESS_CD
NAME
LAST_NAME_SEARCH
SETID_DEPT
DEPTID
NAME_AC
NID_COUNTRY
NATIONAL_ID_TYPE
NID_DESCRSHORT
NATIONAL_ID
Note Alt - check the Alternate Search Key check box
Select Tools > DataAdministration > Set_TableSpace.
Click on Set_TableSpace to display the Select Tools data administrator.
![]()
Click on Set_TableSpace to display the Change Space dialog box.
![]()
Select a record.
Select Build > Current Object to display the Build dialog box.
![]()
To build the new record, click the Build button.
Select File > New > Panel and click OK.
Drag the fields from the record onto the panel.
![]()
In the Save As dialog box, type in the Panel name and then click OK..
![]()
To define a panel group for this panel
Select New > File > Panel Group and then click OK.
Drag the panels you want to include in the panel group, to the Panel Group window.
![]()
Select the Property icon and click on the Use tab.
![]()
From the Search record drop-down menu, select the Record you defined in the previous step.
Select the checkboxes for the Actions you want to use.
In the Save As dialog box, type the Panel Group name, select the Market type from the drop-down list., and click on OK.
![]()
Select File > New > Menu and click OK.
In the New Menu dialog box, select the Standard radio button, and click OK.
![]()
Double-click on the menu bar that appears, to open the Menu Item Properties dialog box.
![]()
Type Use in the Name and Label text boxes and then click OK.
Drag the panel group to the menu item.
![]()
In the Save As dialog, type in the Menu name, and click OK..
![]()
To define a new business process
Select File > New > Business Process and click OK.
Drag an activity to the workspace.
When the Activity is at the location you want, click the left mouse button to display the Activity Choice dialog box.
![]()
Select the Create New Activity radio button and click OK.
Select the Activity tool and then click the right mouse button.
Type in the activity definition and then click OK.
![]()
Click the OK button to create a business process.
Drag the Message Definition icon onto the worksheet.
![]()
Click the right mouse button and type the Message Definition name.
![]()
Type in the Message Definition name.
Press the Attribute button and select the fields from the Message Attribute dialog box drop-down lists.
![]()
Press the Level Mapping button and select the appropriate radio buttons and checkbox.
![]()
Click on the Field Mapping button.
Type in the Field name and then click OK.
The following table is the end result of the complete process.
![]()
Note EmplId and OperClass must be selected from the Search Record.
Previous Contents Index DocHome Next
Copyright © 2000 Sun Microsystems, Inc. Some preexisting portions Copyright © 2000 Netscape Communications Corp. All rights reserved.
Last Updated June 13, 2000