UI generation

Table of Contents:



introduction:

While the UI is one of the 6 primary components of SAND, it is not directly considered to be a supporting technology. While SAND has formal technology interfaces for messaging, persistency, configuration, control and framework processing (see nodecommon and the DataManager), it provides an interface for UI development.

SAND actually provides for UI development at multiple levels. This document covers each of these levels starting with the fundamentals and working upwards from there.

TOC


Requirements and responsibilities:

There are two primary requirements for a SAND UI:

  1. It must communicate with the SAND application via SAND messages. That's not to say a UI built using SAND cannot directly access the database or do anything else it wants. It can. However this kind of access is outside outside of anything supported by SAND (and outside the scope of this document).
  2. It must shoulder the burden of authentication and communicate with other nodes in the system via secure messaging. As the closest point of contact to the user, the UI must ascertain the user's identity, and not allow for interception, spoofing, or other problems resulting from faulty communication.

Meeting these requirements is fundamental to establishing a clear contract of responsibilities within the deployed application.

To accomplish authentication, the UI makes use of the standard means relative to the requirements of the application. This can be anything from a web login form, to a retinal scan, to a game of 20 questions. How this is done is up to the UI, although the SAND environment does provide basic default support for webapp authentication.

SAND messaging can be achieved easily using an in-process bridge. In this approach, the deployment configuration contains a node which is executing in the same process space as the UI code. The UI retrieves a direct reference to this node using a SingletonAccessor and then calls it's generated messaging methods directly:

./images/bridgeUInode.gif

To support incoming asynchronous communications, a UI can register itself with the bridge node for callback. For additional information, refer to adaptor node deployment and the messaging overview.

TOC


Security and authorization:

SAND supports authorization at the level of actions, data types, data instances, data fields, data field values, and other programmatic logic done by the application Authorizer. It is the responsibility of the Authorizer to ensure that no unauthorized data is ever passed to the UI, and that no unauthorized actions or data are accepted from the UI.

In order to provide a non-frustrating user experience, the UI should in turn:

Obviously this requires close cooperation between the Authorizer node, and the SAND UI. In SAND this cooperation is achieved through the AuthFilter, which provides the authorization logic. The AuthFilter is used directly by both the Authorizer, and the SAND UI, to ensure that the application is consistent.

Refer to the information filtering use cases for details on specific authorization scenarios.

TOC


SANDForms:

When you take the number of structs in an application, and look at writing display, edit, query and collection forms for each one, and then writing authorization filtering for each one, autogenerated code is clearly the way to go. The challenge with SANDForms was to handle this code generation in a way that would:

  1. adapt to different display technology (web, GUI, mobile device)
  2. adapt to, and play nicely with, existing frameworks
  3. provide for easy customization
  4. be easily extended

SANDForms are built from the struct declarations. The generators create display code for the associated struct, update, query and collection messages. The display code targets the specific UI technology, so for a webapp, the code writes XHTML forms. The forms are managed using an extended MVC architecture:

SAND provides fully functional default implementations of these interfaces, which can be extended to provide additional functionality. With the XHTMLFormAdaptor, the generated output can also be post-processed using XSLT or other transformation operations. The example TaskHeapDemo deployment uses this technique with a simplified default transformation template.

Refer to the UIFormContext overview for details on the SANDForms model.

TOC


Dataset pagination:

When the UI issues a query, it needs to consider the maximum number of matching items that should be returned. While the UIFormOwner will typically enforce some limitations in its formFind processing, and the DataManager is configured with hard constraint settings, the correct number of return values for a query is a balance of:

Some typical approaches involve specifying the return collection to have
  1. exactly the number of items as the display will hold. This approach is appropriate for general ad-hoc query results.
  2. the number of items the display will hold, times the number of pages the user is likely to traverse. This approach is appropriate for targeted queries where the user is expected to page through the results in order.
  3. as much data as can possibly be retrieved. This approach is appropriate when the entire result will be cached or otherwise stored in state for further manipulation (such as with a rich client interface).

If a query returns a complete collection (see the SandCollectionMessage isComplete method), then a UI can offer arbitrary sorting of the query results. This is referred to as result ordering. But due to runtime query processing restrictions, not all query result collections will be complete. In these cases the UI must work via dataset pagination.

Dataset pagination refers to traversing the total dataspace via repeated queries, and is therefore dependent on data ordering. If no orderBy is specified in the query, then ordering is by uniqueID, and dataset pagination is handled automatically via the uniqueIDAfter query field. If orderBy is specified, then the UIFormOwner must handle data pagination itself using its knowledge of alternate keys.

A few cases are worth mentioning explicitely to illustrate:

Standard dataset pagination:

The UIFormManager calls the UIFormOwner to process the query. The UIFormOwner executes the query without specifying orderBy, and the resulting collection elements are displayed ordered by uniqueID.

While maxReturn in the UIFormContext.findQuery message determines the total size of the returned collection, the number of items which are displayed is determined by the UIFormContext.findCollMaxDisplay. The display starts at findCollIndex in the findCollection, and shows findCollMaxDisplay items.

Pagination is handled as follows:

Dataset pagination with custom ordering:

When standard dataset pagination detects that it needs to reissue the query in response to either a "next" or "previous" action, it skips the uniqueID calculations if orderBy is specified in the findQuery. Movement within the collection elements is still supported, but when a query needs to be reissued it is not modified by the UIFormManager.

Since the UIFormManager calls the UIFormOwner to process the query, and passes along the UIFormContext, the UIFormOwner has all the information it needs to handle custom data pagination. To do this it will need to implement the change to the query, but with the alternate ordering key.

As an example consider custom pagination ordering on the username key of BaseUser. Before processing the query, an extra match is added specifying username as greater than the last value in the current collection. This match takes the place of the uniqueIDAfter in standard dataset pagination. In this case the findKeys field (used for reverse pagination) would hold usernames rather than uniqueIDs.

Custom data pagination is relatively easy to implement since the code relating to the existing collection is re-used as a common framework.

TOC


Adapting SANDForms to other UI technology:

At the time of this writing, only the XHTMLFormAdaptor is available. Using SANDForms with other UI technology would require writing other UIFormAdaptor implementations. For example a SwingFormAdaptor would write Swing classes to provide forms for the defined structs.

The SandUI framework is designed to be technology independent, and is intended for use with webapps, rich client GUI interfaces, text terminals, restricted display interfaces, or voice interfaces. By autogenerating the user interface from the data structures and the SandUI definition, it is possible to support many application changes without impact to user display rendering, even if the application supports multiple user interfaces simultaneously.

Our next priority is likely to be SWT, but this depends on customer projects. Our hope is to release these adaptors to open source as the versions upgrade. If you are interested in specific technologies, joint development, or extensions to SANDForms, please contact Structs And Nodes Development Services

TOC


Using SANDForms with other UI frameworks:

For new development, we would recommend creating a UIFormAdaptor to generate the code expected by the UI framework. This can be done using the XHTMLFormAdaptor as a model, or alternatively using runtime post-processing (provided the differences in form output are relatively minor).

In situations where there is already significant established UI code, it may be fastest to build an adaptor node to convert the existing UI form processing calls to SAND messaging. If new data structures are being added to an existing webapp, it may be best to segment the application to take best advantage of code generation to minimize the work involved.

Conversion work is being handled on a per-project basis.

TOC


The SANDForms native framework:

The SANDForms native framework is implemented in the apps/ui project and supporting tools. A user interface is defined as an instance of a SandUI, which can be viewed/modified using the UI editor. The interface is then implemented through generated code, which varies depending on the interface technology used.

As one example, here's how the webapp interface of the TaskHeapDemo deployment works:

To handle a given screen request, XHTMLSandUIServlet

  1. reconstructs the current screen object (using its UIScreenAdaptor)
  2. processes the screen (using its UIFormManager, which calls through to the UIFormOwner as needed)
  3. renders the resulting output (using its UIScreenAdaptor)
  4. transforms the resulting output (using its SandTransformer and the template specified for use with the screen)

That's about it. Authentication and error processing are pretty standard for servlet processing. The only other point of interest is that it is possible to override locale information regardless of server settings, which can be handy. For more details, refer to XHTMLSandUIServlet.java.

TOC


Appendices:


model/view/controller (MVC) architecture:

In a typical web browser UI, individual data entry and query forms are placed into pages, and the pages are organized into a web site. As a website grows in size, separating the component aspects of the site becomes increasingly important in managing complexity. MVC is a general UI architecture which helps separate the major component aspects:

So you might have a clock object with getTime and setTime methods (model), with code to translate the clock object into an analog or digital display (view), and code to check if the time was changed and/or if that is allowed (controller).

There are several mature frameworks (both commercial and open source) available for building user interfaces. There is also the default SandUI framework, with form support autogenerated from the struct definitions. Which framework you choose will be based on your application requirements, but regardless of which you choose, the Structs And Nodes Development approach is the same:

  1. Create your struct definitions. These determine the core data being exchanged between the user and your app (model).
  2. Write your display transform generators. These will create code to translate messages to/from your interface (view).
  3. Create an adaptor node that accepts input from the view, does whatever work is necessary, and passes back output (controller).

How the adaptor node does its work, and what the view generator code needs to do, depends on your application, the interface API, and which framework you are using. SandBoss ships with an example TaskHeapDemo deployment with a simplified user interface that serves as an example for how to get started.

TOC


information filtering:

Enterprise information is sensitive, so it is imperative that no unauthorized information be transmitted to a client machine. Preventing unauthorized input, and setting unauthorized fields to their default values is the job of the Authorizer node. Hiding messages, fields, or values from view is the job of the UI, since this is where the message is transformed from an object into a display structure. Both mechanisms use an AuthFilter to determine the appropriate action to take.

./images/authfilter.gif

Although different applications have different authorization requirements, the following cases illustrate the types of processing required:

TOC


UIFormContext overview:

note:

  • Familiarity with basic SAND terms and messaging is assumed. Refer to Messaging.html for information.
  • The behavior described here is general and may be overridden by a UIFormManager implementation.

    The UIFormContext has four major modes, each of which can be accessed as an initial state or through standard user actions:

    A mode is not a state, since actual function varies depending on supported actions and context. A description of each mode and transitional actions follows.

    Listing Mode:


    Updating Mode:


    Adding Mode:


    Finding Mode:


    To support the modes and actions described above, the UIFormContext contains

    The UIFormManager (view implementation) must provide for processing of user requests by implementing the methods called in response to a user action. It is expected most applications will leverage either PlainObjectFormManager or PersistentObjectFormManager through extension or aggregation/passthrough.

    In addition to implementing UIFormManager, a UI adaptor node will typically modify the display results to customize the look and feel for the application. It is also responsible for providing an AuthUser and AuthFilter for authorization processing. Under some circumstances, a UI may also create additional user actions beyond those directly supported by the UIFormContext.

    I18n can be handled within result transformation template processing, loading of localized result transformation templates, customized rendering, extended form management, or a combination of these approaches. The best approach for your application depends on your application requirements. For additional information contact Structs And Nodes Development Services.

    TOC










    © 2002 SAND Services Inc.
    All Rights Reserved.