2007/04/20
20 Apr, 2007

WSO2 Commons Admin UI Framework

  • Saminda Abeyruwan
  • - WSO2

Introduction

WSO2 Admin UI framework [1] is an extensible framework used to generate multiple static pages (HTML). It also provides a base Javascript/AJAX library to communicate with servers using Web Services standards. This does not include any Web services QoS standards.

Note: WSO2 Admin UI framework will be referred to as framework here onward.

Artifacts and Dependencies

This framework consists of the following artifacts.

  1. wso2adminui-[version/timestamp].jar : Contains the servlet and UI processor.
  2. wso2adminui-[version/timestamp].zip : Contains the Javascript/A JAX library.

These artifacts are available at https://dist.wso2.org/maven2 under the groupID org.wso2.adminui.

The wso2adminui-[version/timestamp].jar artifact depends on the following third party JARs.

  1. Apache AXIOM API and Implementation (Latest head or released version)
  2. commons-logging-1.1.jar/log4j-1.2.13.jar
  3. stax-api-1.0.1.jar/ wstx-asl-3.2.0.jar/xml-apis-1.3.03.jar/mail-1.4.jar/jaxen-1.1-beta-10.jar

SVN/ Nightly Builds

The latest source code is available at

https://wso2.org/repos/wso2/trunk/commons/adminui for committers, and at

https://wso2.com/repos/wso2/trunk/commons/adminui for non-committers (read-only access.)

Nightly builds are available at https://dist.wso2.org/maven2 under the groupID org.wso2.adminui.

Main Components

Figure 1 shows the high level overview of the framework.

high_level_overview

Figure 1 - High Level Overview

The heart of the framework is the UI Processor. The output of the framework is a collection of HTML documents based on templates, resources, and ui-extensions-config.xml. Templates are special HTML documents that contain place holders (tokens), which will be processed and filled with the relavent resources. The rules in which these place holders should be processed and filled are in the ui-extensions-config.xml.

Once the documents are generated based on rules, templates and resources, an entity that will expose these documents will be created. This entity will be org.wso2.adminui.AdminUIServletFilter, which can be run on any J2EE environment (e.g., Tomcat) as shown in Figure 2.

 

figure2

Figure 2 - Request/Response

Thus, the framework's main components are,

  1. ui-extensions-config.xml - Used to configure the framework.
  2. org.wso2.adminui.AdminUIServletFilter - Filters the requests for the pages and sends the response to the browser.
  3. main.js and dhtmlHistory.js - Facilitates communicating with the servers and preserves the Back button function.

 

The following section describes the main components of the framework in detail.

1. ui-extensions-config.xml

The framework is configured using the ui-extensions-config.xml file. To generate the pages, the config file should be available in the classpath. The default config file is available at org/wso2/adminui/ui-extensions-config.xml of adminui-<version>.jar.

The configuration file has the following format:

 1 <extension-config>
2 <description/>
3
4
<files>
5 <file>foo.html</file> [1..*]
6 </files>
7
8
<file-mappings>
9 <mapping>
10 <token>@bar.items@</token>
11 <file>bar.html</file>
12 </mapping> [1..*]
13 </file-mappings>
14
15
<extension-order>
16 <item>core</item> [1..*]
17 </extension-order>
18 </extension-config>
19

Explainations of the element information items:

/extension-config : This is the root element. The configuration file should start with this element.

/extension-config/description : Provides the description.

/extension-config/files : Contains the templates [discussed later] that should be processed by the UI processor.

/extension-config/files/file : Represents the template that should be processed. This template location should be relative to the Web container's resource base context [discussed later]. There can be one or many file elements present.

/extension-config/file-mappings : Contains information on the file mappings. There can be one or many file mapping elements present.

/extension-config/file-mappings/mapping : Holds the information of the mapping itself.

/extension-config/file-mappings/mapping/token : Holds the token that should be replaced with the file content.

/extension-config/file-mappings/mapping/file : Holds the file whose content will replace the associated token.

/extension-config/extension-order : Holds the order in which the corresponding files should be processed.

/extension-config/extension-order/item : Holds the order in which the items should be processed. If the parent of this element is not present, ordering will be done according to the file system's lexical order.

1.1 Resource Base

ui-extensions-config.xml has rules to generate pages based on "resources". These resources are files such as HTML or XML. There should be a reference to the location of these resources. We introduced the concept of "Resource Base", which is the reference point to the locations of the resources. (It is assumed that there are resources available in the file system.) We currently do not support resources in a registry or any server such as LDAP.

The resource base provides the location in which all the static resources are available. For example, if you deploy foo.war in an Apache Tomcat environment, the default resource base will be ${tomcat.home}/webapps/foo if an exploded scenario has been used. Thus, this location will be referred to as the Web container resource base context. Thus, this location will be the "resource base" for ui-extensions-config.xml.

As seen in the above element information items, /extension-config/files/file and /extension-config/file-mappings/mapping/file hold the resource files. They are generally HTML or XML files.

Figure 3 Introduction to resource base

The above mentioned concepts are illustrated using Figure 3.

index.html and wso2.html are in the Web container resource base context. (resource base) . Thus, /extension-config/files/file should contain extension files in the Web container resource base context.

The corresponding ui-extensions-config.xml will be:

1 <extension-config>
2 ...
3
4
<files>
5 <file>index.html</file>
6 <file>wso2.html</file>
7 </files>
8 ...
9 </extension-config>

/extension-config/file-mappings/mapping/file contains the mapping. The content of it will be replaced with the associated token (which will be discussed later). These mapping files should only be available at [resource base ]/extensions/[any] locaton. As you can see from the above figure, js.html is in /extensions/core and css.xml and divs.html are in /extensions/bar. (More on this area will be discussed later) Thus, the corresponding ui-extensions-config.xml is as follows.

 1 <extension-config>
2 ...
3 <file-mappings>
4 <mapping>
5 ...
6 <file>divs.html</file>
7 </mapping>
8 <mapping>
9 ...
10 <file>js.html</file>
11 </mapping>
12 <mapping>
13 ...
14 <file>css.xml</file>
15 </mapping>
16 </file-mappings>
17 ...
18 </extension-config>

2. Templates

/extension-config/files/file element holds the files that need to be processed. These files are called templates. These templates can be embedded with place holders (tokens) to inject content to at the time of processing. These templates should be contained only in the Web container resource base context. Place holders are marked by the "@foo@" notation.

Example 1: index.html

 1 <html>
2 <head>
3 <title>Management Console</title>
4
5
<!-- #################################################################### -->
6 <!-- Place Holder for CSS File References -->
7 <!-- #################################################################### -->
8 <link rel="stylesheet" type="text/css" href="css/main.css" media="screen, projection"/>
9 @css.file.items@
10
11
<!-- #################################################################### -->
12 <!-- Place Holder for Javascript File References -->
13 <!-- #################################################################### -->
14 <script language="javascript" src="js/main.js"></script>
15 <script language="javascript" src="js/dhtmlHistory.js"></script>
16 @js.file.items@
17 </head>
18
19
<body>
20 <!-- ####################################################################### -->
21 <!-- Place Holder for div Items -->
22 <!-- ####################################################################### -->
23 @div.items@
24
25
</body>
26 </html>

Thus the @css.file.items@, @js.file.items@ and @div.items@ place holders will be processed and injected with content.

3. Tokens

/extension-config/file-mappings/mapping/token holds all the place holders that need to be processed. These place holders are also known as tokens. These tokens are represented with the "@foo@" notation.Coupled with each token is the "file" (/extension-config/file-mappings/mapping/file) that holds the content that needs to be injected. These files are generally HTML or XML.

 

These files that are associated with each token should be given relative to the [resource base]/extensions/[any] path. "[resource base]/extensions/core" will be the default path.

Thus, the example 1: index.html will have the following configuration file. For example, when the index.html finds @css.file.items@, that location will be replaced with the content of the css.html.

 1 <extension-config>
2
3
<description>Configuration file for example-1::index.html</description>
4
5
<files>
6 <file>index.html</file>
7 </files>
8
9
<file-mappings>
10 <mapping>
11 <token>@css.file.items@</token>
12 <file>css.html</file>
13 </mapping>
14 <mapping>
15 <token>@js.file.items@</token>
16 <file>js.html</file>
17 </mapping>
18 <mapping>
19 <token>@div.items@</token>
20 <file>div.html</file>
21 </mapping>
22 </file-mappings>
23
24
<extension-order>
25 <item>core</item>
26 <item>extras</item>
27 </extension-order>
28
29
</extension-config>

Let's look at the above configuration relative to a file system (Linux or MS Windows) with some important properties. Figure 4 shows the layout.

Figure 4 - File system layout of example 1

As you can see from the above format, div.html appears in /extensions/core and /extensions/extras/. This is where /extension-config/extension-order/item comes into play. First the UI processor will inject the contents in div.html that is present in /extensions/core. After which the UI processor will inject the content in div.html that is present in /extensions/extras. So, the /extensions-config/extension-order handles the order in which the items should be processed to be placed in the place holders.

4. UIProcessor

org.wso2.adminui.UIProcessor.createPages(final String resourceBase,String configFileName,final Map mainFileMap) will process the pages and they will be available in 'mainFileMap'. org.wso2.adminui.AdminUIServletFilter will respond with the files when the user asks for it.

Example

The best way to get the semantics of WSO2 Admin UI is to give a working example of this. At the end of this example, you will know everything you need to know to work with Admin UI processing.

Prerequisites

  • Apache Tomcat 5.5.x distribution
  • log4j-1.2.13.jar
  • commons-logging-1.1.jar
  • wso2adminui-1.2-SNAPSHOT.jar
  • axiom-api-SNAPSHOT.jar
  • axiom-impl-SNAPSHOT.jar
  • stax-api-1.0.1.jar
  • jaxen-1.1-beta-10.jar
  • mail-1.4.jar
  • xml-apis-1.3.03.jar
  • wstx-asl-3.2.0.jar

The source code is available at https://wso2.org/files/admin_ui_src.zip

adminui_test.war is available at https://wso2.org/files/admin_ui.war

Let's look at the layout of our sample. There will be an index.html and a working.html at the root level.

The following picture shows the file system layout of an exploded adminui_test.war:

Figure 5 : Example's file system layout

The sample index.html looks as follows: This is the template.

It has a place holder @div.items@ to inject content.

The sample working.html looks as follows: This is another template.

It has a place holder @working.items@ of the injected content.

Let's look at the ui-extensions-config.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
2 <extension-config>
3 <description>Sample Admin UI Configuration</description>
4
5
<files>
6 <file>index.html</file>
7 <file>working.html</file>
8 </files>
9
10
<!--
11 Mappings of Tokens to files. When these tokens are found in
12 a file listed above, they will be replaced with the
13 contents in the corresponding mapped files.
14 -->
15 <file-mappings>
16 <mapping>
17 <token>@div.items@</token>
18 <file>divs.html</file>
19 </mapping>
20 <mapping>
21 <token>@working.items@</token>
22 <file>working_div.html</file>
23 </mapping>
24 </file-mappings>
25
26
<!--
27 The Management Console ordering will first order according to this
28 order, and thereafter, order the extension items in the natural
29 order of their names.
30 -->
31 <extension-order>
32 <item>core</item>
33 <item>extras</item>
34 </extension-order>
35 </extension-config>

As you can see from the configuration file and layout from Figure 5, divs.html and working_div.html are either available in /extensions/core or /extensions/extras folder. As you might have guessed, there are two divs.html files, one in /extensions/core and one in /extensions/extras. Now if you want the UI processor to process divs.html in /extensions/core first, rather than the divs.html in /extensions/extras, you'll have to provide the extension order as shown in ui-extensions-config.xml. If you swap the items in /extension-config/extension-order, you'll observe that the content in divs.html in /extensions/extras has been processed first. If you ignore or completely comment out the /extension-config/extension-order element, the UI processor will process the mapping files and embed its content in place holders with respect to the file system's lexical order. Try this out.

Sample divs.html that comes in /extensions/core would look as follows:

Let's write the servlet to process the UI, and call it UIServlet. It'll be available in the package org.wso2.adminui_test. The complete working code is as follows:

 1 package org.wso2.adminui_test;
2
3
import org.wso2.adminui.UIProcessor;
4 import org.wso2.adminui.UIProcessingException;
5 import org.wso2.adminui.AdminUIServletFilter;
6
7
import javax.servlet.ServletConfig;
8 import javax.servlet.ServletException;
9 import javax.servlet.ServletContext;
10 import javax.servlet.http.HttpServlet;
11 import java.util.Map;
12 import java.util.Hashtable;
13
14
public class UIServlet extends HttpServlet {
15
16
public void init(ServletConfig servletConfig) throws ServletException {
17 // assumes only exploded case
18 ServletContext servletContext = servletConfig.getServletContext();
19 String resourceBase = servletContext.getRealPath("."); // Obtaining the resource base.
20 Map files = new Hashtable();
21 try {
22 UIProcessor.createPages(resourceBase, "ui-extensions-config.xml", files);
23
24
AdminUIServletFilter adminUIServletFilter = (AdminUIServletFilter) servletContext
25 .getAttribute(AdminUIServletFilter.class.getName());
26 adminUIServletFilter.init(files,"/adminui_test");
27
28
29
} catch (UIProcessingException e) {
30 throw new ServletException(e);
31 }
32
33
}
34 }
35

The above code assumes that the adminui_test.war has been exploded. The 'files' map holds the processed contents. Finally, let's look at the web.xml.

 1 <?xml version="1.0" encoding="UTF-8"?>
2
3
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"https://java.sun.com/dtd/web-app_2_3.dtd">
4 <web-app>
5 <filter>
6 <filter-name>UIFilter</filter-name>
7 <filter-class>org.wso2.adminui.AdminUIServletFilter</filter-class>
8 </filter>
9 <filter-mapping>
10 <filter-name>UIFilter</filter-name>
11 <url-pattern>/*</url-pattern>
12 </filter-mapping>
13 <servlet>
14 <servlet-name>UIServlet</servlet-name>
15 <servlet-class>org.wso2.adminui_test.UIServlet</servlet-class>
16 <load-on-startup>0</load-on-startup>
17 </servlet>
18
19
</web-app>

As you can see from the web.xml, the UIServlet will be loaded at startup. The UIFilter will respond with the processed content, if the user requests for it.

The output of the above processed files can be observed as follows in you favourite browser,

How to add a processing resource at runtime

It's very simple. You have to list the new file in /extension-config/files/file, add the relevant mapping, and restart the system.

Conclusion

The Admin UI Framework provides flexible and extensible components to generate static and dynamic contents in a J2EE environment. Though this article does not cover the Javascript/AJAX library, this framework consist of a flexible Javascript/AJAX library to communicate with servers using Web Services standards, without QoS support.

To learn how to use main.js and dhtmlHistory.js and how the WSO2 Admin UI is integrated with WSO2 Web Services Application Server (WSAS), please refer to : Customizing WSO2 Admin UI and Web Services Application Server Management

 

References:

[1] Admin UI

[2] WSO2 Web Services Application Server

[3] WSO2 Enterprise Service Bus

[4] WSO2 Mashup Server

Author

Saminda Abeyruwan, Software engineer, WSO2 Inc. saminda at wso2 dot com

 

 

 

About Author

  • Saminda Abeyruwan
  • WSO2 Inc.