C H A P T E R  8

3270 Pathway Recorder in Detail

This chapter provides detailed information about the 3270 Pathway Recorder. It contains the following topics:


Sun 3270 Pathway Navigation Class

This section describes how to create and save a new Sun 3270 Pathway navigation class.


procedure icon  To Create a Navigation Class

1. Start the recorder.

See Starting the Sun 3270 Pathway Recorder.

2. Select File right arrow New on the main recorder window to display the New Navigation Class window.

 FIGURE 8-1 New Navigation Class Window

Screen shot showing New Navigation Class window.

3. In the dialog box, specify the following information:

a. In the Class field, type the name of the navigation class to create, for example AccountQueryObject.

Follow Java naming conventions and start the name with an uppercase letter. The dialog allows you to type only characters that are valid for a Java class name. For example, you cannot use an exclamation mark (!).

b. In the Package field, type the package name.

The dialog attempts to prevent you from typing an invalid package name. It is a good idea to specify a package name because some IDEs refuse to import a source file (or Java Bean) that is not part of a package.

c. 3270 connection details:

When you start the recorder, you must specify the TCP/IP host name and port of the TN3270 server to which to connect. You can also choose one of the following terminal models:

d. If you want the recording process to begin as soon as the terminal is connected, select the Start recording immediately checkbox.

When recording is turned on, any user interaction with the 3270 emulator generates code in the Code Viewer window, which represents the user interaction.

e. If you decide to create a new Sun 3270 Pathway navigation class when a 3270 connection is already established, you can choose to maintain that connection by selecting the Maintain 3270 Connection button.

This is useful when creating multiple navigation classes to perform separate fragments of your 3270 application, which you can subsequently invoke sequentially.

4. Click OK.


procedure icon  To Save Navigation Classes to the Disk

1. On the recorder main screen, select File right arrow Save.

2. When the dialog box shown in FIGURE 8-2 is displayed, type the class and package names in the Class definition area.

You can change class and package names that are displayed in the dialog box.

 FIGURE 8-2 Saving a Navigation Class

Screen shot showing the Select a directory to save into dialog box. Used for saving a navigation class.

3. Select the output directory.

4. Click the Save button.

This initiates the saving and building process and generates the following:

The navigation class files are compiled. The compiled class files and the manifest stub are used to create a Java Bean JAR containing the navigation class. A progress bar displays during the save process. If an error occurs at any stage, a window displays the error details.

When this process completes, all the files are ready for use, either as stand-alone classes or to be imported into IDEs.


Navigation Recorder Window

The Navigation Recorder window contains a 3270 emulator, menu bar, and toolbar.

 FIGURE 8-3 Navigation Recorder Window

Screen shot showing the Navigation Recorder window.

The 3270 emulator enables you to interface with the host system. The toolbar, located at the top of this window, permits easy access to the functions:

These functions are also available from the menu bar of this window. The menu bar also enables you to change the font of the emulator by selecting Settings right arrow Font.

Starting and Stopping Recording

The most important control on the Navigation Recorder window is the recording control. When recording is turned on, any user interaction with the 3270 emulator generates code in the Code Viewer window, which represents the user interaction.


procedure icon  To Start and Stop Recording

single-step bulletUse either method:

Supplying a Variable

When recording is turned on, you can type the contents of a variable into the 3270 emulator at the current cursor position by selecting the Type a variable option from the Actions menu or using the corresponding toolbar button on the Navigation Recorder.

Selecting this option displays a dialog box from which you can choose the variable whose contents you want typed into the 3270 emulator. You can only type String type variables into the 3270 emulator screen; the dialog box only shows these variables. After you choose a String variable and click OK, the current value of the variable is entered into the 3270 emulator as if a user had typed it. This operation might not succeed if, for example, there is insufficient space in the 3270 field or if the cursor of the 3270 emulator is on a protected area of the screen.


procedure icon  To Create a New Variable

single-step bulletClick the Create button on the Navigation Recorder toolbar.

See Variable Types.

Double-Byte Character Set (DBCS) Issues

When typing the contents of a String variable into the 3270 emulator screen, the string must contain data that is compatible with the screen field into which it is being entered. The following table describes each screen field type.

Field

Description

Pure single-byte

The string can only contain Unicode characters that translate to single-byte code points using the current DBCS code page.

Pure double-byte

The string can only contain Unicode characters that translate to double-byte code points using the current DBCS code page.

SOSI (shift-out shift-in)

The string can contain Unicode characters that translate to either single- or double-byte code points using the current DBCS code page. However, the string cannot contain SO or SI characters because they are generated automatically where required. Therefore, you must ensure that there is sufficient space in the entry field for both the characters and any automatically generated SO or SI characters.


Highlighting an Area of the Screen

Several operations on the 3270 emulator, such as storing an area of the screen into a variable or performing an assert operation, require you to highlight an area of the screen. There are two selection modes that you can use to highlight an area of the screen:

Flow Selection Mode. Using this mode, all 3270 characters in the display buffer are highlighted from the chosen start location to the chosen end location.

Block Selection Mode. Using this mode, a block or rectangle of characters are highlighted where the chosen start and end locations define opposite corners of the block.


procedure icon  To Highlight an Area of the Screen

1. Choose a selection mode from the appropriate menu item or use the appropriate toolbar button on the Navigation Recorder window.

2. Place the mouse at the start of the area to highlight. Click and hold down the (left) mouse button.

This activates the recorder functions that operate on a highlighted area.

3. Drag the mouse to the end of the area to highlight.

An outline is displayed showing the highlighted area.

4. Release the mouse button.

The background color of the characters changes to indicate the selection.

Highlighting an area does not generate any code in the Code Viewer window.

Storing an Area of the Screen

You can store an area of the 3270 emulator screen in a variable, but first you must highlight the area of the screen that you want to store. See Highlighting an Area of the Screen.


procedure icon  To Store the Highlighted Area of the Screen

1. Select the Store Highlighted Area option from the Actions menu or use the toolbar button from the Navigation Recorder window.

2. In the dialog box, choose a variable in which to store the highlighted area.

Depending on the selection mode you used to select the highlighted area, you must choose a specific type of variable:

If you are in Flow Selection mode, you must choose a String variable. The contents of the variable are replaced with the contents of the highlighted area.

If you are in Block Selection mode, you must choose a Vector variable. The contents of the variable are replaced with the contents of the highlighted area. Each row of the block selection becomes an element of the Vector variable.

When DBCS data from a shift-out shift-in (SOSI) field is stored, any SO and SI characters present in the highlighted area are not stored in the selected variable because they are not required in a Unicode string. This allows you to reenter an area of the screen, which was stored in a variable this way, using the Type a variable control at a later time.

Creating an assert

After you highlight an area of the screen, you can perform an assert operation for that area.

single-step bulletSelect the Assert Highlighted Area option of the Actions menu or use the corresponding toolbar button from the Navigation Recorder window.

This generates a line of code in the Code Viewer window:

assert("ENTER COMMAND",261);

When this code is executed, it confirms (asserts) that these characters are present at the specified offset of the 3270 emulator display buffer. If this is not the case, the assert() method generated in the output class throws a Java IllegalStateException.

This mechanism enables a Sun 3270 Pathway Bean to confirm that it is on the expected screen of an application and to notify its caller if this is not true.

SO or SI characters within an area being asserted are not placed in the assert string because they are not required.

Starting the Store List Wizard

The Store List Wizard enables you to create Java code to save related data from multiple 3270 screens into a single variable, for example, a list. The Store List Wizard saves you the effort of traversing each screen of the list and copying the data manually. See Chapter 9 for information about using the Store List Wizard.


procedure icon  To Change the Font

single-step bulletUse either method:

a. Move the cursor over the 3270 emulator.

b. Click the right mouse button to display the pop-up menu.

c. Select Font, and select a font style that you prefer.


Namespace Viewer Window

The Namespace Viewer window (FIGURE 7-7) enables you to view and manipulate variables. The primary purpose of the variables is to act as input and output areas for data supplied to and from the generated Java class at execution time.

Any variables defined to the recorder in the Namespace Viewer window also are displayed as instance variables in the generated Java code, which you can see in the Code Viewer window (FIGURE 7-8). Also, each variable can have a pair of get() and set() accessor methods. For example, for a variable called var1, a pair of methods is created by default in your navigation class called getVar1 and setVar1.

Namespace Viewer Window Contents

On the Namespace Viewer window menu you can choose the type of variables to view:

The Namespace Viewer window contains a list of the variables of the chosen type with information about each.

TABLE 8-1 Variable Type Information

Variable Information

Description

Type

S or V. Vector variables that currently contain elements also have a + symbol on the type. By clicking this symbol you can view the current values of each element of the vector.

Name

Name of the variable.

Default

Default value of all Vector variables is shown as {empty}. You can alter the default value of a String variable by double-clicking the left mouse button in this area.

Current

Current value of the variable.

Get Method

If the check box is checked, a get() method is generated for the variable.

Set Method

If the checkbox is checked, a set() method is generated for the variable.

In Use

If this checkbox is checked, the variable is being used and you cannot delete it. You cannot alter the value of this check box.

Description

Description of the variable. You can change the description by double-clicking the left mouse button in this area.


Variable Types

There are two variable types in the Namespace Viewer window:

String. A Java String object. String variables are typically used to contain either input or output parameters for the navigation class.

Vector. A Java Vector object where each element of the vector is a Java String. Vector variables are only used as output parameters. For example, they can be used to contain the result of storing a Block Selection or to contain a list generated by the Store List Wizard.

Creating and Deleting Variables

This section describes how to create and delete variables.



Note - You can only delete a variable when it is not in use. There is no generated code other than the get() and set() methods that access the variable.




procedure icon  To Create a Variable

1. Select the Create option from the Actions menu of the Namespace Viewer window or use the corresponding toolbar button.

2. On the Create a variable window (FIGURE 7-10), supply the following information:

a. In the Variable Name field, type the name using the Java convention of starting variable names with a lowercase letter.

For example, for a variable named var1, the accessor methods generated are called getVar1 and setVar1 (with an uppercase V). This follows the standards of the Java Bean naming pattern conventions. The recorder attempts to prevent you from typing any characters that are not valid in a Java variable name.

b. In the Description field, type a brief description of the variable.

When your Sun 3270 Pathway class is saved as a Java Bean, this description is stored in the generated BeanInfo file (see To Save Navigation Classes to the Disk). An IDE makes this information available to a developer using the generated Sun 3270 Pathway Bean.

c. In the Variable Type field, select either String or Vector, depending on the type of variable that you want to create.

d. In the Default/Current Value field, type an appropriate value.

This field applies to String variables only. Because Vector variables are used only as output variables, there is no mechanism to set a default or current value.

The Default value is the value to which the variable is initialized in the generated class. For example, a String variable called var1 with a default value of fred generates the line:

private String var1 = "fred";

The Current value defines the initial value of the variable for the purposes of the recording session only. This value does not appear in the generated code. For example, this allows a recorder user to define a variable called password, set the current value of password, and successfully navigate through a 3270 application that requires that password.


procedure icon  To Delete a Variable

1. Select the variable in the Namespace Viewer window.

2. Select the Actions right arrow Delete option or press the Delete button on the toolbar of the Namespace Viewer window.

A confirmation dialog box is displayed.

3. Click OK to delete the variable.


Code Viewer Window

The Code Viewer window (FIGURE 7-8) dynamically displays the code generated by the recorder. Using the Code Viewer window you can view either the main class, which is generated by recorder, or the BeanInfo class (Structure of the BeanInfo Class) that corresponds to the main class. The code visible in these two classes is what is saved to disk when you select the Save option from the File menu on the main recorder window. See To Save Navigation Classes to the Disk.

Structure of the Main Navigation Class

When recording is on, interaction with the 3270 emulator in the Navigation Recorder window immediately generates code in the Code Viewer window. This section describes the important portions of the Sun 3270 Pathway-generated main class.

Instance Variables

Several private instance variables are defined in your main Sun 3270 Pathway navigation class as:

private Terminal term;

This is the instance of Sun 3270 Pathway Bean that this navigation class manipulates. This variable has no default value and is initialized to null.

The following line of code identifies the default TN3270 host name to which this navigation class connects, unless otherwise instructed:

private String tn3270Host = "locis.loc.gov";

The following line of code identifies the name of the default TN3270 port to which this navigation class connects, unless otherwise instructed:

private int tn3270Port = 23;

Each of these instance variables also has a corresponding get() and set() method pair for access.

init() Method

The init() method is a private method that is called at the beginning of the performWork() method. It is the job of the init() method to ensure that the instance variable term is a valid reference to a connected Terminal before returning control to the performWork() method.

The init() method uses the following logic:

1. Ensure that the term instance variable is not null. If term is null, create a new Terminal and set its host and port to be equal to the tn3270Host and tn3270Port instance variables.

2. When term is in the process of disconnecting, allow it to finish.

3. If term is disconnected, issue a connect request.

4. Wait for term to become connected.

5. Wait for the keyboard to become unlocked.

This enables a user to call a Sun 3270 Pathway navigation class in several ways. In the following examples, NavClass1 and NavClass2 are separate navigation classes.

Example 1: Create a navigation class that creates and uses its own private Terminal, connecting it to the default host and port:

NavClass1 nav1 = new NavClass1();
nav1.performWork();

Example 2: Create a navigation class that creates and uses its own private Terminal, connecting it to host myhost and port 9993:

NavClass1 nav1 = new NavClass1();
nav1.setTN3270Host("myhost");
nav1.setTN3270Port(9993);
nav1.performWork();

Supply the first navigation class with a predefined Terminal, then call that navigation class. Next, invoke a second navigation class in the same way. The Terminal term can remain connected between the calls to the two navigation classes, enabling the classes to be chained together sequentially.

Terminal term = new Terminal();
term.setTN3270Host("myhost");
term.setTN3270Port(9993);
term.connect();
NavClass1 nav1 = new NavClass1();
nav1.setTerminal(term);
nav1.performWork();
NavClass2 nav2 = new NavClass2();
nav2.setTerminal(term);
nav2.performWork();

performWork() Method

A user of the main class should call the performWork() method to have it perform its navigational work. The performWork() method always starts with a call to the init() method.

Following the call to init(), there are lines of code that represent the recorded actions. These lines are grouped together and are referred to as interactions. Each interaction represents an instance of a user interacting with the 3270 emulator, then pressing an AID key (for example, Enter, Clear, PF, PA), which causes the keyboard to become locked pending a response from the 3270 host. The interaction typically ends with a line of code that waits for the host to respond.

Example: If the user types ACCT and presses Enter, the generated interaction is:

term.typeString("ACCT");
term.pressEnter();
term.waitUntilkeyboardUnlocked();

The code is grouped into these interactions for clarity and readability and to allow the most recent interaction to be deleted by selecting the Delete option from the Actions menu of the Code Viewer window.

The most recent interaction is highlighted in a different color, drawing attention to the lines of code being generated.

By default, the recorder attempts to position the generated code in the Code Viewer window so that the most recent interaction is kept visible. The generated code consists primarily of calls to the Terminal bean that this navigation class will use.

Structure of the BeanInfo Class

A BeanInfo class is a Java class whose sole purpose is to describe a Java Bean. Because the recorder generates code that can be a Java Bean, it also generates a BeanInfo class.

BeanInfo classes are a standard part of Java Bean definition. The BeanInfo class generated by the recorder is an implementation that provides a full description of the Bean as created by the recorder.

All the instance variables defined in the generated navigation class are declared as properties in the BeanInfo class. Depending on whether there are get() and set() methods for the variables, normal, read-only, or write-only properties are generated.

Most recorder users do not need to understand the structure of this class.

Deleting the Most Recent Interaction

When using the recorder, you can delete the most recent interaction.



caution icon

Caution - Deleting interactions may make your generated class inconsistent with the 3270 application that you were recording. Therefore, use this function with care. It is your responsibility to ensure that the generated class is correct if you choose to delete interactions.




procedure icon  To Delete the Most Recent Interaction

1. Verify the interaction is currently highlighted in red.

2. In the Code Viewer window, select Actions right arrow Delete from the menu.

A confirmation dialog box is displayed.

3. Click OK to delete the interaction.

Code Viewer Window Settings

You can manipulate the behavior of the Code Viewer window using the following options on the Settings menu:

The Code generation option displays a dialog that allows you to set the following:

Wait Strategies

This section describes the differences between a well-behaved and poorly-behaved 3270 application, and the waiting strategies used by the recorder.

A well-behaved 3270 application sends a screen of information to a user on a 3270 terminal as follows:

1. One or more datastreams are sent from the host to the terminal to build the screen that is presented to the user.

2. The last datastream sent to the terminal instructs the terminal to unlock the keyboard, allowing the user to interact with the terminal.

A poorly-behaved 3270 application sends a screen of information to a user on a 3270 terminal as follows:

1. One or more datastreams are sent from the host to the terminal to build the screen that is presented to the user.

2. A datastream prior to the last datastream sent to the terminal unlocks the keyboard.

In this case, it is usually only the speed with which the subsequent data streams are sent after the keyboard is unlocked that prevents the user from interacting with the terminal before the last data stream arrives. An application behaving in this manner is in error because a user should not be allowed to interact with a terminal until the host has finished sending data to that terminal.

Before using the recorder, correct any 3270 applications that are poorly-behaved. If you fail to do this, the recorder uses its wait strategies to cope with poorly-behaved applications.

The strategies used to insert wait commands into the generated code are based on two methods available in the Terminal class. You can find a complete description of these methods in the Javadoc for the Pathway Terminal.

The method typically used with a well-behaved screen is:

waitUntilKeyboardUnlocked()

The method typically used with a poorly-behaved screen is:

waitHeuristic(int t)

The recorder has three strategies for inserting wait commands into the generated code. The following table describes each.

TABLE 8-2 Wait Strategies

Wait Strategy

Description

Intelligent waiting

Inserts calls to the waitUntilKeyboardUnlocked() method when the recorder observes that the screen is well-behaved. This is the default strategy.

If the recorder detects that a screen is poorly-behaved, a call to waitHeuristic(int t) is generated instead.

The interval used as the parameter t for waitHeuristic() is determined by observing the data streams received at recording time, and making a reasonable guess at an interval based on 2 x maximum observed interval between sends for the screen after the keyboard is freed.

Intelligent waiting with override

Similar to intelligent waiting. The only difference is that instead of using a reasonable guess for the waitHeuristic() method, a fixed configurable value is used. You can modify the value using the Code Generation dialog. This is a useful strategy if the application is less well-behaved at deployment time than it was at recording time.

Fixed heuristic waiting

Generates waitHeuristic() calls for all screens. The time parameter for this call is a fixed configurable value. You can modify the value using the Code Generation dialog. This is a useful strategy if the application is as well-behaved at deployment time as it was at recording time.


Normally, the default strategy is adequate. However, you may require the other strategies for some types of application. You can change the strategy using the Code Generation dialog.



Note - Using the waitHeuristic() method has an associated performance penalty because, for each interaction with the host, an extra delay of the time period t is incurred.