Xoetrope
HomePage :: Categories :: PageIndex :: RecentChanges :: RecentlyCommented :: Login/Register
Most recent edit on 2008-01-07 11:02:21 by LuanO

Additions:
XUI is an application development framework designed to relieve the programmer of many common tasks involved in building rich internet applications.
This section of the Evaluator's Guide describes the overall architecture of XUI and details how its subsystems interact.

The XUI Solution

At its simplest XUI s a set of factories designed to hide some of the complexity involved in application construction. XUI builds upon several well known patterns (see Design Patterns [1]) to simplify object creation and to separate concerns within the application.
Typical of this is the use of factory methods to hide the details of object construction and the use of adapters to provide uniform access to data.
Using these facilities the application developer can offload much of what we term ‘plumbing’ to the XUI library.
The solution offered by XUI and enhanced by XUI is layered in an object oriented fashion so there is considerable control as to how extensively XUI need be used in an application. At its fullest XUI can provide a large proportion of what is needed to build a complete application, apart that is from the application specific business logic
At a high level XUI consists of
Image

Figure 1: Overall application structure

Project support for coordination of resources

Most applications deal with a variety of objects and resources and an XUI application is no different. In a bid to coordinate resource usage XUI includes a project concept. This project is little more than a mechanism for holding references to the various resource manager objects and types needed by an application.
The use of a project facilitates access to resources by providing a central access point. Making the project the owner of these resources also means that the responsibility for resource creation and disposal can be coordinated. This coordination helps provide an orderly and predictable application startup sequence.
The term resource is used in a broad context to mean any class or object used by the application and this includes the management objects that form part of the XUI framework. An XUI
project therefore has application specific resources such as pages, data, colours and fonts as well as the framework originated resources such as page factories, component/widget factories classes, validation factories and event and data management components.
The project acts as a store for most of an application’s data, delegating to other classes to manage things like styles and pages. The project retains ownership of these classes and therefore it in turn owns all the resources used by the application. With this demarcation of resources it is possible to coordinate several project (or modules) within a single JVM and therefore the XProjectManager singleton is used to store references to the projects and it provides access to these projects by name.

Application lifecycle and stubs

The core mechanism for loading the application and the project is encapsulated in the XApplicationContext context class. The class coordinates loading of classes that are used by the project, given that many of these classes can be configured and customized via the startup files and other configuration files. The application context is also responsible for some of the lifecycle interfaces, for instance adding a shutdown hook to coordinate resource cleanup when the JVM exits.
Normally the application context is used in conjunction with an instance of XStartupObject. The startup object depends upon the widget set being used and encapsulated some of the widget specific issues (by instantiating an instance of WidgetAdapter specific to the widget set being used), and by managing the display. For instance the basic XApplet class for Swing coordinates the setup of the page container used to display XUI’s pages. However the startup object relies on the application context and the support classes that it instantiates (like the XPageManager) to manage the application lifecycle.
Several startup objects are provided, one for each of the Widget sets supported by XUI, plus some additional forms that allow customized display such as embedding of XUI applications within other applications.

Factory methods to remove repetition

Perhaps one of the most obvious places to begin our description of XUI is with user interface construction and a description of how widgets are added to an application.
Many Java IDEs rely on the basic Java bean facilities to manipulate user interface (UI) components. These beans provide fine grained access via accessor methods and while this is well suited to generated code it is not very programmer friendly. More often than not once generated the UI code is further manipulated by the programmer and this manipulation may break the IDEs graphical editing capabilities. Not only does this situation rapidly degenerate into ugly code and maintenance issues but it also is cause for excessive code bloat.
XUI provides several factory methods that take car of constructing the UI objects and setting the most common properties such as location and content. XUI also includes support for style sheet like specification of attributes such as colour and typograhical information. These additional attributes can be applied by simply using a different object factory. The object factories can be used interchangable and also help construct an object hierarachy as components and containers are added. A single factory method call can replace up to a dozen lines of generated code.
Later this document will detail how this method of object construction can even be removed from the Java code base and declare via XML. This XML declaration however is still routed though the same component factories outlined above.
XUI 3.0 introduced a common mechanism for registering various modules and components. This registration mechanism allows multiple named configuration files to added for most components. The mechanism allows handling multpiple third party components and for qualified selection of components based upon usage or upon a developer defined match/callback

Factories to target different devices/platforms

One of the key design goals behind XUI was to target limited devices such as handheld computers. For this reason XUI was initially built to support AWT based UIs and JDKs as early as JDK 1.1. Later support was added for JFC/Swing interfaces and additional widget types.
The relatively low base means that XUI can support a wide range of devices not just the latest desktop computers.
The use of component factories mean that the UI implementation can be changed from AWT to Swing simply by changing a startup parameter. XUI also employs a pluggable architecture for registration of the component factories so there is litle difficulty extending XUI to support other UI widget sets such as the LCDUI found in J2ME devices such as RIM’s Blackberry devices of Palm’s PDAs.
Ignoring the some the device limitations (such as screen resolution) for a moment this targetable UI support means that the same code can be used to simultaneously support a variety of devices.

Full API access

Unlike many other client solutions XUI provides full access to the underlying API. Widgets and components created with XUI can be accessed and manipulated as though they were constructed directly using the API.
Some wrapper for standard widgets are provided but this is for convenience and to allow switch of implementations. The wrappers are thin layers and do not block access to any of the underlying features.
Furthermore all the normal mechanisms for operating on components such as the built-in event handling are available and can be used in conjuction with the features provided by XUI. If for some reason the XUI approach is found to be limiting then it can be supplemented or replaced by direct coding.
This strategy also means that XUI applications can be extended by adding third party components and tools without restriction. Ultimately the XUI code base is open source and is available under a license that allows modification so (probably as a last resort) any of the XUI features could be modified to meet the applications needs.

Layered approach to styles

As has already been mentioned above XUI support a style sheet like way of configuring the appearance of widgets.
Styles can be declared in an XML style file and applied to the components during the component construction process. All that is needed to employ the style sheets is to use the XStyleFactory class to construct the widgets instead of the basic component factory. In fact by default XUI will use the style factory.
Moving style declarations to a separate XML file not only means further cleanup of the UI code but it also facilitates additional features such a rebranding an application. Changing the style file associated with an application way also go some way towards addressing the differences in the device capabilities mentioned above.
Styles can also be applied to an application by using a Java Look and Feel (L&F) or a theme, however the styles sheet support provided by XUI offers a much finer level of control over an application’s appearance than could be achieved with a L&F alone.

Modular extension

To support multiple widget sets XUI employs an abstract registration mechanism whereby component factories can be added to an application. The XProject class owns the component factory and additional factories can be registered at any time although registration is normally carried out at startup.
The component factories offer a number of interfaces for creation of an object. The build in components are assigned unique identifiers whereas additional factories generally rely on a type name to construct the component.
The component class name can also be used to instantiate a component so that third party components or components not expressly supported by a factory can also be added.
The component factories also make use of the XAttribuedComponent interface to set component attributes in a generic way rather than having to have detailed knowledge of the accessor methods and without recourse to reflectionor the bean support classes. This method of setting attributes works well in a cross platform situation where there may be differences in the implementation of a particular feature, for many APIs from JDKs are now deprecated.
As factories are normally registered during startup with the project and as the order in which the factories are registered may be important it is therefore easy to see how important a role the project has in creating a predictable startup.

Page management

The component factories described above can be used on their own without need for other parts of the XUI or XUI frameworks but much advantage would be lost if such an approach is adopted.
Applications rarely consist of a single screen or page so XUI provides additional support for instantiating and uses pages in an application framework. The term ‘page’ derives from the notion of presenting an application with a series of page or screen. Logically these pages may equate to steps within a business process or data capture cycle.
Depending on the type of application pages may be used on a one off basis or reused repeatedly, perhaps with updatable content.
XUI provides a page management facility to store pages and manage the context in which they are displayed. Normally only one page is visible at a time but pages may also be used within a frameset to allow further decomposition of the on screen layout. Each element in a frameset holds an individual page.
The XPageManger class is owned by the project and in turn it owns the individual pages in the application. XUI includes page navigation methods such as showPage and showPrevious. If the page manager determines that it does not already hold a reference to the request page it will instantiate the page on behalf of the application.
At its simplest a page is instantiated by invoking the ClassLoader to create a new instance of the class. The page is then inserted into the display area via the XPageDisplay interface which is implemented by the applet/application class.
If the page is already loaded and is not the currently displayed page the new pages is swapped into the display and the previous page is removed from the container and hidden.
The page manager invokes several methods during page creation and display to allow the page update its content, these lifecycle methods include notification of page creation, activation, and deactivation.
Since a page may be declared via XML it is not possible to directly instantiate an instance of a page class that will represent the content of the XML file. Instead the page manager delegates to a secondary loader (registered at startup) that processes the XML file and creates and configures the page’s components.
During construction an instance of an XPage is created or of a derived class and the components are addressed to the new page. Once create in this way the XML originated page is largely indistinguishable from one created from a Java class.
The same lifecycle events are fired and an XML page can therefore use the use the page creation response methods to do any additional setup. In a Java page the constructor might do more than just create the widgets so the page creation method provides an opportunity to do equivalent processing for the XML page.
Given that an XML based page may reuse the same base class definition the page creation response method gains in importance as it may be used to bind references to widgets for subsequent use in the class.
The application context by default instantiates at least one page loader (XPageLoader) and adds it to the page manager’s list of page loaders. The default page loader is the XuiBuilder class that parse the page XML. The page manager may therefore have many different page loaders for various file formats and it will iterate through these page loaders till the requested page is successfully loaded.

Extensible loaders

XuiPro extends the page loader mechanism, adding several additional page loaders for different file formats. The loader mechanism is designed to be extensible but in many cases declarative systems can be mapped the XGenericBuilder which defines a hinting and mapping format for this purpose. The generic builder can also be further customized, with the addition of extra parsers and interpreters so that systems as diverse as Python, VB and Oracle Forms can be mapped to XUI.
Using this extension mechanism means that providing editor support for these formats is relatively easy as the editor itself employs a customized loader. Once the loader/builder is complete the internal representation of the format should be the standard XUI form (although the widget sets may vary).

XML as a shortcut to declaring content

XML as a means of declaring content opens upon many possibilities. Coupling between business logic and the user interface is reduced and the implementation of the UI is more flexible as it can be rendered for different situations in different ways.
The XML needed to represent a page is also relatively compact in comparison to the byte code produced for an equivalent page. This can be of benefit where bandwidth is an issue.
XML can also be generated on demand and in some situation this might be desirable, for example where repetitive catalogue content is being streamed from a database yet where the content may content subtle variations that need to be accommodated in the layout.

Proxies for event management

As with the UI construction XUI provides extensive support for event handling. Using XUI all the plumbing code needed to direct the application to an event response method is hidden from the programmer. There is no need to declare listeners or adapters, all the application need to is declare its interest in receiving notification of an event.
To handle an event the XUI page container registers a proxy for handling the event and using reflection behind the scenes the appropriate response method is invoked by the proxy. To support this reflection mechanism the response method must be in a class derived from the XPage class, normally this is the case.
Figure 3 2: Event dispatch for a mouse event
While the response methods invoked in this way are parameterless access to the event is available through the page. The response method may also be overloaded in a polymorphic fashion and in this way libraries of page types may be constructed. Typical of this is a definition of response methods that handle page navigation functions. Such functions can be provided at a low level and shared by derived classes so that the navigation methods need be defined only once.

Input validation

Using a mechanism similar to the event registration XUI can register validation rules for input fields. The validations are special response methods invoked wherever an input field gains or looses control of the input focus, or upon page transition.
In response to this change of focus a validation rule is invoked. Several predefined validation rules are available, for example a XMinMaxValidation defines a rule that checks for that an input in with a specified range of values. The limits or parameters for the validation rule are named and the name is associated with values read from a configuration file (by default validations.xml). The validation parameters can even contain method calls that are evaluated at runtime.
Each XUI page can have a validation factory that will construct the parameterized validations on behalf of the page. The page delegates addition of the validation rule to a validation handle that adds the appropriate event handlers to the component being validated. The validation handler coordinates the validation rule checking in cases where more that one rule needs to be evaluates or where dependencies exist.
Some validations may be marked as mandatory so that their input must be valid before certain actions such as page transitions can take place. The validation handler object provides some several methods for checking and rechecking the state of a page’s inputs.
Should an error (such as an out of range value) be encounter while validating an input an exception is thrown. The exception is handled by an instance of the XValidationExceptionHandler class. By default it is the page that actually that implements and handles this response by displaying a warning or error message. However the application can override the processing to provide a page specific way of handling the error or the application may choose to register a completely different error handler. An example of this might be where an application chooses to display a list of error in a common window instead of popping up separate error messages for each error.
Figure 4: Exception handling during validation

Data modelling

An application is of little value without data and very often an application serves to do very little other than providing convenient access to or representations of data.
Much of the logic in a form or page based application can revolve around getting and setting the values of UI components. Much of this work is repetitive and mechanistic.
To remove the burden of managing this data access XUI provides a hierarchical data model. This model can be accessed using an XPath like syntax so that the application programmer need not be concerned with the details of how a model node is reached and accessed apart from specifying the path to the node.
Each node in this model can be a simple primitive type such as a string or number or it can be rich types like a list object or even a database table.
The XModel class provides an abstract representation of the nodes in the model. The model also acts a way of unifying all the data used within the application although data of different types (database tables for example) may be maintained on a different branch within the overall model.
This single data hierarchy and common access mechanism greatly simplifies data access. Despite this rich capability one size rarely fits all uses and therefore the model architecture is extensible right from the management of the model through to the representatation and usage of the model nodes.

Data loading

Once again the project class owns the model and upon startup the applet instantiates a data source (XDataSource in the basic XUI setup). The data source can then load the data from various sources. XUI’s data source reads a number of configuration file and has multiple data sources. The data loaded by the data source is attached to the model at a node specified by data source’s XML configuration file.
At this point the model need not be fully populated and some data may be loaded on demand. In some cases the model may not actually store the data and instead the model node may merely be an interface through which data is accessed. Database access is an example of this as is access to remote data and services.
At runtime the model may also be extended by the addition of sub branches as more data becomes available.
The creation state of the model is largely transparent to the application. For example if a node is accessed it will be automatically created if not already in existence. In this way storage can be made available for say a calculated value or an input value as needed. Frequently calculated data is assembled or produced only as progress is made through an application session.
Indeed this dynamic extension to the model can greatly facilitate the simplification of an application as it need not know very much about the overall state of the underlying data model. In
practice this agnostic approach to the model allows opportunities for ‘lazy’ loading of data and for redundant data sources (i.e. where a failover source of data is available should the primary source be unavailable for any reason).

Data binding

Although XUI provides a simple method of accessing data in the model it is unnecessary to use this method display and store data in the UI components. Data in the model can be simply bound to UI components.
Just as validation rules and event response methods can be associated with UI components as though they were component attributes data can also be bound in this way. Again access is through the page container and all the application need to is specify which piece of data to bind to an individual component.
Beneath the scenes a factory class is again used to construct data bindings (derived from the XDataBinding class) and associate them with the component. The data binding knows how to get and set data and persist it to the model, equally it knows how to pull data from the model it and update the UI state. This two way data update means that the binding can update both the model and the UI without further intervention from the programmer.
The data binding and the underlying model can be seen to act as a data channel for passing information from one page to another without directly referencing one page from another. Thus an axample of this might be where a page displays an input for a user name or ID, if the input field for this information is bound to the model any other page that binds a UI component to the same model node will automatically display the same data once that page is displayed.
Not all data is equal and some UI components demand different data. For instance an edit field might require a simple piece of text or a string a drop down list demands a set or list of data and a table component demands tabular data. Because the required data is not necessarily of the same type or structure as is held at a particular model node an adapter class may need to be created to allow the data be accessed and represented in a meaningful way.
Figure 5 Data binding
The core XUI package provides a limited set of adapters as itself provides only a limited set of model nodes, mostly for static data sources. XUI on the other hand provides much richer and varied data sources. Indeed XUI’s data model encapsulates remote data and remote services both of which may return unknown data types. XUI therefore defines an extensible factory for the creation of bindings and adapters. The factory uses a double dispatch mechanism whereby both end of the binding are used to determine the type of binding required. A binding may in fact be composed of several layers of adapters depending upon what is demanded by the UI component and on what is offered by the model.
This flexibility in creating bindings and in handling differing data sources removes considerable burden from the programmer. In this way business logic can be coded with a large degree of disregard for how the data is display and how it is stored.
Equally, the use of adapters and dynamic data binding also increase the flexibility with which a UI can be constructed. Some page can effectively be build without detailed knowledge of the data they will represent. In some applications such as catalogues or browsers this flexibility may make it possible to have a page adapt itself to a broad range of content. Traditionally this would have required custom logic and would have introduced extensive coupling between the presentation and the model.

Database access

One of the most common data sources is the database. XUI provides access to databases via the model. Tables can be preconfigured for specific queries (including parameterized queries) or the queries can be constructed dynamically.
XUI also manages the connections on behalf of the application by providing pooling and by hiding details of the connection from the application. Not only does this remove configuration
information from the application code but it also make the coding simpler.
To support the widest possible range of scenarios XUI uses JDBC for the underlying database access but limits itself to a fairly low level of features as some of the lightweight and open source databases have limited features. XUI builts upon this access by then adding features such as a caching layer and replication services.
For the most part once a table has been configured the application can use it as though it were any other node in the model. Rows and Fields can be addressed using XPath like expressions and the tables can be bound to UI components via the sort of adapters mentioned above.
For remote client applications databases can be replicated to the client device on demand and cached locally across sessions. Whenever a database resource is accessed the state of this cache is checked and updates are obtained as needed.
The transparent replication of tables from a server to client make it very easy to move functionality from a server to a client in order to create a standalone client.
The database may be used in the reverse scenario where a client application has been operating off-line and has stored information in the local client side database and needs to update the server. The client will again synchronize with the server side database, uploading data once a new session is initiated. Of course in a multiuser environment this sort of update places special design considerations on the database so that the consistency of any shared data can be preserved.

Services and communication

XUI introduces another special type of node to the model, an XServiceProxy node. This node type is a wrapper for a call to some function or service. At its most basic the service proxy node calls a function and as a result returns data. Access the proxy via the model effectively means calling that function. The function can be paramaterized by the nodes attributes and can be implemented in a variety of ways.
In XUI the service proxies are frequently layered to provide additional processing for features such as data checking, encryption, compression and so on. In some architectures this layers objects are termed ‘interceptors’.
Another common use of the service proxies is to wrap transport protocols such as Http. As you can imagine with something like an http call there are two sides to the call, a client and a server side. XUI provides for different configurations for the client and server sides and therefore the stack (of services) for each side of such a call can be configured as appropriate.

Routing

The layering of service calls is called routing in XUI. For example a call to a remote business operation might be made over a secure http channel. To provide such a route several services would be used; an encryption service, a compression service and an http service on the client side, while on the server side the call would pass through the http server side service, a (de)compression service, and a (un)encryption service before finally being processed by a business object of some sort.
As you can imaging an application may need several of such service stacks to implement all its needs. XUI allows a service proxy to be routed via any named route. The services at either end of the route act as the endpoints. At one end the service represents the point at which the service/route stack is bound into the model and at the other end the final service nomally implements or interfaces to the business process.
Although a route is comprised of several service proxies the stack of services that comprise the route are treated slightly differently than plain service nodes. A route can be reused by multiple service proxies, for example the http transport route described above could be reused for numerous calls within an application.
XUI’s support for routes does not stop with transport protocols. XUI also provides routes for fault tolerant communication, store and forward communications (i.e. data is forwarded once a communications channel becomes available), for redundant routing (communications can be attempted over several routes in parallel) and for failover services (an example might want to provide a default locel implementation if the server cannot be contacted).

Resource Loading

Invariably an application makes use of many resources such as graphics, text, data and files of various formats. An application could simple assume the resources it needs are available or are installed but this would make for an inflexible approach. Furthermore depending on the distribution mechanism the resource could well be located on a client machine in the fie system or in an archive or on a server somewhere. During the lifetime of an application the location of the resource may even change.
XUI’s resource manager class provides several methods for locating and retrieving a resource. The resource manager can also construct an input stream on behalf of the application and it may also retrieve objects such as graphics on behalf of the application.
In order to locate and/or retrieve a resource the resource manager attempts to find the resource on the classpath and on the file system. The resource manager can also make use of a custom class loader to search additional paths if needed (this strategy is employed by the IDE at design time).
In addition to this direct loading of resources XUI provides support for extract resources from the classpath to a temporary directory for subsequent loading. This may be necessary where it is assumed that a resource is accessed as a file (some databases make this assumption) or for loding of system files such as native libraries.

MVC pattern for separation of concerns

The Model-View-Controller pattern is another de facto industry standard and already it should be apparent that such a constructional pattern is employed by XUI. Support for this pattern is provided by the factory classes that help encapsulate the various UI components and features, by a rich data model and by the event and validation handling facilities that can be used to control the application in conjunction with the business logic.
The MVC patterns help to separate the architectural and modelling concerns in an application. With such a separation the role of each component is clearer and hence more maintainable.




Oldest known version of this page was edited on 2008-01-07 10:21:45 by LuanO []
Page view:

XUI Architecture




Return to the Evaluator's Guide
Page was generated in 0.2584 seconds