Page Automation Overview Portlet Factory's Page Automation provides automation for many of the common page functions required in J2EE applications. The Data Page builder is the core builder that provides the Page Automation functionality. There are additional higher level builders in Portlet Factory (such as View & Form and Input Form) that wrap one or more other builders such as Imported Page along with a Data Page builder to extend the base functionality provided by the Data Page builder. There are numerous other modifier builders in Portlet Factory (such as Data Field Modifier, Data Column Modifier, Data Hierarchy Modifier and Form Layout) that work with the Data Page builder to modify its behavior. The Page Automation component effectively maps a data variable in a model to a page. The Data Page builder can work with a simple type such as a String, a complex XML schema type, or even a schema introspected from a Java bean. The Data Page builder can either work with an existing variable or it can use a schema to create a new variable in the model. The Data Page builder can operate in two modes, View Only and Data Entry. The two modes are very similar in their operation. In View Only mode, the Data Page builder maps the data contained in the model variable to a set of display tags on the page. In Data Entry mode, the Data Page builder maps the model variable to a set of form inputs on the page. If the variable already contains existing data, the form inputs can be automatically pre-populated with the existing data. When used in Data Entry mode, Page Automation not only handles mapping the model variable to one or more form input elements on the page but also automatically updates the model variable when the form is submitted. Page Automation provides this very powerful set of features and it is highly recommended that it be used any time when one or more inputs need to be collected on a page. Illustration 1: The Data Page builder inputs specifying the model variable, page and mode
User Interface Settings The Data Page builder can automatically generate a user interface on the page or it can work with an existing HTML page. If the Data Page builder is configured to automatically generate a user interface, it will generate all of the tags needed on the page using a single page location to place the new tags. The HTML Template File is used as a template for the layout and generation of the necessary tags on the page. The HTML Template File can be customized, which allows a great deal of control over the appearance of the generated user interface. If the Data Page builder generated user interface is not adequate, then the Data Page builder can be configured to not generate a user interface and instead operate with an existing HTML page. If the Data Page builder does not generate a user interface, it uses existing named tags on the page to locate where the elements of the model variable should be rendered. Illustration 2: The Data Page builder inputs for UI generation Formatting, Translation and Validation The Page Automation component provides a rich set of data formatting, translation and validation options. These options are extremely configurable and can be used to customize the display, input and validation of data in a Portlet Factory created portlet. There are three distinct operations that Page Automation uses, these are formatting, translation and validation. All three operations are optional and can be configured and used independently of each other. The formatting, translation and validation options can be specified in several different ways, but all achieve the same effect essentially supplying additional metadata about an XML schema. The formatting, translation and validation options are linked to the schema elements to which they apply, and each schema element can have it's own independent settings. PageAutomation_DFM.model provides a sample showing the use of formatting, translation and validation. PageAutomation_DFM.model uses a set of Data Field Modifier builders to apply the formatting, translation and validation to the schema elements. Run PageAutomation_DFM.model to see how the formatting, translation and validation options work. After submitting the form in PageAutomation_DFM.model, the second page will display both a formatted version and a raw version of the data contained in the model variable. PageAutomation_RDD.model is similar to PageAutomation_DFM.model; it defines exactly the same formatting, translation and validation rules, but it uses a Rich Data Definition file to specify the formatting, translation and validation settings instead of Data Field Modifier builders. The primary difference in using a Data Field Modifier builder versus a Rich Data Definition file is that the Data Field Modifier builders apply to a specific Data Page only whereas the Rich Data Definition applies directly to the schema and will therefore be used anytime that schema is used. You may notice in PageAutomation_RDD.model that there is a bit of extra work required (creating a new schema and variable) in order to get the raw version of the data to display on the confirm page.
When configured in Data Entry mode, the Data Page builder provides a set of Inputs that control the use of validation. The Data Page inputs shown here will be discussed in further detail in this document. Illustration 3: The Data Page builder inputs for validation Formatting Page Automation performs the formatting operation when data from the model variable is rendered on the page. The formatting operation provides the ability to display data on the page in a different format than the actual data contained in the model variable. PageAutomation_DFM.model demonstrates the use of some of the built in formatting features. Some of the built in format expressions require arguments, others do not. In PageAutomation_DFM.model, the Data Field Modifier for the AMOUNT field provides an example of a format expression that requires an argument. The format expression used here is the NumberFormat(FormatString) expression. The format expression argument that is used is the string #,##0.00. This argument is used by the formatter to render the number grouping digits by three and requiring two digits after the decimal point. This allows for additional flexibility for the formatter to support a wide range of capabilities. Translation Page Automation performs the translation operation when the form on the page is submitted. The data contained in the form is processed by the SaveData method. This method executes the translation operation on each form input element. The translation operation provides the inverse operation of the formatting operation. Translation allows for data to be input in one format and saved into the model variable in a different format. PageAutomation_DFM.model demonstrates the use of some of the built in translation features. Some of the built in translate expressions require arguments, others do not. In PageAutomation_DFM.model, the Data Field Modifier for the AMOUNT field provides an example of a translate expression that does not require an argument. This translate expression is the Floating Point blank becomes zero expression. Validation Page Automation also performs the validation operation when the form on the page is submitted. The validation operation allows the submitted data to be validated against a configurable set of rules. The validation step is performed by the SaveData method immediately following the translation operation. The validation step, therefore examines the data in the model variable in the data format, not in the display/input format. Model 1 demonstrates the use of some of the built in validation features. The validate expression for the ORDER_ID field has been configured to use a regular expression through the RegularExpression(RegExString) validate expression. The RegExString argument in use here is ^\\d{6}$. This regular expression requires the value to contain exactly 6 digits.
The Page Automation Components Before continuing, it will help to introduce the components of Page Automation that make all of this possible. The <page>_savedata Method The Data Page builder adds a method to the model with a name pattern of <page>_savedata. The SaveData method is responsible for taking the data submitted in the form inputs on the page and saving the data into the model variable. Page Automation's save operation (and the SaveData method) should not be confused with the operation of persisting data into a database. The SaveData method only saves the data into the model variable. The SaveData method also performs translation and validation on the model variable as the form data is saved into the model variable. To view an example of the SaveData method, load the PageAutomation_DFM.model sample model. In the main Eclipse menu select Window->Preferences... then select the WebSphere Portlet Factory Designer node in the tree. Check the box labeled Show Hidden Objects and click OK to close the dialog. In the WebApp Tree view of the model, expand the Method node and select the updatepage_savedata method. The right pane of the WebApp Tree view should show the code generated for the updatepage_savedata method. You will notice that the code not only saves the data from the request inputs into the model variable, but it applies the translation and validation rules to the submitted data during this process. Illustration 4: An example of a SaveData method
The <page>error LJO The Data Page builder adds a Linked Java Object (LJO) to the model with a name pattern of <page>error. The <page>error LJO is used by Page Automation to maintain error messages for the form when it is submitted. Any validation errors encountered by the SaveData method are added to the <page>error LJO. The <page>errorljo provides methods that allow individual error messages to be returned or set for each field in the form. The <page>errorljo also provides methods to obtain all of the form's error message in a single formatted HTML string. Illustration 5: An example of an ErrorLJO The <page>_nextaction Method Page Automation and the Data Page builder also provide a facility to assist with updating a database or other back-end data storage system. The actions to make the updates need to be constructed independently, but they can be referenced in the Data Page builder. The Data Page builder provides a Success Action input. If an action is specified in the Success Action input, the Data Page builder will generate a a method with a name pattern of <page>_nextaction. The NextAction method will check the <page>error LJO to determine if any error messages exist for the form and conditionally call either the Success Action or Failure Action. (If the <page>error LJO has no errors, then the Success Action will be invoked by the NextAction method. If the <page>error LJO has errors, then the action provided for the Failure Action input in the Data Page builder is invoked.) Any time a Data Page builder is used for data entry, the Success Action input should be populated, allowing the Data Page builder to generate the NextAction method. The submit button for the form should invoke the <page>_nextaction method rather than calling the data persistence action directly. This is the proper way to provide for form input validation in Portlet Factory. PageAutomation_DFM.model provides a sample showing the proper use of the NextAction method. Run PageAutomation_DFM.model to see how the NextAction method controls the flow of the application. To view an example of the NextAction method, load the PageAutomation_DFM.model sample model. In the WebApp Tree view of the model, expand the Method node and select the updatepage_nextaction method. The right pane of the WebApp Tree view should show the code generated for the updatepage_nextaction method. You will notice that the updatepage_nextaction method checks the updatepageerror LJO to see if there were errors encountered during the validation process. If errors occurred, the updatepage_nextaction method will re-
render the updatepage. If no errors occurred, the updatepage_nextaction method will continue on to the configured Success Action for the Date Page and display the confirmpage. Illustration 6: An example of a NextAction method The Post-Save Method The Data Page builder provides a Post-Save Method input. Among other things, the Post-Save method can be used to execute validation operations on the entire form as a whole. For example, one field of a form may be conditionally required depending on the value of another field in the form. The Post-Save method is invoked immediately following the SaveData method. This allows the Post-Save method to process the form and add any error messages to the <page>error LJO before the NextAction method is called. PageAutomation_DFM.model provides an example for using the Post-Save Method in the Data Page builder. The Post-Save Method in this case has been used for three functions. The Post-Save Method input in the Data Page builder has been configured to call the postsaveactions method in the model. The first function provided by the postsaveactions method is to provide alternate text for the introduction string used for the Full Error Location. The Error LJO provides a method called seterrorintrostring. This method can be called to change the introduction string displayed at the Full Error Location. The second function that the postsaveactions method performs is to provide an alternate error message when validation on the ORDER_ID field fails. The validate expression for the ORDER_ID field has been configured to use a regular expression through the RegularExpression(RegExString) validate expression. The RegExString argument in use here is ^\\d{6}$. This regular expression requires the value to contain exactly 6 digits. Since the formatter cannot interpret the regular expression and provide a meaningful error message to the user, it supplies a basic message stating, The value "..." did not match the regular expression "^\d{6}$". For users that aren't familiar with the regular expression syntax, this won't make much sense. The postsaveactions method works with the updatepageerror LJO to check the ORDER_ID field for validation errors and re-set the error message to a more appropriate message if any errors exist.
The third function that the postsaveactions method performs is to provide cross-field validation between the STATUS and DATE_SHIPPED fields. The postsaveactions method enforces a cross-field validation rule that if the STATUS is Shipped or Returned then the DATE_SHIPPED field must be populated. Illustration 7: An example of a Post Save method The <field>_validationerror tags The validation error messages can be displayed within the page relative to each field. Validation error messages are displayed within the page relative to each field by using a set of named tags inserted by the HTML template. These named tags have names with a pattern of <field>_validationerror. If you desire to disable the display of validation error messages within the form, the HTML template can be edited to remove the tags that create the <field>_validationerror tags. If these tags are not present, validation error messages can still be displayed using the Full Error Location. In the example below, you can see the <field>_validationerror tag and that it's contents are automatically populated from a method call to the ErrorLJO to get the error message for the associated field. Illustration 8: An example of a ValidationError tag
The Full Error Location The Data Page builder provides a Full Error Location input. This input can be used to specify a named tag on the page where a collection of all validation error messages should be displayed. The collection of all validation error messages will be displayed at this location and will be prefixed with an introduction string. The text for the introduction string can be set using the Error LJO's seterrorintrostring method. If the Full Error Location input is left blank, the collection of all validation error messages will not be displayed on the page. If the Full Error Location is not used, validation error messages can still be displayed using the <field>_validationerror tags. Illustration 9: An example of a Full Error Location Custom Formatter Classes Page Automation can also work with custom formatter classes. If you find that the StandardFormatter class is not sufficient for your needs, you can implement your own formatter class. This provides for complete flexibility over the formatting, translation and validation of data. All formatter classes must implement the com.bowstreet.methods.iinputfieldformatter interface. This interface defines several methods that must be implemented. The com.bowstreet.methods.baseinputfieldformatter class provides a generic implementation of the IInputFieldFormatter interface, and is a good starting point for any custom formatter classes that may be written. CustomFormatter.model provides an example demonstrating the use of a custom formatter class. The custom formatter class used by this model is com.bowstreet.samples.formatter.memorysizeformatter. The custom formatter class can be specified either through a Data Field Modifier builder (as shown in CustomFormatter.model) or through a Rich Data Definition file. The IInputFieldFormatter class defines a getwebappaccess method that can be used to provides the formatter class with a WebAppAccess object. The getwebappaccess method will return null unless additional steps are taken to set the WebAppAccess object for the formatter. One way to set the WebAppAccess object for the formatter class is to define an Event Handler builder in the model which listens for the OnWebAppLoad event, the event handler should then invoke the setwebappaccess action on the formatter class. Another way to set the WebAppAccess object for the formatter class is to declare that the formatter class implements the com.bowstreet.builders.webapp.methods.webappaccessconsumer interface. If Page Automation detects that the formatter class implements this interface, it will invoke the setwebappaccess method automatically. Care must be taken when using the WebAppAccess object in a formatter class, as the WebAppAccess object is really only designed to be used within the scope of a single request. After the request for which the WebAppAccess object was created has completed, the object will become stale. When setting the WebAppAccess object using an OnWebAppLoad event handler this will be the case. Some methods of a stale WebAppAccess object will still function properly, such as the getvariables method, but others will not work as intended.