Creating custom components and widgets

ZIETrans provides a set of host components that recognize elements of the host screen and widgets that render the recognized elements. The components and widgets have settings that you can modify if the default settings do not recognize components or render widgets as you want them. If the components, widgets, and the settings that are provided by ZIETrans do not meet your needs, you can create your own custom components or widgets or modify existing host components or widgets. You might want to create your own host component in order to recognize elements of your host screen that the ZIETrans components do not recognize. You might want to create your own widget in order to change the way elements are presented on the Web page. The following sections describe how to create custom host components and widgets. For further information, see Appendix A. ZIETrans Toolkit files.

Notes:
  1. ZIETrans automatically updates your class loader policy when you add custom components or widgets to your ZIETrans application. This updates the default WAR class loader policy of your ZIETrans application to Single class loader for application.
  2. If you are using a bidirectional code page, you can control the direction of widgets and other presentation aspects. See Using the ZIETrans bidirectional API.

ZIETrans component tag and attributes

ZIETrans creates a JavaServer Pages (JSP) page (and writes information to a .jsp file) that reflects host component and widget selections that were made during transformation configuration in the ZIETrans Toolkit. ZIETrans writes this configuration as a set of attributes for the <ZIETrans:Component> tag. The <ZIETrans:Component> tag invokes the code to define host components and specify widget output. To view or edit the transformations in your ZIETrans project, expand the project in the ZIETrans projects view and look under Web Content/Transformations.

This JSP code example shows the format of the <ZIETrans:Component> tag.

<ZIETrans:Component type="<fully qualified component class name>" 
   widget="<fully qualified widget class name>" 
   row="1" col="1" erow="24" ecol="80" componentSettings="" widgetSettings="" 
   textReplacement=""  />

The attribute data of the <ZIETrans:Component> tag determine which host component and widget classes to call and how to present the widget in HTML output. The type attribute of the <ZIETrans:Component> tag specifies which component recognition class to use when recognizing the selected host screen component. The widget attribute specifies which rendering class to use when generating the HTML output. The following list describes the other attributes:

row
The starting row position for host component recognition.
col
The starting column position for host component recognition.
erow
The ending row position for host component recognition. You can specify -1 to mean the last row on the host screen.
ecol
The ending column position for host component recognition. You can specify -1 to mean the last column on the host screen.
componentSettings
A set of key and value pairs that is sent to the component class. When you specify componentSettings values, specify them in the form key:value. If you specify more than one key:value pair, separate them with a split vertical bar ( | ). For example, <.. componentSettings="key1:value1|key2:value2" ... >.

You can use the componentSettings attribute for advanced customization of the component. Surround the entire list with quotation marks. For example, if your command line uses the token >>> instead of ==>, you can pass this component setting value here.

widgetSettings
A set of key and value pairs that is sent to the widget class. When you specify widgetSettings values, specify them in the form key:value. If you specify more than one key:value pairs, separate them with a split vertical bar ( | ). Surround the entire list with quotation marks. For example, <... widgetSettings="key1:value1|key2:value2" ... >.

You can use the widgetSettings attribute for advanced customization of the widget. For example, if you want a table to have a certain number of columns, you can pass this widget setting here.

textReplacement
Any settings that are defined for text replacement for this use of the component. Text replacement attributes are the same as those for definition of text replacement at the project level. See <replace> tag for descriptions of the attributes.

When defining text replacement, if you want to replace certain special characters, you must use the following in the settings:

@vb.
| (split vertical bar)
@cm.
, (comma)
@dq.
" (double quote)
@lt.
< (less than)
@gt.
> (greater than)
@eq.
= (equal sign)

For example, to replace the string ABC with the string "ABC", specify text replacement as follows:

textreplacement="ABC=@dq.ABC@dq." 

ZIETrans performs the following steps to process each <ZIETrans:Component> tag that it encounters in the JSP page.

  1. ZIETrans attempts to instantiate the component specified by the type attribute of the tag. This attribute can be the fully qualified class name of a component provided by ZIETrans or one created by you.
    Note:
    You must specify the fully qualified path, e.g. com.company.division.product.MyComponent. If you want to be able to work with your custom component in ZIETrans Toolkit, place the class file in either the WEB-INF/classes directory or in a jar file in the WEB-INF/lib directory. If you prefer, you can import the source (.java) file into the project's source directory. If you have tested your custom component and you do not wish to work with it in ZIETrans Toolkit, you must make the .jar file available to your ZIETrans application when it is installed on WebSphere® Application Server.
  2. ZIETrans attempts to instantiate a widget object specified by the widget attribute of the tag.
    Note:
    You must specify the fully qualified path, like com.company.division.product.MyWidget. If you want to be able to work with your custom widget in ZIETrans Toolkit place the class file in either the WEB-INF/classes directory or in a jar file in the WEB-INF/lib directory. If you prefer, you can import the source (.java) file into the project's source directory. If you have tested your custom widget and you do not wish to work with it in ZIETrans Toolkit, you must make the jar file available to your ZIETrans application when it is installed on WebSphere Application Server.
  3. ZIETrans invokes the recognize() method of the component object.

    Each component has a different implementation of the recognize() method. The recognize() method performs pattern recognition logic and host screen data location. Component classes return an array of com.ibm.hats.transform.ComponentElement objects. This array is the logical representation of what was recognized by this component at the specified region with the specified settings.

  4. ZIETrans performs text replacement by calling the doTextReplacement() method on each ComponentElement object in the array that was returned by the recognize() method of the component object.
  5. ZIETrans invokes the drawHTML() method of the widget. If an applicable drawHTML() method cannot be found, the widget's draw() method is called. This method simply returns (unless overridden by subclasses) the concatenation of the toString() calls on each component element in the component element array returned by the component.

    The drawHTML() method renders the array of component elements as HTML output. The drawHTML() method does this by returning a StringBuffer object that contains its rendering of the supplied component element array. The widget used for the component determines how the component elements are rendered. Two widgets can take the same type of input. For example, the Link widget and the Button widget can both take the same type of input, but their drawHTML() methods generate different HTML content.

The following figure illustrates the flow of data from a region of the host screen, through the component and widget, to the Web page.

Figure 1. Flow of data from host screen to Web page
Flow of data from host screen to Web page

Creating a custom host component

ZIETrans provides a Create Component wizard to help you create custom components. You can start the wizard in several ways:

There are two panels of the Create Component wizard. On the first panel, you provide the name of the project, the name of the new component, and the name of the Java™ package for the component. Optionally, you can select a check box to include stub methods that allow you to define a GUI panel for configuring the settings used by the new component (see ZIETrans Toolkit support for custom component and widget settings for more information). On the second panel, you enter the name you want displayed for the new component in the ZIETrans Toolkit and select the widgets to associate with the component. Widget association is not necessary to complete the wizard. You can define the association of components and widgets later. Refer to Registering your component or widget for more information about associating components and widgets.

The following sections explain the required elements of a custom component that the wizard provides:

If you selected the check box to include ZIETrans Toolkit graphical user interface support methods, enabling you to modify the settings of the component, the Create Component wizard adds the following methods:

See ZIETrans Toolkit support for custom component and widget settings for more information about the methods necessary to support your custom component.

Note:
If you want your component to work properly within Default Rendering, you must set the consumed region (that is, the area of the host screen that has been processed) on each component element that your component returns, before returning the component element. This tells the Default Rendering that this region of the screen has been consumed, or processed, by a host component and should not be processed again. To set the consumed region, use this method:
public void setConsumedRegion(BlockScreenRegion region)
Refer to the ZIETrans API References (Javadoc) for the ComponentElement class for more information. See Using the API documentation (Javadoc).

Extending component classes

ZIETrans provides a number of host component classes. You can extend any of the host component classes that are found in the ComponentWidget.xml file by replacing the statement public class MyCustomComponent extends Component in the created .java file for the new component with the class name of an existing component. For example:

public class MyCustomComponent 
             extends com.ibm.hats.transform.components.CommandLineComponent
Note:
Bidirectional components are stored in the com.ibm.hats.transform.components.BIDI package. The names of bidirectional classes for components are the same as regular components, but they are followed by "BIDI"; for example, com.ibm.hats.transform.components.BIDI.CommandLineComponentBIDI.

Each ZIETrans component performs recognition of elements of the host screen in the recognize() method. To extend a host component and accomplish the specific recognition task you need, you can use either of these approaches:

The Create Component wizard generates a recognize() method that returns null, which indicates that the host screen region is not recognized by the new component. To change the custom component to act as the ZIETrans component it is extended from, whose elements contain all of the correct ComponentElements, remove the "return null" from the .java file and change the code in the component code. For example:

public ComponentElement[] recognize(LinearScreenRegion region, Properties settings) { 
ComponentElement [] elements = super.recognize(region, settings); 
return elements;
}

ZIETrans instantiates the custom component based on the setting of the type attribute of the <ZIETrans:Component> tag.

To edit the ComponentWidget.xml file, click the Navigator tab of the ZIETrans Toolkit. The ComponentWidget.xml file is shown at the bottom of the Navigator view of your project. See Registering your component or widget for more information about the ComponentWidget.xml file.

Creating a custom HTML widget

ZIETrans provides a Create Widget wizard to help you create custom widgets. You can start the wizard in several ways:

There are two panels in the Create Widget wizard. On the first panel, you provide the name of the project, the name of the new widget, and the name of the Java package for the widget. Optionally, you can select a check box to include stub methods that allow you to define a GUI panel for configuring the settings used by the new widget (see ZIETrans Toolkit support for custom component and widget settings for more information). On the second panel, enter the name you want displayed for the new widget in the ZIETrans Toolkit and select the components to associate with the widget.

The wizard provides the following required elements of a custom widget:

If you selected the check box to include ZIETrans Toolkit graphical user interface support methods, enabling you to modify the settings of the widget, the Create Widget wizard adds the following methods:

See ZIETrans Toolkit support for custom component and widget settings for more information about the methods necessary to support your custom widget.

Extending widget classes

ZIETrans provides a number of widget classes. You can extend any of the widget classes found in the ComponentWidget.xml file by replacing the

public class MyCustomWidget extends Widget implements HTMLRenderer

in the created .java file for the new widget with the class name of an existing widget, such as

public class MyCustomWidget extends 
  com.ibm.hats.transform.widgets.FieldWidget            
Note:
Bidirectional widgets are stored in the com.ibm.hats.transform.widgets.BIDI package. The names of bidirectional classes for widgets are the same as regular widgets, but they are followed by "BIDI"; for example,
com.ibm.hats.transform.widgets.BIDI.FieldWidgetBIDI

If you want to modify an existing widget, you must extend one of the existing widget classes and override its drawHTML method. Refer to the ZIETrans API References (Javadoc) for details about widget interfaces and methods. See Using the API documentation (Javadoc).

ZIETrans instantiates the custom widget based on the setting of the widget attribute of the <ZIETrans:Component> tag.

Widgets and global rules

Widgets that present input fields should check whether the input field has already been processed by a ZIETrans global rule. When a host screen is received, ZIETrans searches it for host components that match global rules that are defined for that ZIETrans application. When your widget checks whether the input field has already been processed by a ZIETrans global rule, the call returns null if the input field has not been processed. If the input field has already been processed according to a global rule, the call returns the transformation fragment to which the input field has been transformed by the global rule. Your widget should output the fragment rather than processing the component element. Examples are shown below for Web applications:

String ruleReplacement = 
		RenderingRulesEngine.processMatchingElement(componentElement, contextAttributes);
if (ruleReplacement != null) {
		buffer.append(ruleReplacement);
} else {
    .
    .
    .
}

Add the above example to the drawHTML() method for the widget.

Registering your component or widget

Registering your custom components and widgets in the ComponentWidget.xml file makes them available for use in the ZIETrans Toolkit, such as in the Insert Host Component wizard.

Host components must map to specific widgets. Custom host components can map to any existing widget or to a custom widget. The Create a custom component or widget wizards register your custom components and widgets in the ComponentWidget.xml file, and associates components and widgets. When using the wizards, if you did not associate your custom component or widget, you need to edit the ComponentWidget.xml file and add the associations. To edit the ComponentWidget.xml file, click the Navigator tab of the ZIETrans Toolkit. The ComponentWidget.xml file is shown at the bottom of the Navigator view of your project.

Note:
If you decide to delete a custom component or widget after it has been registered, simply deleting the source code for the component or widget from the Source folder of your project is not enough to completely remove it. It is still referenced in the registry and there is no programmatic way to remove it. You should remove it from the registry by editing the ComponentWidget.xml file and deleting the references to the component or widget.

Following is an example of the ComponentWidget.xml file that shows the ZIETrans-supplied Field Table component and one of the associated widgets, the vertical bar graph widget.

<ComponentWidgetList>
  <components>
    <component className="com.ibm.hats.transform.components.FieldTableComponent" 
							displayName="Field table" image="table.gif"> 
      <associatedWidgets> 
        <widget className="com.ibm.hats.transform.widgets.VerticalBarGraphWidget"/> 
      </associatedWidgets> 
    </component>
  </components>


  <widgets>
    <widget className="com.ibm.hats.transform.widgets.VerticalBarGraphWidget" 
							displayName="Vertical graph" image="verticalBarGraph.gif" />
  </widgets>
</ComponentWidgetList> 

As you can see, there are two sections to this file: components and widgets.

The components section contains the list of all registered components. To register a custom component and make it available to the ZIETrans Toolkit, add a <component> tag and the associated <widget> tags to the ComponentWidget.xml file. You must supply a className, displayName, and the associated widgets.

className
Identifies the Java class that contains the code to recognize elements of the host screen. The class name is usually in the form com.myCompany.myOrg.ClassName.
displayName
Identifies the name by which your custom component is known and how it appears in the list of components in the ZIETrans Toolkit. This name must be unique among the registered components. The form of the displayName for a custom component is simply a string. Spaces are allowed in the displayName.
image
The image attribute identifies the image to use for your component when it appears in the ZIETrans Toolkit.
widget
Identifies the widgets that are associated with this component. There must be a separate <widget> tag for each associated widget. All of the <widget> tags for the component must be defined within the <associatedWidgets> tag and its </associatedWidgets> ending tag. The <widget> tag within the <associatedWidgets> tag contains only the className attribute, which identifies the Java class that contains the code to link the widget to the component. The class name is usually in the form com.myCompany.myOrg.ClassName.

The widgets section contains the list of all registered widgets. To register a widget, link it to a component, make it available for use in the ZIETrans Toolkit, and add a <widget> tag to the ComponentWidget.xml file. You must supply a className and a displayName.

className
Identifies the Java class that contains the code to render the widget. The class name is usually in the form com.myCompany.myOrg.ClassName.
displayName
Identifies the name by which your custom widget is known and how it appears in the list of widgets in the ZIETrans Toolkit. This name must be unique among the registered widgets. The form of the displayName for a custom widget is simply a string. Spaces are not allowed in the displayName. However, you can use an underscore ( _ ) in place of a space.

ZIETrans Toolkit support for custom component and widget settings

You can provide GUI support for modifying the settings of your custom component and widget. This is useful if other developers will be using your custom component or widget or you want to easily test different combinations of settings using the preview features available in the ZIETrans Toolkit. The base component and widget classes implement the ICustomPropertySupplier interface. This interface allows a component or widget to contribute setting information to the ZIETrans Toolkit. This information is used to render a panel by which the settings of the component or widget can be modified. Not all settings need to be exposed in the GUI.

The getCustomProperties() method returns a vector of HCustomProperty customizable property objects. Each HCustomProperty object represents a setting of the component or widget. The ZIETrans Toolkit renders each HCustomProperty objects based on its type. For example, an object of type HCustomProperty.TYPE_BOOLEAN is rendered as a GUI checkbox.

The following sample code demonstrates how a widget can provide GUI support for three of its settings (mySetting1, mySetting2, and mySetting3):

// Returns the number of settings panels (property pages) to be contributed 
//by this widget.  The returned value must be greater than or equal to 1 if 
//custom properties will be supplied via the getCustomProperties() method.  
public int getPropertyPageCount() {
         return 1;     
}

// Returns a Vector (list) of custom properties to be displayed in the GUI 
//panel for this component or widget.     
public Vector getCustomProperties(int iPageNumber, Properties properties, 
         ResourceBundle bundle) {
         Vector props = new Vector();          

// Constructs a boolean property that will be rendered as a checkbox         
HCustomProperty prop1 = HCustomProperty.new_Boolean("mySetting1", 
                "Enable some boolean setting", false, null, null);         
props.add(prop1); 

// Constructs a string property that will be rendered as a text field         
HCustomProperty prop2 = HCustomProperty.new_String("mySetting2", 
                "Some string value setting", false, null,
                 null, null, null);         
props.add(prop2);          

// Constructs an enumeration property that will be rendered as a drop-down         
HCustomProperty prop3 = HCustomProperty.new_Enumeration("mySetting3", 
                 "Some enumerated value setting", false,
                 new String[] { "A", "B", "C" }, new String[] 
                 { "Option A", "Option B", "Option C" }, null, null, null);
props.add(prop3);          

return props;     }
Widget GUI

The values supplied by the user of the custom component or widget will be available in the componentSettings Properties object passed into the recognize() method of the component or the widgetSettingsProperties object passed into the constructor of the widget. The getCustomProperties() method may be called during runtime to collect default values for settings.

For a description of the arguments and usage of these methods, refer to the ZIETrans API References (Javadoc) for the HCustomProperty class. See Using the API documentation (Javadoc).