Adding business logic

Business logic is any Java™ code that is invoked as an action when an event occurs, such as a host screen being recognized or your ZIETrans application being started. Business logic is specific to the application and is not provided as part of ZIETrans. You can use business logic to extend your ZIETrans application to integrate with other data sources, such as a database or an Integration Object. For example, you can read the contents of a file or a database into ZIETrans global variables and use the global variables to fill in a drop-down list or pop-up to be used in the application's GUI pages.

ZIETrans automatically updates your class loader policy when you include ZIETrans business logic in your ZIETrans Web project. This updates the default WAR class loader policy of your ZIETrans application to Single class loader for application.

You can create business logic and add it to your project using the Create Business Logic wizard. To invoke this wizard, right-click in the ZIETrans Projects tab of the ZIETrans Toolkit, and click New ZIETrans > Business Logic.

In the Create Business Logic wizard, specify the project you want to add the business logic to and supply the Java class name. The default package name is projectName.businessLogic, but you can change this in Studio Preferences. Optionally, you can supply a package name or click Browse to select an existing Java package. If you want your business logic to include methods for easy access to the project global variables, or to remove project global variables, select the Create global variable helper methods check box. Click Finish when you have provided the required information.

After you create your business logic class, you will want to link it to one or more screen or application events so it is executed when that event occurs. Edit each event (application event or screen customization) to which you want to add the link. On the Actions tab, click Add, select Execute business logic, then fill in the details for your business logic class. Refer to ZIETrans User's and Administrator's Guide for information about editing both screen customization and events.

You can see the business logic files in the project by expanding the Source folder on the ZIETrans Project View tab of the ZIETrans Toolkit. Each package name or class name appears in the Source folder. Expand the package name folder to see the Java class name. Click the class name to edit the class. The Source folder can also include other Java files that have been imported into your ZIETrans project.

If you use the Create Business Logic wizard to create business logic, the method that is invoked by the execute action is named execute by default. If you write your own class, the method must have the following attributes:

The method must use this form, followed by your own business logic code:

public static void myMethod (IBusinessLogicInformation businesslogic)

The IBusinessLogicInformation object that is passed to your custom Java code enables you to access and use or modify various objects and settings of your ZIETrans project. These include:

For more information about the classes made available to you, see the ZIETrans API documentation in the ZIETrans Infocenter at https://zietrans.hcldoc.com/help/index.jsp for the IBusinessLogicInformation class. Since IBusinessLogicInformation extends the IBaseInfo class, several of these APIs are defined in the IBaseInfo class.

Incorporating Java code from other applications

You can incorporate Java code from other existing applications into your ZIETrans projects in a variety of ways.

If you want to incorporate the source code (.java files) from your existing business logic so you can modify the code, you can import the .java files into the Source folder in your existing project. Click File > Import > General > File System to open the Import wizard. In the Import wizard, select the location of your source files in the From directory field. For Web projects, select the Java Source folder of your project in the destination Into folder entry field. When your source .java files are imported, they are automatically compiled and packaged into your ZIETrans project. You can edit, set breakpoints, and debug your source files in the Rational® SDP workbench.

You can also incorporate a Java archive (.jar) file with compiled Java business logic. The entire Java archive is added; you cannot select individual classes to add.

  1. Import the .jar file into the ZIETrans EAR project.
    1. Click File > Import > General > File System to open the Import wizard.
    2. Select the source directory of the Java archive (.jar) you want to import in the From directory field.
    3. Select the .jar file from the right pane.
    4. Select your ZIETrans EAR project as the destination in the Into folder field.
    5. Click Finish.
    6. When your .jar file is imported, click the Navigator tab of the ZIETrans Toolkit and expand your ZIETrans ear project. You will see the imported java archive file.
  2. Add a java archive to the project build path.
    1. In the Navigator tab of the ZIETrans Toolkit, select the project in which you want to invoke your business logic.
    2. Right-click the high-level ZIETrans project, and select Properties.
    3. In the Properties window, select Java Build Path in the left table and click the Libraries tab on the right.
    4. Click Add JARs to open the JAR Selection window.
    5. Expand the ZIETrans EAR project, and select the newly imported Java archive file.
    6. Click OK in the JAR Selection window, and click OK in the Properties window.
    7. Repeat this process for all ZIETrans projects for which you want to use the business logic.
  3. Define the project where the business logic is to be invoked.
    1. In the Navigator tab of the ZIETrans Toolkit, again select the project in which you want to invoke your business logic.
    2. Expand the project, the Web Content folder, and the META-INF folder.
    3. Double-click the MANIFEST.MF file to open the JAR dependencies editor. Select the check box next to each .jar file that you want to include in your project's class path.

There are other ways to import Java archives into the ZIETrans project. ZIETrans projects are extensions of Web projects in the Rational SDP workbench. For more information about importing files into Web projects, open the Rational SDP Help and search for Web projects

Using global variables in business logic

If your ZIETrans application uses global variables to store information, you can use these global variables in your business logic.

There are two types of global variables: local and shared. A local global variable is one that is created within a ZIETrans project and is only visible to the project. A shared global variable is one that is visible to and can be used by all the applications in an EAR file. There are also two lists of ZIETrans global variables, one for local global variables and one for shared global variables. Two global variables with the same name can coexist if one is local and the other is shared.

When you create your business logic class, use the Create Business Logic wizard and select the Create global variable helper methods check box. This creates methods in your business logic for getting, setting, and removing local and shared global variables.

The following methods are created:

////////////////////////////////////////////////////////////////////////////////
//  This sample is provided AS IS.
//  Permission to use, copy and modify this software for any purpose and
//  without fee is hereby granted. provided that the name of IBM not be used in
//  advertising or publicity pertaining to distribution of the software without
//  specific written permission.
//
//  IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SAMPLE, INCLUDING ALL
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL IBM
//  BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
//  DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
//  IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
//  OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SAMPLE.
////////////////////////////////////////////////////////////////////////////////
/**
	* Example method that sets a named global variable 
	* from the current session to a value
	* @param blInfo - IBusinessLogicInformation from current session
	* @param name - Name of the global variable
	* @param value - Value of the global variable
	*/
public static void setGlobalVariable(IBusinessLogicInformation blInfo,
					String name,Object value)
{
		IGlobalVariable gv = blInfo.getGlobalVariable(name);
		if ( gv == null )
			{
				gv = new GlobalVariable(name,value);
			}
		else
			{
				gv.set(value); 
			}
		blInfo.getGlobalVariables().put(name,gv);
}

/**
	* Example method that sets a named shared
	* global variable from the current session to a value
	* @param blInfo - IBusinessLogicInformation from current session
	* @param name - Name of the shared global variable
	* @param value - Value of the shared global variable
	*/ 
public static void setSharedGlobalVariable(IBusinessLogicInformation 
		blInfo,String name,Object value)
{
		IGlobalVariable gv = blInfo.getSharedGlobalVariable(name);
		if ( gv == null )
			{
				gv = new GlobalVariable(name,value);
			}
		else
			{
				gv.set(value); 
			}
		blInfo.getSharedGlobalVariables().put(name,gv);
}

/**
	* Example method that removes a named global variable from the current session
	* @param blInfo - IBusinessLogicInformation from current session
	* @param name - Name of the global variable
*/
public static void removeGlobalVariable(IBusinessLogicInformation blInfo, String  name)
{
		IGlobalVariable gv = blInfo.getGlobalVariable(name);
		if ( gv != null )
			{
				blInfo.getGlobalVariables().remove(name);
				gv.clear();
				gv = null;
			}
}
/**
	* Example method that removes a named shared global variable from the current session
	* @param blInfo - IBusinessLogicInformation from current session
	* @param name - Name of the shared global variable
*/
public static void removeSharedGlobalVariable(IBusinessLogicInformation blInfo, String name)
{
		IGlobalVariable gv = blInfo.getSharedGlobalVariable(name);
			if ( gv != null )
				{
					blInfo.getSharedGlobalVariables().remove(name);
					gv.clear();
					gv = null;
				}
}
/**
	* Example method that retrieves a named global variable from the current session
	* @param blInfo - IBusinessLogicInformation from current session
	* @param name - Name of the global variable
	* @return - an instance of the global variable, or null if not found.
	*/
public static IGlobalVariable getGlobalVariable(IBusinessLogicInformation 
		blInfo,String name)
{ 
		IGlobalVariable gv = blInfo.getGlobalVariable(name);
		return gv;
}

/**
	* Example method that retrieves a named shared 
	* global variable from the current session
	* @param blInfo - IBusinessLogicInformation from current session
	* @param name - Name of the shared global variable
	* @return - an instance of the global variable, or null if not found.
	*/
public static IGlobalVariable getSharedGlobalVariable(IBusinessLogicInformation 
		blInfo,String name)
{ 
		IGlobalVariable gv = blInfo.getSharedGlobalVariable(name);
		return gv;
}

Elsewhere in your code, when you need the value of a local global variable, you can call this method:

  GlobalVariable gv1 = getGlobalVariable(blInfo,"varname");

To get the value of a shared global variable, use the following method:

  GlobalVariable gv1 = getSharedGlobalVariable(blInfo,"varname");

Business logic examples

This section contains examples of using business logic. Each works with global variables. Each example uses one or more of the global variable helper methods previously described, and the classes should include those methods. They are omitted in these examples to make it easier to view the example code.

Example: Date conversion

This example converts a date from mm/dd/yy format to month, day, year format. For example, the example converts 6/12/2004 into June 12, 2004. The example assumes that the global variable theDate has been set before the business logic is called. Note how the example uses the following method to obtain the value of the input variable:

IGlobalVariable inputDate = getGlobalVariable(blInfo, "theDate");

After using standard Java functions to manipulate the string to represent the date in the desired format, the example uses the following method to put the new string into the same global variable:

setGlobalVariable(blInfo, "theDate", formattedDate);

////////////////////////////////////////////////////////////////////////////////
//  This sample is provided AS IS.
//  Permission to use, copy and modify this software for any purpose and
//  without fee is hereby granted. provided that the name of IBM not be used in
//  advertising or publicity pertaining to distribution of the software without
//  specific written permission.
//
//  IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SAMPLE, INCLUDING ALL
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL IBM
//  BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
//  DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
//  IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
//  OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SAMPLE.
////////////////////////////////////////////////////////////////////////////////
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.ibm.hats.common.IBusinessLogicInformation;
import com.ibm.hats.common.GlobalVariable;
import com.ibm.hats.common.IGlobalVariable;

public class CustomDateFormatter
{
 		public static void execute(IBusinessLogicInformation blInfo)
			{
				IGlobalVariable inputDate = getGlobalVariable(blInfo, "theDate");
				SimpleDateFormat inputFormat = new SimpleDateFormat("MM/dd/yyyy");
				SimpleDateFormat outputFormat = new SimpleDateFormat("MMMM dd, yyyy");
       		
				try 
					{
						Date tempDate = inputFormat.parse(inputDate.getString().trim()); 
						String formattedDate = outputFormat.format(tempDate); 
						setGlobalVariable(blInfo, "theDate", formattedDate);
					} 
						catch (ParseException ex) 
							{
								ex.printStackTrace();
							}
			}
}

Example: Adding values that are contained in an indexed global variable

This example adds the values that are contained in an indexed global variable and stores the sum in another, non-indexed global variable. It assumes that you have stored strings representing numbers in the indexed global variable subtotals.

The previous example included the names of the input and output global variables (theDate) on the set calls. This example sets the names of the input and output variables into local string variables and uses those strings on calls to get and set the global variable values. Because the name of the global variable is being passed as a variable, it is not put into quotes:

setGlobalVariable(blInfo,gvOutputName, new Float(myTotal));

////////////////////////////////////////////////////////////////////////////////
//  This sample is provided AS IS.
//  Permission to use, copy and modify this software for any purpose and
//  without fee is hereby granted. provided that the name of IBM not be used in
//  advertising or publicity pertaining to distribution of the software without
//  specific written permission.
//
//  IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SAMPLE, INCLUDING ALL
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL IBM
//  BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
//  DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
//  IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
//  OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SAMPLE.
////////////////////////////////////////////////////////////////////////////////
import com.ibm.hats.common.IBusinessLogicInformation;
import com.ibm.hats.common.GlobalVariable;
import com.ibm.hats.common.IGlobalVariable;

  public static void execute(IBusinessLogicInformation blInfo)
    {
    	// Name of indexed global variable to be read in
        String gvInputName = "subtotals";
        // Name of global variable to be calculated and saved
        String gvOutputName = "total";
        
        // The indexed global variable where each index is a subtotal to be summed
        GlobalVariable gvSubtotals = 
					((GlobalVariable)getGlobalVariable(blInfo, gvInputName));
        
        float myTotal = 0;
        
        // Calculate the total by adding all subtotals
        for (int i = 0; i < gvSubtotals.size(); i++)
        {
        	myTotal = myTotal + Float.valueOf(gvSubtotals.getString(i)).floatValue();
        }
		
        // Save the total as a non-indexed local variable
        setGlobalVariable(blInfo,gvOutputName, new Float(myTotal));
    }

Example: Reading a list of strings from a file into an indexed global variable

This example reads a file from the file system and stores the strings in the file into an indexed global variable. You can use a technique like this to read a file that contains, for example, a list of your company's locations. After storing the strings in a global variable, you can use the global variable to populate a drop-down list or other widget to enable users to select from a list of values. You can create a global rule to use this widget wherever an appropriate input field occurs. To make sure that the global variable is available as soon as the application is started, add the execute action for this business logic class to the Start event.

Note:
If your text file has carriage returns and line feeds between lines, you might need to use "\r\n" as the second argument of the StringTokenizer constructor call in the following example.

////////////////////////////////////////////////////////////////////////////////
//  This sample is provided AS IS.
//  Permission to use, copy and modify this software for any purpose and
//  without fee is hereby granted. provided that the name of IBM not be used in
//  advertising or publicity pertaining to distribution of the software without
//  specific written permission.
//
//  IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SAMPLE, INCLUDING ALL
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL IBM
//  BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
//  DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
//  IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
//  OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SAMPLE.
////////////////////////////////////////////////////////////////////////////////
import com.ibm.ejs.container.util.ByteArray;
import com.ibm.hats.common.IBusinessLogicInformation;
import com.ibm.hats.common.GlobalVariable;
import com.ibm.hats.common.IGlobalVariable;

public class ReadNamesFromFile
{

  public static void execute(IBusinessLogicInformation blInfo)
  {
		// Name of indexed global variable to be saved
		String gvOutputName = "namesFromFile";
		
		// The file containing a list of information (in this case, it contains names)
		java.io.File myFileOfNames = new java.io.File("C:" + java.io.File.separator
						 + "temp" + java.io.File.separator + "names.txt");
    	
    	try
    	{
			// First, read the contents of the file
			
			java.io.FileInputStream fis = new java.io.FileInputStream(myFileOfNames);
			
			int buffersize = (int)myFileOfNames.length(); 
			byte[] contents = new byte[buffersize];; 

			long n = fis.read(contents, 0, buffersize);
			 
			fis.close();
			
			String namesFromFile = new String(contents);
			
			// Next, create an indexed global variable from the file contents
			
			java.util.StringTokenizer stok = 
						new java.util.StringTokenizer(namesFromFile, "\n", false);
			
			int count = stok.countTokens();
			String[] names = new String[count];
			for (int i = 0; i < count; i++)
			{
				names[i] = stok.nextToken();
			}
			
			IGlobalVariable gv = new GlobalVariable(gvOutputName, names);
			blInfo.getGlobalVariables().put(gvOutputName,gv);			
    	}
    	catch (java.io.FileNotFoundException fnfe)
    	{
    		fnfe.printStackTrace();
    	}
    	catch (java.io.IOException ioe)
    	{
    		ioe.printStackTrace();
    	}
  }
}

Example: Calling an Integration Object

This example illustrates calling an Integration Object from business logic. The example assumes that you have an Integration Object named Iomac, which takes one input parameter, a string called input, and returns a string named output.

This business logic performs these steps:

  1. Instantiates the Integration Object:
     IntegrationObject.Iomac io = new IntegrationObject.Iomac();
  2. Sets the input variable from a global variable:
    io.setInput(getGlobalVariable(blInfo,"input").getString());
  3. Gets the servlet request and response objects from the ZIETrans wrapper method and invokes the Integration Object using the request and response:
    WebRequest webReq = (WebRequest)blInfo.getRequest();
    HttpServletRequest req = webReq.getHttpServletRequest();
    WebResponse webResp = (WebResponse)blInfo.getResponse();
    HttpServletResponse resp = webResp.getHttpServletResponse();
    io.doHPTransaction(req,resp);
  4. Checks for exceptions.
  5. If the Integration Object executed successfully, sets the global variable output to the value returned by the Integration Object's getOutput() method:
    if (io.getHPubErrorOccurred() == 0)
    			setGlobalVariable(blInfo,"output",io.getOutput());

If you want to invoke an Integration Object that accepts more input variables or returns more variables, add setter and getter calls to set the input variables before invoking the Integration Object and retrieve the output values after it executes.

////////////////////////////////////////////////////////////////////////////////
//  This sample is provided AS IS.
//  Permission to use, copy and modify this software for any purpose and
//  without fee is hereby granted. provided that the name of IBM not be used in
//  advertising or publicity pertaining to distribution of the software without
//  specific written permission.
//
//  IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SAMPLE, INCLUDING ALL
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL IBM
//  BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
//  DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
//  IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
//  OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SAMPLE.
////////////////////////////////////////////////////////////////////////////////
import com.ibm.hats.common.IBusinessLogicInformation;
import com.ibm.hats.common.GlobalVariable;
import com.ibm.hats.common.IGlobalVariable;

public class myLogic
{

    public static void execute(IBusinessLogicInformation blInfo)
    {
        //add code here to perform your business logic
        IntegrationObject.Iomac io = new IntegrationObject.Iomac();

		// Set Integration Object's HAOVariable "input" 
		// equal to text from ZIETrans gv "input"
		io.setInput(getGlobalVariable(blInfo,"input").getString());
	
		// Get the request and response objects from the ZIETrans wrapper method and run the hp transaction
		
		try {
			WebRequest webReq = (WebRequest)blInfo.getRequest();
			HttpServletRequest req = webReq.getHttpServletRequest();
			WebResponse webResp = (WebResponse)blInfo.getResponse();
			HttpServletResponse resp = webResp.getHttpServletResponse();
			io.doHPTransaction(req,resp);
		}
		catch (Exception e) { 
			System.out.println("Exception thrown: " + e.toString());
			setGlobalVariable(blInfo,"output",
				"An exception was thrown. Please view the log for more details");
		}
		
		// Retrieve "output" computed through IO transaction 
		// and set it to ZIETrans gv "output"
		
		if (io.getHPubErrorOccurred() == 0) {
			setGlobalVariable(blInfo,"output",io.getOutput());
			System.out.println("Transaction has been completed successfully.");		 
		}
		else {
			setGlobalVariable(blInfo,"output","Transaction has failed unexpectedly. 
					ZIETrans Error message = " + io.getHPubErrorMessage());
			System.out.println("Transaction failed unexpectedly. ZIETrans Error message =
					" + io.getHPubErrorMessage()");		}
    }
}

Using custom screen recognition

You can use business logic to perform custom screen recognition. ZIETrans Toolkit provides many options for recognizing screens within a screen customization, including the number of fields on a screen, the presence or absence of strings, and the use of global variables. These options are described in ZIETrans User's and Administrator's Guide. You might find, however, that you want to recognize a screen in a way that you cannot configure using the options in the screen customization editor. In that case, you can add your own custom screen recognition logic.

Note:
The information in this section can be used for screen recognition within macros as well as within screen customizations.

If you want to create custom screen recognition logic using ZIETrans global variables, see Custom screen recognition using global variables.

If you have already created custom screen recognition logic by extending the ECLCustomRecoListener class, you can use this logic within ZIETrans. If you are creating new custom logic, follow these steps:

  1. Open the Java perspective.
  2. Click File > New > Class.
  3. Browse to the Source directory of your ZIETrans project.
  4. Enter the names of your package and class.
  5. For the superclass, click Browse and locate com.ibm.hats.common.customlogic.AbstractCustomScreenRecoListener.
  6. Select the check box for Inherited abstract methods. Click Finish. This imports the code skeleton into the project you specified.
  7. Add your logic to the isRecognized method. Make sure that it returns a boolean value.

    public boolean isRecognized(String arg0, IBusinessLogicInformation arg1, ECLPS arg2, ECLScreenDesc arg3)

    Refer to the ZIETrans API documentation at the ZIETrans Infocenter for a description of this method.

  8. After creating your method, you must update the screen recognition to invoke your method. From the ZIETrans projects view, expand your project and the Screen Customizations folder. Double-click the name of the screen customization to which you want to add your custom logic. Click the Source tab to open the Source view of the screen customization.
  9. Within the Source view, you will see a block that begins and ends with the <description> and </description> tags. This block contains the information that is used to recognize screens. Add a line within this block to invoke your custom logic:

    <customreco id="customer.class.package.MyReco::settings" invertmatch="false" optional="false"/>

    where customer.class.package.MyReco is your package and class name. If you want to pass any settings into your class, add them after the class name, separated by two colons. Settings are optional, and your class must parse whatever values are passed in. If you do not need settings, omit the two colons.

    Consider where within the description block you want to place the <customreco> tag. If you want your custom logic invoked only if all the other criteria match, place the <customreco> tag at the end of the block, immediately before the </description> tag. If your screen customization compares a screen region to a value, the description block will contain a smaller block, beginning and ending with the <block> and </block> tags, to define the value to which the screen region is compared. Be sure not to place your customreco tag inside this block.

    Following is an example section of a description block. Note the <customreco> tag just before the </description> tag, and not between the <block and </block> tags.

    <description>
    <oia invertmatch="false" optional="false" status="NOTINHIBITED"/>
    <numfields invertmatch="false" number="61" optional="false"/>
    <numinputfields invertmatch="false" number="16" optional="false"/>
    <block casesense="false" col="2" ecol="14" erow="21" 
    			invertmatch="false" optional="false" row="20">
    <string value="USERID ==="/>
    <string value="PASSWORD ==="/>
    </block>
    <cursor col="16" invertmatch="false" optional="false" row="20"/>
    <customreco id="customer.class.package.MyReco::settings" 
    			invertmatch="false" optional="false"/>
    </description>
  10. To rebuild your ZIETrans project, click Project > Clean on the toolbar.
  11. Use Run on Server to test your project. If you receive a ClassNotFoundException error, modify the class loader policy on your server. Refer to ZIETrans Getting Started for more information.

Example of custom screen recognition

Following is an example of business logic that performs custom screen recognition. This business logic class takes a list of code page numbers, separated by blanks, as its settings, and recognizes the screen if its code page matches one of those listed in the settings. The tag syntax is:

<customreco id="company.project.customlogic.CodePageValidate::[settings]" 

optional="false" invertmatch="false" />

For example, you can insert the following tag into a description block:

<customreco id="company.project.customlogic.CodePageValidate::037 434 1138" 

optional="false" invertmatch="false" />

In this case the screen will be recognized if its code page is 037, 434, or 1138.

////////////////////////////////////////////////////////////////////////////////
//  This sample is provided AS IS.
//  Permission to use, copy and modify this software for any purpose and
//  without fee is hereby granted. provided that the name of IBM not be used in
//  advertising or publicity pertaining to distribution of the software without
//  specific written permission.
//
//  IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SAMPLE, INCLUDING ALL
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL IBM
//  BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
//  DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
//  IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
//  OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SAMPLE.
////////////////////////////////////////////////////////////////////////////////
package company.project.customlogic;

import java.util.StringTokenizer;
import java.lang.Integer;
import com.ibm.eNetwork.ECL.ECLPS;
import com.ibm.eNetwork.ECL.ECLScreenDesc;
import com.ibm.hats.common.IBusinessLogicInformation;
import com.ibm.hats.common.HostScreen;
import com.ibm.hats.common.customlogic.AbstractCustomScreenRecoListener;

public class CodePageValidate extends AbstractCustomScreenRecoListener {

/**
 * @see com.ibm.hats.common.customlogic.AbstractCustomScreenRecoListener
 * #isRecognized(java.lang.String, com.ibm.hats.common.IBusinessLogicInformation,
 *       com.ibm.eNetwork.ECL.ECLPS,  com.ibm.eNetwork.ECL.ECLScreenDesc)
	 */
	public boolean isRecognized(
		String settings,
		IBusinessLogicInformation bli,
		ECLPS ps,
		ECLScreenDesc screenDescription) {
		HostScreen hs=bli.getHostScreen();
		int int_codepage=hs.GetCodePage();
		if(settings!=null)
		{
			StringTokenizer tokenizer = new StringTokenizer(settings);
			while( tokenizer.hasMoreTokens() )
			{   
				int int_token= Integer.valueOf(tokenizer.nextToken()).intValue();
				if ( int_token==int_codepage )
				{    
					 return true;
				}
			}
		}
		return false;
	}

}

Custom screen recognition using global variables

ZIETrans Toolkit provides some screen recognition options using global variables, including these functions:

Refer to ZIETrans User's and Administrator's Guide for information about these options. If you want to perform screen recognition that is based on ZIETrans global variables and the options in the Global Variable Logic panel do not meet your requirements, you can add your own logic based on the values or existence of one or more global variables. This approach does not require you to create a Java class; instead, it uses the GlobalVariableScreenReco class, which is provided by ZIETrans, and you can specify comparisons to be made as settings on the <customreco> tag. The format is one of the following:

Braces {} are used to contain each of the two items that are being compared. The first item is a ZIETrans global variable, whose name is specified in name. You can use option to specify that you want to use the variable's value, length, or existence in your comparison. The resource and index settings are optional. Use resource to indicate whether the global variable is local (which is the default) or shared. Use index to indicate which value to use from an indexed global variable.

The second item can be one of the following:

The valid values for the settings are shown in Table 1. For the COMPARE setting, the only valid values for comparing strings are EQUAL and NOTEQUAL.

Table 1. Valid values for settings
Setting Valid values
type
  • variable
  • integer
  • boolean
  • string
COMPARE
  • EQUAL
  • NOTEQUAL
  • GREATERTHAN
  • GREATERTHANOREQUAL
  • LESS THAN
  • LESSTHANOREQUAL
options
  • exists (boolean)
  • value (string/integer/boolean)
  • length (integer)
  • object (object)
resource
  • local
  • shared
index Any positive integer or 0

The following example compares the values of two local global variables:

<customreco id="com.ibm.hats.common.customlogic.GlobalVariableScreenReco::
		{variable(name=gv1,option=value,resource=local)}EQUAL
		{variable(name=gv2,option=value,resource=local)}" 
		invertmatch="false" optional="false"/>

This expression evaluates to true if the values of gv1 and gv2 are the same.

Now consider the length option. For a non-indexed global variable, length is the length of the value of the variable. For an indexed global variable, if you specify an index, length is the length of that index of the global variable; if you do not specify an index, length is the number of indexed entries in the global variable.

<customreco id="com.ibm.hats.common.customlogic.GlobalVariableScreenReco::
		{variable(name=gv1,option=length,resource=shared)}LESSTHANOREQUAL
		{variable(name=gv2,option=length,index=4)}" invertmatch="false" optional="false"/>

This expression compares the length of gv1 to the length of the fourth index of gv2. It evaluates to true if the length of gv1 is less than or equal to the length of the fourth index of gv2. You can use LESSTHANOREQUAL because length returns an integer value.

The use of resource=shared on gv1 in this example indicates that gv1 is a shared global variable. The other option is resource=local, which is the default, and means that the global variable is not shared with other applications.

You do not have to compare one global variable with another. You can compare the length of a global variable with a fixed integer. You can compare the value of a global variable with another string. For example:

<customreco id="com.ibm.hats.common.customlogic.GlobalVariableScreenReco::
		{variable(name=gv1,option=value)}EQUAL{string(value=mystring)}" 
		invertmatch="false" optional="false"/>

This expression compares the value of gv1 with the string that is contained in mystring. The string can be a fixed string, the value of a variable, or a value that is returned from a method call. In general, you do not need to use custom logic to compare the length or value of a global variable to a fixed value; you can add these comparisons using the Global Variable Logic panel.

Accessing javax.servlet classes

In order to provide a consistent set of APIs for Web application developers, some ZIETrans APIs were generalized so they would work in a Web environment.

The getRequest() method on this interface returns a com.ibm.hats.runtime.IRequest object. In a Web application, this object will be of type com.ibm.hats.runtime.WebRequest. WebRequest has similar methods to HttpServletRequest, but does not extend from it. To access the actual HttpServletRequest object from a WebRequest object, the getHttpServletRequest() method can be called.

Table 2. Javax.servlet class plus ZIETrans class plus the method to access
javax.servlet Class + Wrapper ZIETrans Class + Method to access
HttpServletRequest com.ibm.hats.runtime.WebRequest WebRequest.getHttpServletRequest()
HttpServletResponse com.ibm.hats.runtime.WebResponse WebResponse.getHttpServletResponse()
ServletContext com.ibm.hats.runtime.WebContext WebContext.getServletContext()
ServletConfig com.ibm.hats.runtime.WebConfig WebConfig.getServletConfig()

See the Javadoc API for IBusinessLogicInformation for more information and code samples.