Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
CosmosDataReportingComponent10 209226
Back to Data Reporting Design
Contents
Change History
Name: | Date: | Revised Sections: |
---|---|---|
Sheldon Lee-Loy | 11/14/2007 |
|
Sheldone Lee-Loy | 11/29/2007 |
|
Workload Estimation
Process | Sizing | Names of people doing the work |
---|---|---|
Design | 1 | Sheldon Lee-Loy |
Code | 2 | Sheldon Lee-Loy |
Test | 1 | Sheldon Lee-Loy |
Documentation | 1 ** | |
Build and infrastructure | 0.2 | |
Code review, etc.* | 0.2 | |
TOTAL | 5.4 |
'* - includes other committer work (e.g. check-in, contribution tracking)
'** - documentation may span multiple release. Note an additional enhancement is associated with a programmer's guide (ER 210134)
Purpose
This enhancement will cover the development of a web application user interface.
Requirements
The following are basic requirements needed to create a web user interface.
- Views are required to visualize data from some external datasource. These views are constructed from basic widgets such as tables, trees, button, etc. Expoliters should have the ability to create new views and deployed these new views within the COSMOS UI infrastructure. Furthermore, the infrastructure will provide some common used views that can be configured by exploiters. These common views are developed specifically for System Management operations. These views are further explained in enhancement 208603 (Register Visualzations with a Query Response - programmin...).
- A mechanism is required to layout Views within the page. Exploiters of the infrastructure should have the ability to create different "flavors" of the ui by configuring the page layout.
The ui infrastructure heavily relies on the dojo toolkit. Rather than trying to reinvent the wheel the COSMOS ui infrastructure makes use of many of the dojo toolkit design patterns. The COSMOS ui utilizes the dojo toolkit to do the following
- object declaration/inheritance
- pub/sub messaging
- method connections
- attach points
- asynchronous requests
The COSMOS UI design implores several dojo programming models. Familiarly with the Dojo toolkit is required to understand the COSMOS ui infrastructure. This document will not cover Dojo concepts.
Design
Pages Templates
A page template is a concept introduced by the COSMOS UI infrastructure. These are html files that create the structure of the page. Exploiters can associate an attachpoint with a section within the page. Exploiters can then register a view to a particular attachpoint. When the page template is rendered the COSMOS UI runtime will place the view in the associated section on the page.
Consider the following example:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>My User Interface</title> <script type="text/javascript" src="dojo/dojo/dojo.js" djConfig="isDebug: false, parseOnLoad: true"> dojo.require("cosmos.widget.*"); dojo.require("cosmos.utility.*"); dojo.require("dojo.parser"); </script> <style type="text/css"> @import "dojo/dojo/resources/dojo.css"; @import "dojo/dijit/themes/tundra/tundra.css"; </style> </head> <body class="tundra"> <table style="background-color:#eee" width="100%"> <tr><td> <div dojoType="cosmos.widget.WidgetContainer" attachPoint="nav"></div> </td></tr> <tr><td> <div dojoType="cosmos.widget.WidgetContainer" attachPoint="details"></div> </td></tr> </table> </body>
Notice that the template file is a regular html file. This gives the exploiter alot of flexibility to layout the page. Also notice that attach points are created by declaring a "comos.widget.WidgetContainer" element and setting the "attachPoint" attribute to a tagname. This will identify these section of the page as attach points. As a result any views that are registered to any of these attach points are placed in the particular section within the page. It should be noted that the following lines are always required in a page template:
<script type="text/javascript" src="dojo/dojo/dojo.js" djConfig="isDebug: false, parseOnLoad: true"> dojo.require("cosmos.widget.*"); dojo.require("cosmos.utility.*"); dojo.require("dojo.parser"); </script>
This will enable the dojo parser and include the COSMOS and dojo javascript files.
Widgets
Views are rendered by creating dojo widgets. The default views provided by the COMSOS ui are all widgets that have been inherited or composed of basic dojo widgets. The default widgets are developed in javascript files and deployed under /COSMOSUI/cosmos/widgets
Since these views are dojo widgets exploiters familiar with working with dojo widgets can either create these widgets programmically or declaratively. Refer to the dojo documentation to understand how this is done.
Creating new widgets
It is recommended that new widgets should be created using the dojo toolkit programming model. This will make deployment of the widgets easier with the COSMOS UI infrastructure. However it's not a requirement. Lets look at creating a tree widget to get an understanding how the COSMOS UI infrastructure exploits the dojo programming model.
dojo.provide("my.widget.Tree'); dojo.declare( // class "my.widget.Tree", // superclass [dijit.Tree], // member variables/functions { title:'This is my tree', postCreate: function(){ alert(this.title); //call superclass my.widget.Tree.superclass.postCreate.apply(this, arguments); } } );
The above example shows a widget class that inherits the behavior of dijit.Tree. Exploiters can instantiate this new widget programmically as follows:
var mywidget = new my.widget.Tree({title:"this is my title"});
The above line will create my custom widget and change the title. Note that the properties of the widget can change by passing in a javascript object. Also note that the javascript object is in JSON format which is quite nice. As a result, exploiters can configure dojo widgets by providing JSON data. The COSMOS UI infrastructure exploits this behavior.
View Configuration Files
The COSMOS UI introduces a notion of configuration files named as view.jprop. These configuration files will configure a particular view within the browser page. For example consider the following configuration file:
{ clazz: "cosmos.widget.Navigator", initialize: "MDRTreeJSON", Query: {nodeClass:'mdr*'}, initQueryHandler: "handler/json/nav.json", publish: ['properties', 'detail'] }
The COSMOS UI runtime will process the above configuration file to configure a view within the page. A "cosmos.widget.Navigator" dojo widget will be instantiated and initialized with a set of properties specified in the configuration file. Therefore the above configuration file will translate to the following javascript code in the COSMOS UI runtime:
var mywidget = new cosmos.widget.Navigator({initialize: "MDRTreeJSON",Query: {nodeClass:'mdr*'},initQueryHandler: "handler/json/nav.json",publish: ['properties', 'detail']});
Note that the "clazz" property is a specialized property that the COSMOSUI makes use of to determine the widget class to instantiate.
Now let us look at trying to create a page that has three quadrants with different views. Let us create the following page:
Note that I have a tree widget on the left hand side, a XML viewer on the top right quadrant and a properties table on the bottom right quadrant. To construct this page we first create the following report template.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>COSMOS Web User Interface</title> <script type="text/javascript" src="dojo/dojo/dojo.js" djConfig="isDebug: false, parseOnLoad: true"> </script> <style type="text/css"> @import "dojo/dojo/resources/dojo.css"; @import "dojo/dijit/themes/tundra/tundra.css"; .container{ width: 100%; height: 800px; background: #eeeeee; } </style> <script> dojo.require("cosmos.widget.*"); dojo.require("cosmos.utility.*"); dojo.require("dojo.parser"); dojo.require("dijit.layout.SplitContainer"); dojo.require("dijit.layout.ContentPane"); dojo.require("dijit.TitlePane"); </script> </head> <body class="tundra"> <table width="100%" border="0" cellspacing="0" cellpadding="0" class="wpsBannerEnclosure"> <tr> <td height="35" align="left" bgcolor="#F5F5F5"><img alt='Cosmos Data Visualization UI' title='Cosmos Data Visualization UI' src='views/cosmos/images/bannerLeft.gif'/></td> <td height="35" align="right" bgcolor="#F5F5F5"></td> </tr> </table> <table style="background-color:#eee" width="100%"> <tr><td style="padding: 10pt"></td></tr> </table> <div dojoType="dijit.layout.SplitContainer" orientation="horizontal" sizerWidth="10" activeSizing="false" class="container"> <div dojoType="dijit.layout.ContentPane" sizeShare="30" sizeMin="20"> <div dojoType="dijit.TitlePane" title=" Lazy Load Tree" class="navigator"> <div dojoType="cosmos.widget.WidgetContainer" attachPoint="nav"></div> </div> </div> <div dojoType="dijit.layout.SplitContainer" orientation="vertical" sizerWidth="10" activeSizing="false" class="container"> <div dojoType="dijit.layout.ContentPane" sizeShare="40" sizeMin="20"> <div class="detail" dojoType="dijit.TitlePane" title=" Details" sizeShare="60" sizeMin="20"> <div dojoType="cosmos.widget.WidgetContainer" attachPoint="detail"></div> </div> </div> <div dojoType="dijit.layout.ContentPane" sizeShare="40" sizeMin="20"> <div dojoType="cosmos.widget.WidgetContainer" attachPoint="properties"></div> </div> </div> </div> </body>
Note that I use html tags and dojo widgets to construct the page. Since the page is a regular html page I can utilize existing layout widgets such as the dijit.layout.SplitContainer dojo layout container to construct my layout. I can utilize other layout containers defined by the DOJO toolkit (http://dojotoolkit.org/book/dojo-book-0-9/part-2-dijit/layout)
At certain sections within the page I add the following declartive text:
<div dojoType="cosmos.widget.WidgetContainer" attachPoint="detail"></div>
This above text declares a "detail" attachpoint. Any view associated with a "detail" attach point will be rendered within this page section.
Now let us look at configuring a tree view and attaching the view to the "nav" attach point specified in the page template. We create the following properties file.
{ clazz: "cosmos.widget.Navigator", query: {nodeClass:'mdr*'}, initQueryHandler: "handler/json/nav.json", publish: ['properties', 'detail'] }
Note that the "clazz" property refers to a cosmos dojo widget that is able to render a tree. This dojo widget is called "comos.widget.Navigator" and has a set of configuration properties. The following shows the properties that can be configured for the "cosmos.widget.Navigator" dojo widget:
query: the cosmos.widget.Navigator widget stores it's data model as a dojo data source (http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/what-dojo-data/using-datastores). As a result this property defines the query string to fetch the information to show the top level nodes
initQueryHandler: a url to a datafeed that provides the JSON data structure that will show the inital root nodes
publish: a list of topics to publish node selection events to. Refer to the dojo event system for more information(http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/event-system)
I would save the configuration properties file as view.jprop under the views directory as follows:
/views/nav/view.jprop
By saving the configuration file under /views/nav this "attaches" this view to the "nav" attach point. Similarly I would create configuration files for the properties table and BIRT report view and store them under /views/properties/view.jprop and /views/detail/view.jprop respectively.
The view can further be configured depending on the type of data that is presented in the view. For example, different icons can be associated with different nodes in the tree to signify certain visualization cues. As mentioned in the "Data Tagging" section, the data feeds may tag the data with metadata information. The views can uses this meta data to add visual decorators when representing the data within the view. The views can also use this metadata to change how the view behaves. For example, expanding a node in a tree may instantiate a different query object. Exploiters can define a data property file to associate a metadata tag to visual and behavioral cues. The following is an example of a data property file:
{ mdr:{ menuType: {clazz:"cosmos.widget.QueryMenu", query:{clazz:"cosmos.query.BasicQuery", queryHandler:"handler/cosmos/widget/Navigator/stat.json"}, label: "Create Query"}, icon: "images/cmdbf_query.gif" }, mdrcbe:{ menuType: {clazz:"cosmos.widget.QueryMenu", query:{clazz:"cosmos.query.CMDBfQuery", queryHandler:"handler/cosmos/widget/Navigator/stat.json"}, label: "sUBMITqUERY"}, icon: "images/cbe.gif", expandQuery:{clazz:"cosmos.query.BasicQuery", queryHandler:"handler/cosmos/widget/Navigator/cbe.json"} }, mdrstat:{ icon: "images/stat.gif", expandQuery:{clazz:"cosmos.query.BasicQuery", queryHandler:"handler/cosmos/widget/Navigator/stat.json"} } }
The above example shows a data file that defines visual and behavioral cues for a tree widget. The tree will show the "images/cmdbf_query.gif" icon for any data tagged with a value of "mdr". Also a popup menu will be shown for any node that is visualizing data that is tagged with a value of "mdr".
Data Tagging
The COSMOS UI implores a RESTful Web 2.0 design pattern where the data is served by data feeds. The data feeds provide JSON datastructures. The structure of the JSON data is consumed by the view widget. Note that the JSON data structure provides a contract between the backend data and the user interface. This architecture provides a clear decoupling between the raw data and the user interface. As a result, new UI widgets, that conform to the JSON contract, can be constructed to create different visualizations. The following is an example of a JSON structure used to send a list of three nodes to a tree widget.
{ identifier: "object", label: "title", items:[ {tag:"mdrstat", title:"Statistical Data",object:“21"}, {tag:"mdrcbe",title:"Monitoring Data",object:"14"}, {tag:"mdr",title:"Asset Repository", object:“91"},} ] }
The above example defines three objects that have three attributes (tag, title, and object). The tree widgets uses these atributes to construct nodes within the tree. The title attribute signifies the name of the node, the object attribute provides a unique id and the tag attribute provides meta data information. The tag attribute is an important attribute that is processed by the COSMOS widgets. The widgets makes use of the tag attribute to determine if certain visual or behavorial cues should be applied to the node. For example, a specific icon can be rendered for data with specific tag values or different menu items can be shown in the menu bar for specific tagged data.
Data Feeds
The COSMOS UI infrastructure will implore a RESTful service architecture. Data models required by the DOJO widgets will be produced by JSON feeds via HTTP requests as illustrated below:
Note that query objects are created to create the binding logic between the DOJO widget and the HTTP request as mentioned in the previous sections.
The following is an overview how data feeds will be constructed.
A request delegator will receive the request and instantiate a particular outputter that will handle the request. The request delegator will provide interfaces to deserialize the request into a set of parameters that the outputter understands. The request delegator will also provide a global store that outputters can save state data. Note that the outputter themselves are stateless and can only change the state of the store.
Client browsers can make a request to a particular data feed by constructing the appropriate HTTP request. Consider the following request
/COSMOSFeeds?service=/org/eclipse/cosmos/provisional/tree/json¶m1=2343245¶m2=select
COSMOS will provide a single service that will receive requests from the client to generate a particular data feed. The "service" parameter will dictate the outputter to instantiate. For example, the above request will cause the request delegator to instantiate org.eclispe.cosmos.provisional.tree.json.Outputter. The delegator will pass a parameter map with two parameters: param1 and param2. Exploiters can define custom outputters and add the outputter class to the classpath of the request delegator.
The following define the IOuputter, IParameters and IStore interfaces.
IOutputter
/** * Provides data feeds */ public interface IOutputter { /** * A resolver class that will generate unique ids. unique ids * may be required by the outputter to identify particular items in * the generated output. * @param idResolver id resolving class */ public abstract void setIdResolver(IIDResolver idResolver); /** * Writes content to a PrintWriter. An input map is passed to this method * that the render method will use to generate the data feed * @param output a PrintWriter that method will write to * @param input an input map that contains name value pairs * @throws Exception */ public abstract void render(PrintWriter output, IParameters input) throws Exception; /** * This method is called write after instantiating the outputer. A persisted storage * object is passed that outputters can use to save state * @param store a persistent storage object * @param parameters an input map that contains name value pairs * @throws Exception */ public abstract void initalize(IStore store, IParameters parameters) throws Exception; }
IParameters
/** * Provides a list of name value map that is used by outputters as input * parameters. */ public interface IParameters { /** * Returns a parameter value with an associated key name * @param name - key name * @return value of the parameter */ public String getParameter(String name); }
IStore
/** * Persistent storage used by outputters to save state */ public interface IStore { /** * Returns a value from the store with provided key name * @param name - key name * @return stored value */ public abstract Object getAttribute(String name); /** * Stores a value with an associated key name * @param name - key name * @param value - value to store */ public abstract void setAttribute(String name, String value); }
Error Handling
Client-side error handling is discussed in enhancement 209223
Deployment Model
As explained in the previous sections there are several components involved in the COSMOS UI infrastructure. These components are as follows:
- Page Templates
- Widgets
- View Configuration Files
The COSMOS UI infrastructure defines a deployment model to deploy the above components:
/dojo -Directory where dojo widgets and classes are deployed /pages -Directory where pages are deployed /views -Directory to store view and data configuration files
The page directory is further structured as follows:
/pages/<namespace>/index.html - defines the page template /pages/<namespace>/images - defines images associated with the page template /pages/<namespace>/css - defines style sheets associated with the page template
Note a namespace is associated with a page template. This allows the COSMOS ui infrastructure to server many different pages. For example I can define two diffent pages with different layout and view configurations such as:
/pages/cosmos/index.html /pages/cosmosBlue/index.html
To access each page I would enter the following urls respectively:
http://localhost:8080/COSMOSUI/?page=cosmos
http://localhost:8080/COSMOSUI/?page=cosmosBlue
The Dojo directory is further structured as follows:
/dojo/cosmos - contains comsmos dojo widgets and classes /dojo/cosmos/provisional/widget - defines cosmos widgets /dojo/cosmos/provisional/utility - defines cosmos utility classes /dojo/cosmos/provisional/data - defines cosmos data classes
Note that the above naming convention follows a similar pattern suggested by the Eclipse Naming document (http://wiki.eclipse.org/Naming_Conventions)
Exploiters can deploy their own widgets and classes under the 'dojo' directory. For example, the following defines custom classes under the dojo/mywidget
directory:
/dojo/mywidget
The view directory contains the view and data property file. The structure of the view directory is explained in the previous section.