Integration Objects - advanced topics
This chapter introduces some topics that are related to advanced uses of Integration Objects.
Customizing Integration Object Java code
When you create an Integration Object from a macro, or when HATS creates an Integration Object automatically when you save a macro, HATS uses Integration Object templates to create the Integration Object. These templates contain the Java code that is included in each Integration Object.
HATS enables you to modify how an Integration Object interacts with the underlying subsystems, at the Java code level, to perform additional functions.
There are two types of Java coding templates: default templates and customizable templates. The templates are stored in the predefined/IOTemplates directory of the HATS Studio toolkit (HATS_install_dir/eclipse/plugins/com.ibm.hats_6.0.0/predefined/ IOTemplates). The default templates are HPubTemplateHODBean.Default and HPubTemplateHODBeanInfo.Default. The customizable templates are HPubTemplateHODBean.Customize and HPubTemplateHODBeanInfo.Customize. The default templates contain Java code that is independent of the HATS and Host On-Demand code. Integration Objects that are created using the default templates do not need to be recompiled and redeployed if the HATS or Host On-Demand code changes for enhancements or service.
The default templates call methods from the superclass. The customizable templates contain the methods, which you can customize. You can modify the HPubTemplateHODBean.Customize template to add function to your Integration Objects. For example, you might want to find out not just the text on the host screen, but also its characteristics, such as color or highlighting.
The customizable templates contain substantial Java code that interacts with the HATS code, Host On-Demand objects, events, and other Java constructs. These templates enable you to modify an Integration Object to perform additional functions. Integration Objects that are created using the customizable templates contain code that directly interacts with the HATS and Host On-Demand code and implements much of the data processing. If any HATS or Host On-Demand code changes affect the code contained in the Integration Object, the Integration Object might have to be recompiled and redeployed.
The templates that are used by HATS are different from those that are used by Host Publisher. If you modified an Integration Object template in Host Publisher, make the same changes to the templates that are provided by HATS and recreate your Integration Objects in order to achieve the same functions in your Integration Objects. When you import or migrate a Host Publisher Integration Object that was created with a modified template, or an application using such an Integration Object, you will see a message indicating that the Java bean was created from a customized template.
Choosing Integration Object templates
If you do not need to modify how Integration Objects interact with HATS or the operating environment, always use the default templates, HPubTemplateHODBean.Default and HPubTemplateHODBeanInfo.Default. You do not need to take any action to use these templates, unless you have previously selected a different template.
If you want Integration Objects to perform additional functions, make a copy of the HPubTemplateHODBean.Customize and HPubTemplateHODBeanInfo.Customize templates and rename them. Modify the new template files to add Java code for the functions you want the Integration Objects to perform.
If you use either the customizable templates or renamed copies of the templates, tell HATS which templates to use when creating Integration Objects. To choose Integration Object templates in HATS Studio, click Window > Preferences. Expand HATS and click Integration Object. Browse to locate the Integration Object templates you want to use.
Choosing Integration Object templates for a bidirectional project
Two templates are provided as additional functions for HATS projects that use bidirectional code pages. These templates are:
- HPubTemplateHODBeanBIDI.Default
- HPubTemplateHODBeanBIDI.Customize
If you create a HATS project that uses a bidirectional code page, HPubTemplateHODBeanBIDI.Default is used by default when you create an Integration Object. If you wish to add customization to your Integration Objects, modify HPubTemplateHODBeanBIDI.Customize and select it on the HATS Preferences page for use in creating Integration Objects.
These templates enable you to specify whether text output by the Integration Object should be reordered. In addition, the data might be retrieved from an application working in Logical mode and displayed by an application working in Visual mode. Therefore, bidirectional reordering for insert and extract can be controlled separately. The following properties are available:
- promptReordering - determines whether data retrieved from a Prompt action should be reordered
- extractReordering - determines whether data retrieved for an Extract action should be reordered
The following methods are supplied to get and set these properties:
public String getPromptReordering(); public String getExtractReordering(); public void setPromptReordering(String value); public void setExtractReordering(String value);where value can be true or false. By default these properties are set to false, so that the Integration Objects behave like those that are created with non-bidirectional templates. However, when you use HATS Studio to create Model-1 Web pages that are based on Integration Objects that were created with these templates, these values are set to true.
Modifying Java coding templates
The HPubTemplateHODBean.Customize and HPubTemplateHODBeanInfo.Customize templates contain Java code that is incorporated into the Integration Object JavaBean code (.java) file when the Integration Object is compiled. The templates also contain constructs specifically for HATS, which are prefaced with a percent sign (%). These constructs enable HATS to create Java beans from the data that is specified by the user when the Integration Object is created. When modifying the template files, be careful not to delete the statements containing the HATS constructs. Make backup copies of the HPubTemplateHODBean.Customize and HPubTemplateHODBeanInfo.Customize templates before you begin making changes to the template files.
For example, suppose that you want to trace the name and the x and y screen coordinates of the Host On-Demand Extract Events that are processed by an Integration Object.
Note:Extraction of the x and y screen coordinates is not available in the Web Services or EJB environments, because the x and y coordinates require access to internal variables that are not available in those environments.Follow these steps:
- Back up the file HPubTemplateHODBean.Customize.
- Change the code that extracts the macro event in HPubTemplateHODBean.Customize to add the following lines after the pullVariableValueFromExtractData( haovWorkOnThis, data);... statement:
// --- Trace X and Y screen coordinates example --- if (HPubTracingOn) { String strg = "Extracting variable: " + stringExtractNameForThisEvent + " from screen location (" + haovWorkOnThis.intXScreenLocation + "," + haovWorkOnThis.intYScreenLocation + ")"; Ras.trace( this.getClass().getName(),"macroExtractEvent", strg); }For example:... public void macroExtractEvent(MacroExtractEvent oMacroExtractEvent) { // a HOD macroExtractEvent was fired for this macro ... pullVariableValueFromExtractData( haovWorkOnThis, data); // --- Trace X and Y screen coordinates example --- if (HPubTracingOn) { String strg = "Extracting variable: " + stringExtractNameForThisEvent + " from screen location (" + haovWorkOnThis.intXScreenLocation + "," + haovWorkOnThis.intYScreenLocation + ")"; Ras.trace( this.getClass().getName(),"macroExtractEvent", strg); }...- Update the HATS preferences to point to your new templates.
- Create an Integration Object as you normally would. If you want to modify an existing Integration Object to trace the name and the screen coordinates of the Host On-Demand Extract Events, re-create the Integration Object by right-clicking on the macro and selecting Create Integration Object. If you introduced Java syntax errors in your template changes, they will show up as compile error messages in the task list.
- Rebuild your HATS project. In the HATS Project view, right click the name of your project and select Rebuild HATS Project.
- If you already have a way to invoke your Integration Object, skip this step. To test your Integration Object, right click the name of the Integration Object and select either Create Model 1 Web pages, Create Struts Web pages, or Create JSF Web Pages. This creates a page from which you can supply the required inputs and invoke your Integration Object.
- Test your modified Integration Object using the Run on Server function. In the HATS Project view, right click the name of your project and select Run on Server.
Example: Modified Integration Object template
Appendix C. Sample modified Integration Object template contains an example Integration Object template, created by adding code to HPubTemplateHODBean.Customize. This example illustrates the use of a custom screen recognition criterion, which is added to the macro within the description of the appropriate screen, to trigger the DoReco() method, which is defined in the template. DoReco() saves all the fields of the host screen in an XML string named extendedxml. A getter method, getExtendedxml(), is provided so that the value can be extracted by a JSP after the Integration Object has been executed. The changes made to the template are marked with the comment // ADDED FOR XML TABLE.
The use of a custom screen recognition criterion, or descriptor, is of particular interest because it enables you to capture the content of any screen that is encountered by the Integration Object. Integration Objects are not notified when the host screen changes or when a screen is recognized. By inserting a custom screen recognition criterion, you can work with any screen.
To invoke the code that has been added to the template, modify the macro from which you will build the Integration Object. Locate the screen whose information you want to capture, and add this line as the last descriptor:
<customreco id="HPubExtractFieldAttributes|" optional="false" invertmatch="false" />Be sure to add it after the other descriptors, so that it is used only on the desired screens; otherwise you might collect data from the wrong screens. Note that the customreco id is "HPubExtractFieldAttributes", but the line added to the macro has "HPubExtractFieldAttributes|". The bar character (|) is used as a separator for parameters and must be included here even though there are no parameters.
If the macro uses the uselogic attribute to combine descriptors, update the uselogic value to include the new descriptor, or it will be ignored. Here is an example of the modifications make to the macro. If the original screen description is:
<screen name="Screen2.2" entryscreen="true" exitscreen="true" transient="false"> <description uselogic="1 and 2" > <oia status="NOTINHIBITED" optional="false" invertmatch="false" /> <string value="Ready; T" row="1" col="1" erow="-1" ecol="-1" casesense="true" optional="false" invertmatch="false" /> </description>Then the screen description with the new descriptor and the modified uselogic is:
<screen name="Screen2.2" entryscreen="true" exitscreen="true" transient="false"> <description uselogic="1 and (2 and 3)" > <oia status="NOTINHIBITED" optional="false" invertmatch="false" /> <string value="Ready; T" row="1" col="1" erow="-1" ecol="-1" casesense="true" optional="false" invertmatch="false" /> <customreco id="HPubExtractFieldAttributes|" optional="false" invertmatch="false" /> </description>When the DoReco() method is called, the template checks whether it is being called to process the "HPubExtractFieldAttributes|" custom descriptor. If so, it captures the information from the screen; if not, it passes control to the parent method to perform screen recognition using one of the other descriptors. After the Integration Object completes, the calling JSP can use the getter method to obtain the XML string and then works with it.
Using Integration Objects in a WebSphere J2EE Application
This section describes how to use Integration Objects in two types of applications:
- A Web container, such as a custom servlet or JSP
- An EJB container
Using an Integration Object in a Web container (custom servlet or JSP)
The instructions in this section refer to Integration Object methods. See Integration Object methods for a description of these methods.
You can create your own Web project that runs Integration Objects. This section lists the steps to move files from your HATS project to another Web project and configure it to run your Integration Objects. This set of steps supports exporting and using one or more individual Integration Objects. If you want to use a chain of Integration Objects, copy all the files as described here and ensure that the Integration Objects run in the correct order.
HATS maintenance is not applied to Integration Objects that are deployed in a separate Web project. The best way to apply maintenance to Integration Objects used in this way is to update the Integration Objects in a HATS project and then re-export them after performing the following steps:
- Create a Web project, if it does not already exist. This is the target project to which you are exporting the Integration Objects. Copy the Integration Object and BeanInfo source files into the Source directory of the Web project. Be sure to keep the IntegrationObject package.
- Copy the profiles directory located at Web Content\WEB-INF\profiles into the WEB-INF directory of the new project. You can copy the entire directory, or you can re-create the directory structure and copy just the connections and macros subdirectories of the profiles directory, with just the connection and macro that are used by the Integration Object. Either way, you need to have these files:
WEB-INF\profiles\application.hap WEB-INF\profiles\connections\ioconn.hco WEB-INF\profiles\macros\iomacro.hma- Edit the application.hap file to remove unnecessary information. Right click the file, select Open with.. and choose the text editor. When you save your changes in the text editor, you will see a message saying that you are saving a resource in a non-workbench encoding. This is because the file is UFT8-encoded, which is required. Click Yes to continue. If you prefer, you can make a backup copy of application.hap before you copy it to the Web project, and edit it using the HATS editor.
The only information application.hap must contain is the connections:
<?xml version="1.0" encoding="UTF-8"?> <application active="true" configured="true" description="" template="Simple1.jsp"> <connections default="ioconn"> <connection name="ioconn"/> <connection name="io2conn"/> </connections> </application>- Add all the jar files that are contained in the HATS EAR file into the classpath of the Web project, by moving them either to your own EAR file, or into the WEB-INF/lib directory of the Web project.
- Copy the runtime.properties file into the same directory where you added the jar files. The location of the logs directory will be in the same directory as the runtime.properties file.
- Add three function calls to initiate the HATS runtime in your servlet or JSP.
// Initialize and activate the HATS runtime RAS functions, // including tracing, logging, PII retrieval, locale. com.ibm.hats.util.Ras.initializeRas(getServletConfig()); // Create the license manager com.ibm.hats.util.LicenseManager.getInstance(); // Initialize Host Publisher / connection management runtime com.ibm.hats.runtime.connmgr.Runtime.initRuntime(getServletConfig());After performing these steps, you can use the Integration Object as a regular JavaBean in your Web project.
To write a servlet that invokes an Integration Object:
- Create an instance of your Integration Object by calling its constructor.
- Invoke the setter methods for the Integration Object to set properties of input variables. The naming convention for setter methods is as follows:
void setXyz(String)where Xyz is the name of your input variable.You can use a different connection pool from the one you specified when you created your Integration Object. To specify a different connection pool, invoke the method:
void setHPubStartPoolName(String)specifying the name of the connection pool you want to use.
- Invoke the Integration Object to perform its task (running a macro, for example):
void doHPTransaction(HttpServletRequest, HttpServletResponse)- Check for errors. The doHPTransaction(HttpServletRequest, HttpServletResponse) method throws an exception (of type com.ibm.HostPublisher.IntegrationObject.BeanException) if the Integration Object has an error.
When the Integration Object is called by a JSP, the JSP processor catches the exception and redirects the browser to the error page that is specified on the errorPage="errorPageName" attribute of the page directive. Refer to the HATS default error page, DefaultErrorPage.jsp, for an example.
When the Integration Object is called by a custom servlet, your code must catch the thrown exception:
try { integrationObject.doHPTransaction(request, response); } catch (Exception e) { // Handle the exception condition and recover }- Request the results from your Integration Object:
- Retrieve the values of output variables by invoking one of the following methods:
- Simple text
String getAbc()where Abc is the name of your output variable.- Tables
- To get an entire column of results, invoke
String[] getAbc()where Abc is the name of your output variable.- To get a single value from a column of results, invoke
String getAbc(int) throws ArrayIndexOutOfBoundsExceptionwhere Abc is the name of your output variable, and int is the index of the value you want. As you iterate through the array, the method throws an ArrayIndexOutOfBoundsException exception when you have reached the end of the array.- Regardless of the application that you used to create your Integration Object, you can retrieve the output data in XML format by invoking the following method:
String getHPubXMLProperties()which returns the IntegrationObject's properties and values as an XML-formatted string.
The input variables for all Integration Objects have getter methods corresponding to each setter method so that you can retrieve those values if necessary. The signature for these methods is
void getXyz(String)where Xyz is the name of your input variable.
To verify input or output variable names that are generated from data that you entered, look at the properties that are defined in your Integration Object's BeanInfo java file. The Integration Object's BeanInfo .java file is in the Source folder of your project in the IntegrationObject package. In HATS Studio, the BeanInfo file is visible only in the Navigator view.
Using an Integration Object in an EJB container (from your own EJB)
The instructions in this section refer to Integration Object methods. See Integration Object methods for a description of these methods.
You can create your own EJB project that runs Integration Objects. This section lists the steps to move files from your HATS project to another EJB project and configure it to run your Integration Objects. This set of steps support exporting and using one or more individual Integration Objects. If you want to use a chain of Integration Objects, copy all the files as described here and ensure that the Integration Objects run in the correct order.
HATS maintenance is not applied to Integration Objects that are deployed in a separate EJB project. The best way to apply maintenance to Integration Objects used in this way is to update the Integration Objects in a HATS project and then re-export them after performing the following steps. In addition, if you export HATS runtime .jar files from a HATS EAR into your project, re-export them if you apply HATS maintenance.
- Create a custom EJB project (File > New > Project > EJB Project). In this example, the project is referred to as My_EJB. Copy the application.hap file to the ejbModule folder of the EJB project.
- In the ejbModule folder of the EJB project, create a folder named connections (File > New > Other , expand Simple and select Folder). Copy to this folder the .hco file that defines the connection that is used by the Integration Object.
- In the ejbModule folder of the EJB project, create a folder named macros. Copy to this folder the .hma file that defines the macro that is used by the Integration Object, as well as any connect or disconnect macros that are required by your connections.
- In the ejbModule folder of the EJB project, create a folder named IntegrationObject. Copy to this folder the Integration Object files (*.java and *BeanInfo.java). At this point you should have these files:
ejbModule\application.hap ejbModule\connections\ioconn.hco ejbModule\macros\*.hma ejbModule\IntegrationObject\*.java- Add all the jar files that are contained in the HATS EAR file into the classpath of the EJB project, by moving them either to your own EAR file, or into the ejbModule directory of the EJB project.
- Copy the runtime.properties file into the same directory where you added the jar files. The location of the logs directory will be in the same directory as the runtime.properties file.
- In the ejbModule\META-INF folder of the EJB project, edit the MANIFEST.MF file and add all the HATS runtime jar files to the dependency list.
- Add these calls to your code to initiate the HATS runtime:
// obj is the EJB object reference, // e.g., com.ibm.hats.util.Ras.initializeRas(this); com.ibm.hats.util.Ras.initializeRas(obj); com.ibm.hats.util.LicenseManager.getInstance(); // appName is a String representing the EJB project // and obj is the EJB object reference // e.g. com.ibm.hats.runtime.Runtime.initRuntime(My_EJB, this); com.ibm.hats.runtime.connmgr.Runtime.initRuntime(appName, obj);To use an Integration Object from a custom EJB:
- Create an instance of your Integration Object by calling its constructor.
- Invoke the setter methods to invoke methods to set properties of input variables. The naming convention for setter methods is as follows:
void setXyz(String)where Xyz is the name of your input variable.- Set the the pool name to the name of the connection pool that the Integration Object will use. Note that the connection name must be qualified with the name of the EJB project. For example:
void setHPubStartPoolName("My_EJB/main");Where My_EJB is the name of the EJB project, and main is the name of the Integration Object's connection pool.- Invoke the Integration Object to perform its task (running a macro, for example), using the method:
void processRequest() throws BeanExceptionThe processRequest() method throws an exception (of type com.ibm.HostPublisher.IntegrationObject.BeanException) if the Integration Object has an error.
You can reset the input variables and invoke the processRequest() method multiple times. The error indications and result values are reset with each invocation.
- Check for errors by invoking:
int getHPubErrorOccurred()If your result is nonzero, an error has occurred. You will have an error exception. To get the specific exception for the error, invoke:Exception getHPubErrorException()You can retrieve the error message by invoking getMessage() on the Exception object. The messages are documented in HATS Messages. Note that the first seven characters are set to HATxxxx or HPSxxxx, where xxxx is the message number.- Request the results from your Integration Object.
- Retrieve the values of output variables by invoking one of the following methods:
- Simple text
String getAbc()where Abc is the name of your output variable.- Tables
- To get an entire column of results, invoke:
String[] getAbc()where Abc is the name of your output variable.- To get a single value from a column of results, invoke:
String getAbc(int) throws ArrayIndexOutOfBoundsExceptionwhere Abc is the name of your output variable, and int is the index of the value you want. As you iterate through the array, the method throws an ArrayIndexOutOfBoundsException exception when you have reached the end of the array.- Regardless of the application that you used to create your Integration Object, you can retrieve the output data in XML format by invoking the following method:
String getHPubXMLProperties()which returns the IntegrationObject's properties and values as an XML formatted string.
The input variables for all Integration Objects have getter methods corresponding to each setter method so that you can retrieve those values if necessary. The signature for these methods is
void getXyz(String)where Xyz is the name of your input variable.
If you are unsure about any input or output variable names that are generated from data that you entered, look at the properties that are defined in your Integration Object's BeanInfo .java source file. The Integration Object's BeanInfo .java source file is in the Source folder of your project in the IntegrationObject package. The BeanInfo file is visible only in the Navigator view.