Sun ONE Application Framework (JATO)

Version 1.2 Changes

Table of Contents

Previous Version Changes

Overview of Key New Features

Event Method Signature Changes

Command Infrastructure

Default CommandField Activation

QueryFieldDescriptor Filtering for QueryModels

New Servlet Events

TreeModel, TreeView, and JSP Tree Tags

Change Log

Developer Assistance

Deployment Changes

Tag Library Changes

Servlet & Infrastructure Changes

ViewBean Changes

Event Changes

View Changes

Model Changes

Miscellaneous Changes

Previous Version Changes

Overview of Key New Features

The following are some of the key new features in JATO 1.2.

Event Method Signature Changes

Display and request event method signatures have changed significantly in JATO 1.2. Traditionally, these event methods have taken multiple, varying parameters. This was deemed a convenience benefit for developers, but has unfortunately proven limited due to the expanding number of parameters needed to enable new event features. Therefore, these events in JATO 1.2 now take full-fledged event objects which can be arbitrarily expanded in the future without further event method signature changes.

For request events, the immediate benefits of this change are greatly simplified and more consistent event method signatures. The following table outlines the event signature changes for request events:

Pre-JATO 1.2 Request Event Signature JATO 1.2 Request Event Signature
<parent>.handle<child>Request(RequestContext context) <parent>.handle<child>Request(RequestInvocationEvent event)

<parent>.handle<child>Request(RequestContext context, int imageXCoordinate, int imageYCoordinate)

<parent>.handle<child>Request(RequestInvocationEvent event)
<parent>.handle<child>Request(RequestContext context, int rowNumber) <parent>.handle<child>Request(RequestInvocationEvent event)
<parent>.handle<child>Request(RequestContext context, int rowNumber, int imageXCoordinate, int imageYCoordinate) <parent>.handle<child>Request(RequestInvocationEvent event)

(For additional details, please see the JavaDoc for the com.iplanet.jato.view.command.DefaultRequestHandlingCommand class.)

For display events, the immediate benefits of this change are that the signature of these methods is significantly simplified, and the information available in the events is greatly expanded. The display event implementor now has access to JSP-specific objects like the tag handler generating the event. This allows the event implementor to change or read attributes on the tag handler before the tag processes or renders its content. The event implementor also has access to the JSP page context, allowing easy integration with other tag libraries and direct output to the output stream from within an event. The following table outlines the event signature changes for display events:

Pre-JATO 1.2 Display Event Signature JATO 1.2 Display Event Signature
ContainerView.beginDisplay() ContainerView.beginDisplay(DisplayEvent)
ContainerView.beginChildDisplay(String) ContainerView.beginChildDisplay(ChildDisplayEvent)
ContainerView.endChildDisplay(String, String) ContainerView.endChildDisplay(ChildContentDisplayEvent)
ContainerView.endDisplay() ContainerView.endDisplay(DisplayEvent)
<parent>.begin<child>Display() <parent>.begin<child>Display(ChildDisplayEvent)
<parent>.end<child>Display(String) <parent>.end<child>Display(ChildContentDisplayEvent)

(For additional details, please see the JavaDoc for the com.iplanet.jato.view.event.DisplayEvent interface and its subinterfaces and their implementations in the com.iplanet.jato.view.event package, and for the com.iplanet.jato.view.ContainerViewBase class.)

The JATO team plans to provide an upgrade tool with the JATO 1.2 release for automated conversion of existing application code to the new event signatures.

Command Infrastructure

JATO 1.2 introduces a general command pattern and supporting implementation. Commands are now used for all request handling in JATO, and over time, developers can expect that they will be used in other areas of JATO as appropriate. The command interfaces and implementation exist in the com.iplanet.jato.command package, and include the following key classes:

Do not be confused by the CommandDescriptor class in the com.iplanet.jato.command package. JATO 1.1 included a CommandDescriptor class in the com.iplanet.jato.view package that has since been renamed CommandFieldDescriptor. In fact, CommandFieldDescriptors can include instances of CommandDescriptor.

Request Handling with Commands

Request handling in JATO today uses a naming convention to invoke request handling event methods that are associated with the CommandField that was activated by the user on a given page. This technique has several advantages, in that it keeps controller code close to the object to which it pertains, and divides up this controller logic into manageable, fine-grained chunks related to specific user actions. However, it also has some disadvantages. For example, the same code cannot be easily invoked for multiple user actions, and the same code cannot be easily shared between multiple request-handling components. JATO's new command pattern offers an alternative mechanism that may be more suitable for use in situations where these disadvantages are significant.

Whereas the previous behavior used a naming convention based on the name of a CommandField, developers can now optionally specify a CommandDescriptor object with each CommandField. This CommandDescriptor specifies the Command to invoke when the CommandField is activated by the user. It also specifies the operation name and parameters to use when invoking the command. If a CommandDescriptor is not associated with a field, a default command is used to invoke a traditional request handling event method. The CommandDescriptor for a field is specified in the CommandFieldDescriptor associated with that field; thus, each field that wishes to invoke a Command when activated must have both a CommandFieldDescriptor and a CommandDescriptor.

Default ViewBean Command

In addition to being used for handling requests generated by the user activating a CommandField, a default command can also be specified for a ViewBean to be used for requests in which no particular child View generated the request. These types of requests may occur when a ViewBean is displayed for the first time, or when a user submits a form by default by pressing the "Enter" key while within focus of a form component. The default CommandDescriptor to be used in these situations is specified by the getDefaultCommandDescriptor() & setDefaultCommandDescriptor() methods of the ViewBeanBase class. Note, a ViewBean's default command will only be invoked if a the ViewBean or another child View doesn't accept the request, and a default CommandField activation wasn't specified (see below).

Default CommandField Activation

In some cases, a default request to a ViewBean (a request that doesn't indicate a specific CommandField child to activate) needs to be handled as if the user activated one of the available CommandField children. This situation is most common when a user presses the "Enter" key within a form field, thereby submitting the form without actually activating one of the form's buttons. Without specification of a CommandField child to activate, such requests are ambiguous.

One way of resolving this ambiguity is to specify a default command for the target ViewBean, a new feature of JATO 1.2. In some cases, this is appropriate. In others, it is overkill. Therefore, JATO 1.2 includes a somewhat more convenient feature. The <jato:form> tag now includes an additional property called defaultCommandChild that allows the developer to specify which CommandField child to activate in the absence of a specific indication. Please see the JATO tag library documentation for full information on this new attribute.

QueryFieldDescriptor Filtering for QueryModels

JATO's QueryModels use QueryFieldDescriptors as metadata describing the columns that should be used to construct queries and to cache data from a query result set. These descriptors are also used for model-field-to-query-column lookups during operations like setting of user WHERE criteria. JATO 1.1 used the same descriptors for all queries, which in some advanced cases, caused problems when the same model was used to perform different query types, such as SELECT and UPDATE queries. JATO 1.2 now provides the ability to "filter" descriptors on the query type in which they should be used. For example, a developer can now specify that a particular descriptor should be used for SELECT queries, but not UPDATE queries, or vice versa. By default, descriptors are used in all queries unless the developer specifically indicates otherwise. This preserves backwards compatilibty, as well as ease of use in simpler situations.

New Servlet Events

JATO 1.2 includes two new servlet events in the ApplicationServletBase clas:

TreeModel, TreeView, and JSP Tree Tags

JATO 1.2 includes basic support for models and views that are tree-like. The new TreeModel interface provides an abstraction for accessing hierarchical data. The TreeView interface and supporting implementation classes provide an easy way to display hierarchical data in a tree format, using several new tree-specific tags in the JATO tag library. TreeViews are non-prescriptive in their rendering, and are highly customizable. See the JATO sample application for examples of tree usage.

Change Log

The following changes were made from JATO 1.1 to JATO 1.2:

Developer Assistance
Changes Requires 1.1 App Changes
Added command package, comprising a generalized Command pattern infrastructure for JATO  

Deployment Changes
Changes Requires 1.1 App Changes
None  

Tag Library Changes
Changes Requires 1.1 App Changes
Moved HTML-specific tag handlers to the taglib.html package  

Added "tunneling" mechanism for handling CompleteRequestExceptions anywhere during the display cycle. It is now possible to throw a CompleteRequestException from display events and have it propagate out of the initiating forward() or include() call and back to application controller logic.

The trick was to "tunnel" the exception out of the JSP engine, which normally consumes it. Each of the tag handlers now catch this exception whenever they perform an event callback to View objects. The handlers then put the exception in the request attributes and return SKIP_PAGE, which causes the JSP engine to stop page processing in its tracks. The ViewBean.forward() & include() methods then check for the exception in the request attributes and rethrow it if found. This is also the one problem with this approach—you have to use these ViewBean methods in order to benefit from this workaround. If you use a servlet RequestDispatcher directly, you will have to check for the exception manually by calling the ViewBeanBase.checkDisplayEventCompletedRequest() method.

 
An extra value name-value pair for a field is not generated in the rendered page if the value is null. Previously, a blank string value was appended, which was incorrect.  

Servlet & Infrastructure Changes
Changes Requires 1.1 App Changes
Added friendly exception messages to servlet. When an uncaught or fatal error occurs, the user will receive a "friendly" error message that hides the stack trace and indicates an application-level error occurred.  
Added onRequestHandlerNotFound() event to ApplicationServletBase. This event is fired when a ViewBean cannot be found to handle the request. Because this is a fatal error situation, the default implementation of this event returns a "friendly" error message to the client.  
Added onUncaughtException() event to ApplicationServletBase. This event is fired when an otherwise uncaught exception is generated during the request. Because this is a fatal error situation, the default implementation of this event returns a "friendly" error message to the client.  
Made ApplicationServletBase orthogonal to the rest of JATO by using the current instance of ViewBeanManager to obtain the ViewBean instance used to handle a request. This feature also added the ability to put modules in any desired package because the ViewBeanManager is initialized with the base package name used to qualify the bean lookup.  
Removed ApplicationServletBase.createBeanInstance(String) & checkBeanClassName(Object,String) methods. These methods are no longer necessary now that the ViewBeanManager is used to obtain ViewBeans in the servlet.
Maybe
Eliminated null pointer vulnerability in ModelManager if ModelTypeMap is null. The ModelTypeMap instance must be valid when constructing a ModelManager or an IllegalArgumentException is thrown.  
Fix for sessionable Model regression in ModelManager. Models obtained using the setInSession flag were not being stored in session at the end of the request.  
Relaxed exceptions thrown from the RequestHandler.handleRequest() method. This method can now throw Exception, meaning that complex exception wrapping/unwrapping is no longer necessary when interfacing with developer-supplied event methods.
 
Removed the "Pragma: no-cache" header from ApplicationServletBase.addResponseHeaders() since it was causing the Netscape browser to (incorrectly) discard JATO pages from the cache. The original intent of this header was to ensure intervening proxies didn't cache JATO pages.
 

ViewBean Changes
Changes Requires 1.1 App Changes
ViewBeanBase now allows specification of a default Command that can be invoked when no child handles the request. This change resulting in new method getDefaultCommandDescriptor() & setDefaultCommandDescriptor()  
Changed name of page session hidden field key from pageAttributes to jato.pageSession  

Event Changes
Changes Requires 1.1 App Changes

Display event method signatures have changed to accept DisplayEvent objects:

  • ContainerView.beginDisplay() changed to ContainerView.beginDisplay(DisplayEvent)
  • ContainerView.beginChildDisplay(String) changed to ContainerView.beginChildDisplay(ChildDisplayEvent)
  • ContainerView.endChildDisplay(String, String) changed to ContainerView.endChildDisplay(ChildContentDisplayEvent)
  • ContainerView.endDisplay() changed to ContainerView.endDisplay(DisplayEvent)
  • <parent>.begin<child>Display() changed to <parent>.begin<child>Display(ChildDisplayEvent)
  • <parent>.end<child>Display(String) changed to <parent>.end<child>Display(ChildContentDisplayEvent)

Changes to any existing application display event methods is mandatory for this release. The JATO team intends to provide a tool for automatic conversion of event method signatures.

Yes

Request event method signatures have changed to accept RequestInvocationEvent objects:

  • <parent>.handle<child>Request(RequestContext context) changed to <parent>.handle<child>Request(RequestInvocationEvent event)
  • <parent>.handle<child>Request(RequestContext context, int imageXCoordinate, int imageYCoordinate) changed to <parent>.handle<child>Request(RequestInvocationEvent event)
  • <parent>.handle<child>Request(RequestContext context, int rowNumber) changed to <parent>.handle<child>Request(RequestInvocationEvent event)
  • <parent>.handle<child>Request(RequestContext context, int rowNumber, int imageXCoordinate, int imageYCoordinate) changed to <parent>.handle<child>Request(RequestInvocationEvent event

Changes to any existing application request event methods is not mandatory for this release, but strongly recommended. The JATO team intends to provide a tool for automatic conversion of event method signatures.

Advised

View Changes
Changes Requires 1.1 App Changes

Fixed bug in dumpChildValues() method in TiledViewBase. It was previously not outputting child values.

 
Unilateral use of Command objects for request dispatching. If not command is specified by the developer for a given CommandField, the default command class (DefaultRequestHandlingCommand) preserves the existing behavior by dispatching request handling events to the parent View.  
Added the CommandField.beforeCommand(CommandEvent) event method. This event is called on an activated CommandField before the target command object is invoked.  
It is no longer necessary for the developer to call the mapSourceTargetNVPs() method to process source-target pairs specified for a CommandField. This method is now deprecated and is a no-op. The mapping of source target pairs is now invoked automatically using the CommandField.beforeCommand() event. Developers can remove the call to mapSourceTargetNVPs() from existing code.
 

The following CommandSourceTargetPair constants have been changed in the interest of simplicity and clarity.

  • MODEL_OBJECT_TYPE, is now MODEL_FIELD_TYPE
  • SQL_WHERE_OBJECT_TYPE is now SQL_WHERE_TYPE
  • VIEW_OBJECT_TYPE is now DISPLAY_FIELD_TYPE
  • HTTP_SESSION_OBJECT_TYPE is now replaced with HTTP_SESSION_TYPE
  • PAGE_SESSION_OBJECT_TYPE is now replaced with PAGE_SESSION_TYPE

The JATO team intends to provide a tool for automatic conversion of these constants.

Yes
Path parsing in CommandSourceTargetPair now allows specification of a View path using "/" in addition to "."  
Moved CommandField and related classes from the view.html package to the view package and removed all HTML specifics. The only functional implementations of CommandField (HREF and Button) still exist in the view.html package.  
Fixed bug involving default requests for a page via a form submitted by pressing the user pressing the "Enter" key in a form field instead of clicking a form button. A default command child name can now be specified in the defaultCommandChild attribute of the <jato:form> tag, and this child will be activated if no other activated child name appears in the request parameters.
 
Added several simpler constructors for DisplayFieldImpl. This class can now be easily used directly for most display field peers (see taglib documentation for a complete description of peer restrictions).  
The view.CommandDescriptor class was renamed to view.CommandFieldDescriptor, to make it consistent with the new class naming of CommandField. (Do not be confused: a new class called command.CommandDescriptor was added in this version.)  
Added a fine-grained method used for setting specific field values during processing of the ContainerView.mapRequestParameters() method. This allows developers to intercept the setValue() method for a display field and change the value before its set on the target field. This method is called mapRequestParameter(DisplayField, Object[]) and can be found in the various ContainerView implementations.
 
ViewInvocation has expanded to allow specification of the actual target request handler (which in all cases today will be the accepting RequestHandler ContainerView). In the future, this will allow the handling view to allow delegation of the request handling to a child it manages, such as a CommandField instance that is also a RequestHandler.  
ViewInvocation has expanded to allow specification of the Command to invoke to handle the request  

Model Changes
Changes Requires 1.1 App Changes
Much improved QueryModelBase JavaDoc  
SQL tracing is now possible per instance of QueryModelBase; the TRACE_SQL option constant has been removed from QueryModelBase. SQL tracing now uses the JATO Log class, and is traced at the JATO_TRACE log level.  
Deprecated the QueryModelBase.getDelimitedTableNames() & QueryModelBase.setDelimitedTableNames() methods in favor of getModifyingQueryTableName() & setModifyingQueryTableName(). The reason for this change is that the former methods gave the impression that the developer could specify multiple tables for use during these queries, which was never the case and would have generated an error.  
An exception is thrown from QueryModelBase.executeSelect() if a combination of a default connection & incremental fetch directive is specified in the execution context. These are incompatible settings because default connections are closed at the end of this method, and therefore data could not be later incrementally fetched from the result set.  
Fixed bug in DefaultModel.dumpValues() that made distinguishing of empty arrays versus a single blank string value impossible  
QueryModelBase now allows UPDATE & DELETE queries using only WHERE criteria instead of field values  

Qualified field names are no longer used in any modifying queries in QueryModelBase. Specifically, qualified field names in UPDATE queries are no longer used (they were not required, and definitely caused problems in some DBs like AS/400).

 
Added filtering for QueryFieldDescriptors based on query type to QueryModelBase and ResultSetModelBase, so that only certain columns will be used during certain query constructions, or during model updating from a result set  

Miscellaneous Changes
Changes Requires 1.1 App Changes
Improved method registry notification tracing messages to use the JATO Log class. These messages are now logged under the JATO_TRACE log level.  
Changed obsolete terminology in ContainerViewBase JavaDoc  
Converted CommandSourceTargetPair array in CommandFieldDescriptor is now cached for efficiency  
Renamed all option constants throughout JATO to start with "OPTION_"  
Renamed all debug constants throughout JATO to start with "DEBUG_"