Vroom Framework

From Wikipedia, the free encyclopedia
Jump to: navigation, search

Vroom Framework is Java based web application development framework. It is written using J2EE 1.4 specifications to make compatible with all Java EE 1.4 compliant web/application servers.

Contents

[edit] History

Vroom Framework is architected and developed by Farrukh Ijaz s/o Mohammad Riaz in March 2008. It was originally designed with a concept of altering the source code of web pages at run-time based on a configuration file (vroom-config.xml) to create binding between the HTML DOM events and server side Java methods.

Vroom-2, which is the latest version of Vroom Framework, has been revamped to eliminate all the limitations of the first version.

[edit] Architecture

The framework consists of following elements:

  • Core API: The API of the framework is packaged as vroom.jar which contains filter, controller, and other helper classes. The filter and controller is configured by defining entries in web.xml file of the web application.
  • JavaScripts: There is one JavaScript file named vroom.js which is part of the framework but it is not packaged as vroom.jar file. It is placed in \WEB-INF\ folder of the web application. The reason for keeping it outside the package is to provide the developer an opportunity to improve the existing functions as well as to include additional functions if required.
  • Configuration File: Once the framework is set up, a configuration file is maintained for the web application to instruct the framework how to perform certain actions. The file is typically named as vroom-config.xml. It is placed in \WEB-INF\ folder and specified in the config-file attribute of the filter definition in web.xml.

[edit] Installation and Configuration

The framework's latest distribution can be obtained from Project's website. To install the framework, following the instructions below:

  1. Download the latest Vroom-x.x.x.zip file and extract it to the location which is normally used for java libraries e.g. C:\CLASSPATH\Vroom-x.x.x\.
  2. Create a web application and copy the contents available in Vroom-x.x.x\WEB-INF\ folder of the library to your web application's \WEB-INF\ folder.
  3. Define the following entries in web.xml of the application:

    <filter>
        <filter-name>VroomFilter</filter-name>
        <filter-class>net.openkoncept.vroom.VroomFilter</filter-class>
        <init-param>
            <param-name>config-file</param-name>
            <param-value>/WEB-INF/vroom-config.xml</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>VroomFilter</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    <servlet>
        <servlet-name>VroomController</servlet-name>
        <servlet-class>net.openkoncept.vroom.VroomController</servlet-class>
        <init-param>
            <param-name>upload-file-size-threshold</param-name>
            <param-value>1024000</param-value>
        </init-param>
        <init-param>
            <param-name>upload-file-temp-folder</param-name>
            <param-value>/WEB-INF/temp</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>VroomController</servlet-name>
        <url-pattern>/vroom</url-pattern>
    </servlet-mapping>

    Note: You can change config-file, upload-file-size-threshold, upload-file-temp-folder attributes. However, url-pattern for VroomController have to be /vroom. Also remember, the filter-mapping is very important in terms of intercepting the requests. If you want to intercept Html pages (*.html), Struts Actions (*.do) or JSF pages (*.faces), you need to define separate filter-mapping for each of them, otherwise the framework won't be able to manage them.

That's all related to Installation and Configuration of the framework and web application is ready to utilize Vroom Framework.

[edit] How it works?

Vroom Framework can manage anything related to HTML DOM, including Document, Window and Navigator objects. The framework can be used independently or it can be integrated with other Model-2, MVC frameworks. In some aspects, Vroom Framework provides better control of your website e.g. You may want to include Google Analytics JavaScript to your webpages. To do that you probably use one of the following approaches:

  • Open every webpage and paste the JavaScript code Or
  • Use a separate html/jsp file for JavaScript code and modify every webpage to include the include statement Or
  • Use tiles approach if you're using Struts Framework

The first two approaches are quite time consuming; the second approach does not work with HTML pages and in case of third approach, not all applications are built on Struts Framework. Vroom Framework eliminates all this hassle and provides you an easy to use approach to inject such type of scripts by defining webpage element in vroom-config.xml file. Below is the sample webpage definition to accomplish the goal:

<webpage uri="/|(/|[a-z]|[A-Z]|[0-9]|-|_)*.(jsp|html)">
    <script type="text/javascript" url="#{contextPath}/scripts/google-analytics-script1.js"/>
    <script type="text/javascript" url="#{contextPath}/scripts/google-analytics-script2.js"/>
</webpage>

Here is the detail of the above definition:

  • With webpage element, we instruct the framework to intercept all the webpages satisfying the uri /|(/|[a-z]|[A-Z]|[0-9]|-|_)*.(jsp|html) which is a Java specific regular expression. You can always define your own regular expression to include/exclude specific webpage.
  • The script child tag instructs the framework to inject the script to all the webpages.
  • The #{} is the format to access server variables. #{contextPath} is replaced with web application's context path.

The benefits of this approach are:

  1. You don't need to modify your webpages to include the scripts
  2. The approach works for any type of HTML file whether it's *.jsp or *.html
  3. The rule will automatically include newly added pages or exclude removed pages

Coming back to the original point, how the framework works?

It's driven by vroom-config.xml file. When a web application is deployed to the application server, the server loads the filter and controller defined in the web.xml file. As part of VroomFilter loading, the vroom-config.xml file is loaded and becomes available to the framework as a configuration object. Every time when the filter intercepts a request, it consults the configuration object to provide rules (defined as webpage elements) for the request. If no rule is found, the filter ignores the request and processing continues as normal, otherwise, based on the rules, the filter injects the required scripts, stylesheets and meta-tags to the final response of the request and delivers the modified response to the client. User interacts with the webpage as usual and if in execution of any HTML DOM event, which was bound to a server side Java method as per definition in the configuration file, an AJAX request is initiated. The response of the AJAX request is always JSON string. In the vroom-config.xml file, it can be define what to do in response of the event. E.g. to update HTML content or to invoke any JavaScript code. This is explained in detail in the following section.

[edit] Structure of the Configuration File (vroom-config.xml)

The configuration file contain following elements and attributes:

Elements Child Elements Attributes Description
vroom-config
  • webpage [0..*]
  • N/A
This is the root element of the configuration file.
webpage
  • meta [0..*]
  • stylesheet [0..*]
  • script [0..*]
  • object [0..*]
  • form [0..*]
  • element [0..*]
  • event [0..*]
  • uri [required]
  • bean-class
  • var
  • scope
This is the main element used to define rules for webpages. The uri attribute accepts Java specific regular expressions. The bean-class attribute is used to specify Java class which is available in the class path at runtime. The var attribute is used to specify the variable name of the Java class. The scope is specified to locate object either in application, request or session scope. If bean-class is specified but var and scope left empty, the framework will create object of the bean-class with the name exactly as bean-class and set it in application scope.
meta
  • N/A
  • name
  • http-equiv
  • content [required]
This tag is rendered as <meta> tag in the <head> section. Either the name or the http-equiv should be used.
stylesheet
  • CDATA
  • type [required]
  • url
This tag is rendered as <link> tag in the <head> section if the url is specified, otherwise, <style> tag is rendered along with the CDATA. The url must start with #{contextPath} if the resource belongs to the web application. The type should be set "text/css".
script
  • CDATA
  • type [required]
  • url
This tag is rendered as <script> tag in the <head> section. If the url is specified, the CDATA is ignored. The url must start with #{contextPath} if the resource belongs to the web application. The type should be set as "text/javascript".
object
  • event [0..*]
  • name [required]
  • bean-class
  • var
  • scope
This tag is used to register events of objects accessible with in the webpage. In general the name is set as document, window or navigator. However, it can be any object accessible by name. If bean-class, var and scope are not specified, the framework will use the bean-class, var and scope defined for enclosing webpage element, otherwise these attributes will take precedence over the attributes of webpage element.
form
  • navigation [0..*]
  • element [0..*]
  • event [0..*]
  • id [required]
  • method
  • bean-class
  • var
  • scope
This tag is used to register form events. The method attribute is optional, but if used, it's the Java method available in the Java class specified in the bean-class attribute. If bean-class, var and scope are not specified, the framework will use the bean-class, var and scope defined for enclosing webpage element, otherwise these attributes will take precedence over the attributes of webpage element. The method must have the following signature:

public void|String methodName(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse);

The return type of the Java method can be void or String. If it's void then the method should handle the response forward or redirect. If it's String then the framework can handle response forward or redirect based on the <navigation> element.

navigation
  • N/A
  • outcome [required]
  • url [required]
  • forward
This tag tells the framework, if the return value of the form method matches with the outcome of this navigation, then based on the value of forward attribute, if it's true then send response forward to the url specified otherwise send redirect. The default value of forward attribute is false. If the outcome of a navigation is set to "default" the framework will use that if the return value of the form method is null or does not have a matching outcome in any of the navigations defined for the form.
element
  • event [0..*]
  • id [required]
  • property
  • format
  • bean-class
  • var
  • scope
This tag is used to register events of html elements which are either accessible by name or id with in the webpage. Typically those elements are defined which generate events such as onclick, onblur, onchange etc. If bean-class, var and scope are not specified, the framework will use the bean-class, var and scope defined for enclosing form or webpage element, otherwise these attributes will take precedence. The property and format attributes are only available if the element is defined as child of form element. If property is not specified, the id attribute is used to locate property of the bean-class. The format attribute can be set if the element is used to collect date. This format is then used by the framework to convert entered date value to java.util.Date. E.g. on the form, user may be asked to enter date in MM/dd/yyyy format, so the format must be specified in that case otherwise the user entered date will not be set to the corresponding bean-class property.
event
  • call [0..*]
  • type [required]
  • method
  • bean-class
  • var
  • scope
This is the most important element of the configuration. It's available in webpage, object, form and element elements of the configuration. The type attribute is the event type such as onclick, onblur, onload, onunload, etc. For complete list of supported elements please see the event type table at the end of this document. The method attribute is optional, but if used, it's the Java method available in the Java class specified in the bean-class attribute. If bean-class, var and scope are not specified, the framework will use the bean-class, var and scope defined for enclosing object, element, form or webpage element, otherwise these attributes will take precedence. The method must have one of the following signatures:

public void|Object methodName();
public void|Object methodName(javax.servlet.http.HttpServletRequest);
public void|Object methodName(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse);

The return type of the Java method can be void or can be any valid Java object including but not limited to String, Short, Integer, Long, Boolean, Float, Double, java.util.Date, java.util.Collection, java.util.Map, java.util.Properties or any valid Java Bean. The method always returns JSON string of the returned object. If the return type is String, Short, Integer, Long, Boolean, Float, Double or java.util.Date, the value is accessed using #{value} in call elements. If it's a Collection or Array then the values are accessed using #{array[n]} where n is the JavaScript variable containing the index value. If it's Map, Properties or Java Bean then the values are accessed using #{empNo}, #{appTitle} where empNo and appTitle are the keys of the Map or Properties object or the property name of the Java Bean. There are some utility methods available in vroom.js file which shall be discussed later in this article. If you use method="getProperties", the framework will automatically extract the properties of bean-class of the enclosing element and convert it to JSON string. E.g. if there is a bean called EmpBean and it has a property called empNo and empName, by setting the method="getProperties", these properties will become available in call elements as #{empNo} and #{empName}. You can also set method="getEmpNo" and access the value of the property as #{value} in the call elements.
call
  • CDATA
  • type
  • id
  • name
  • tag
  • attribute
  • value
This tag is used to instruct the framework what to do in response of the event call. Type type attribute has two possible values: "update" or "script".

If the type is set to "update" then either id, name, or tag attribute must be specified to locate the HTML object on the webpage. The attribute must specify what to update of the object, it can be innerHTML, className, url, src, title etc. based on the object specified. E.g. you may change the document's title by setting the name="document" and attribute="title" or you may change the src of an iframe using id="frm1" and attribute="src". You can specify the value either by setting the value attribute or providing CDATA element of this element.
If the type is set to "script", you need to provide on the value or the CDATA. In most cases CDATA is provide since the script code can span more than 1 lines. This type of call is normally used to invoke other events, populate select elements or prompting the user using a JavaScript dialog. The use is not restricted, you can write a complete JavaScript program to be called. The JSON string returned by the method called can be converted in to JSON object using:

var jobj = JSON.parse('#{array}');
for(var i = 0; i < jobj.length; i++) {
    alert(jobj[i]);
}

Following server variables are always available whether the event is bound with a Java method or not.

  • #{contextPath} - The is replaced with the application's context path
  • #{sessionId} - This is replaced with session id
  • #{locale} - This is the user's browser's locale. You can convert it to JSON object using JSON.parse('#{locale}') to identify the language and country attributes or you can directly use #{locale.language} to access the value.

All returned JSON strings and server variables are also available in call type "update". So following is correct:

<p> The user session ID is #{sessionId} and browser language is #{locale.language}. </p>

[edit] Sample vroom-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<vroom-config xmlns="http://www.openkoncept.net/schema/vroom-config-2.1.xsd"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://www.openkoncept.net/schema/vroom-config-2.1.xsd vroom-config-2.1.xsd">
    <webpage uri="/|(/|[a-z]|[A-Z]|[0-9]|-|_)*.jsp">
        <stylesheet type="text/css" url="/yui/fonts/fonts-min.css"/>
        <stylesheet type="text/css" url="/yui/container/assets/skins/sam/container.css"/>
        <stylesheet type="text/css">
            #container {height:15em;}
            body {
                margin: 0;
                padding: 0;
            }
        </stylesheet>
        <script type="text/javascript" url="/yui/yahoo-dom-event/yahoo-dom-event.js"/>
        <script type="text/javascript" url="/yui/dragdrop/dragdrop-min.js"/>
        <script type="text/javascript" url="/yui/container/container-min.js"/>
        <event type="onload">
            <call type="update" tag="body" attribute="className" value="yui-skin-sam"/>
        </event>
    </webpage>
    <webpage uri="/admin/gid/CompanySearch.jsp" bean-class="com.myco.bean.CompanySearchBean" var="csb" scope="request">
        <stylesheet type="text/css" url="/yui/autocomplete/assets/autocomplete-core.css"/>
        <stylesheet type="text/css" url="/yui/autocomplete/assets/skins/sam/autocomplete.css"/>
        <stylesheet type="text/css" url="/yui/autocomplete/assets/skins/sam/autocomplete-skin.css"/>
        <script type="text/javascript" url="/yui/autocomplete/autocomplete.js"/>
        <event type="onload" method="getProperties">
            <call type="script">
            <![CDATA[
                var jso = JSON.parse('#{companies.array}');
                var array = new Array();
                for(var i = 0; i < jso.length; i++) {
                    array.push(jso[i].label);
                }
                var myDataSource=new YAHOO.widget.DS_JSArray(array);
                var myAutoComp = new YAHOO.widget.AutoComplete ("myInput", "myContainer", myDataSource);
            ]]>
            </call>
        </event>
    </webpage>
</vroom-config>

[edit] Integration with Struts, JSF and YUI

The framework quite flexible when it's the matter of integration with other Model-2 or MVC frameworks.

[edit] YUI

Integration with YUI is fairly simple since YUI heavily depends upon the HTML ids and Vroom Framework also uses HTML ids or names to locate HTML elements. The framework can help you to develop YUI based applications by:

  1. Providing you better control to manage and deploy YUI scripts and stylesheets and setup skins to one or more webpages by just defining the webpage element in the configuration file. So you don't need to populate your webpages with YUI head script and link tags.
  2. Eliminating the need to write Servlets to serve the AJAX calls.
  3. Easy integration with Server Side Java methods to access Data to build Data Sources for Data Tables and Auto Complete Widgets.

[edit] Struts

To integrate with Struts application, you need to do the following:

  1. Add filter-mapping to handle *.do requests in the web.xml as follows:

    <filter>
        <filter-name>VroomFilter</filter-name>
        <filter-class>net.openkoncept.vroom.VroomFilter</filter-class>
        <init-param>
            <param-name>config-file</param-name>
            <param-value>/WEB-INF/vroom-config.xml</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>VroomFilter</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>VroomFilter</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>

  2. In the vroom-config.xml, for webpage uri, you need change the regular expression to include .do URIs. and specifying the appropriate form-bean to the bean-class attribute. The var attribute must be the one used by Struts framework in struts-config.xml file. For example:

    <webpage uri="/login.(jsp|do)" bean-class="com.myco.struts.form.LoginForm" var="loginForm" scope="request">
    <!-- Other definitions -->
    </webpage>

  3. If you want to use the Vroom Framework navigation machanism, which is typically not required for Struts framework since all navigation is handled by action-mapping, you can define bean-class for form element to use the corresponding Struts Action. However, Vroom Framework can not invoke Struts execute methods, so you need to write a different method as per allowed method signatures.

Struts applications get take advantage of Vroom Framework to deploy scripts, stylesheets, meta tags and implementing various AJAX related features.

[edit] JSF

To integrate with JSF application, you need to do the following:

  1. Add filter-mapping to handle *.faces requests in the web.xml as follows:

    <filter>
        <filter-name>VroomFilter</filter-name>
        <filter-class>net.openkoncept.vroom.VroomFilter</filter-class>
        <init-param>
            <param-name>config-file</param-name>
            <param-value>/WEB-INF/vroom-config.xml</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>VroomFilter</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>VroomFilter</filter-name>
        <url-pattern>*.faces</url-pattern>
    </filter-mapping>

  2. In the vroom-config.xml, for webpage uri, you need change the regular expression to include .faces URIs. and specifying the appropriate backing-bean to the bean-class attribute. The var attribute must be the one used by JSF framework in faces-config.xml file. For example:

    <webpage uri="/login.(jsp|faces)" bean-class="com.myco.faces.bean.LoginForm" var="loginForm" scope="session">
    <!-- Other definitions -->
    </webpage>

It's not advisable to use Vroom Framework navigation mechanism with JSF applications, since JSF applications follow a JSF Life Cycle. Using the framework with JSF is not so straight forward and depends on the JSF implementation you're using. You can use Mozilla Firefox's plugin called Firebug to identify the HTML ids of your controls, which you want to bind. E.g. for Visual JSF implementation by NetBeans, if a Text Field is placed on a Visual Web JSF Page the HTML ID would be something like form1:textField1_field once the page rendering is complete. This is due to the DOJO components used in Woodstock Theme which generates the components at runtime using JavaScript.

[edit] Some Useful JavaScript functions

Following are the list of JavaScript functions which can be used with vroom-config.xml file, while writing script type calls:

  • VroomUtils.triggerEvent(elemId, event); // This method can be used to trigger events of an element. E.g. VroomUtils.triggerEvent('btnSubmit', 'onclick');
  • VroomUtils.populateSelect(elemId, jsonString); // This method is used to populated Select from JSON string, the JSON string must be array of net.openkoncept.vroom.bean.LabelValueBean object.
  • VroomUtils.populateSelect(elemId, jsonString, labelVar, valueVar); // The method is similar to the above method except jsonString can be array of any Java Bean, the labelVar and valueVar are the java * bean properties.
  • VroomUtils.generateRadioGroup(elemId, name, jsonString, cols, styleClass); // This method is used to generate a radio group. The cols is used to specify the no. of radio buttons in one line. The styleClass is CSS class to decorate the radio buttons. The jsonString must be array of net.openkoncept.vroom.bean.LabelValueBean.
  • VroomUtils.generateRadioGroupEx(elemId, name, jsonString, labelVar, valueVar, cols, styleClass); // This method is similar to the above method except jsonString can be array of any Java Bean, the labelVar and valueVar are the java bean properties.
  • VroomUtils.generateCheckBoxGroup(elemId, name, jsonString, cols, styleClass); // This method is used to generate check box group. The cols is used to specify the no. of radio buttons in one line. The styleClass is CSS class to decorate the radio buttons. The jsonString must be array of net.openkoncept.vroom.bean.LabelValueBean.
  • VroomUtils.generateCheckBoxGroupEx(elemId, name, jsonString, labelVar, valueVar, cols, styleClass); // This method is similar to the above method except jsonString can be array of any Java Bean, the labelVar and valueVar are the java bean properties.
  • VroomUtils.getElement(elemIdOrName); // This method finds the element by name. If the element is not found, it finds it by id.
  • VroomUtils.getElementByTagName(tagName); // This method is used to return on the first element of the array of elements of the specified tag name.
  • VroomUtils.getElementsByTagName(tagName); // This method returns array of elements of specified tag name.
  • JSON.parse(jsonString); // This method takes a jsonString and returns the JSON object.

[edit] Supported Event Types

Most commonly used event types are:

  • onload, onunload (this is used at webpage, document or window level)
  • onclick (normally used for images and buttons)
  • onkeypress, onfocus, onblur (typically used for validation)
  • onchange (this is used when a change in select control may affect other select controls, e.g. onchange of select control containing country names may require a refresh the select control of cities)

Below is the complete list of supported events. Elements prefixed with ms- are Microsoft Browser specific where as prefixed with xul- are XUL events:

  • onclick
  • ondblclick
  • onmousedown
  • onmouseup
  • onmouseover
  • onmousemove
  • onmouseout
  • onkeypress
  • onkeydown
  • onkeyup
  • onload
  • onunload
  • onabort
  • onerror
  • onresize
  • onscroll
  • onselect
  • onchange
  • onsubmit
  • onreset
  • onfocus
  • onblur
  • ondomfocusin
  • ondomfocusout
  • ondomactivate
  • onsubtreemodified
  • onnodeinserted
  • onnoderemoved
  • ondomnoderemovedfromdocument
  • ondomnodeinsertedintodocument
  • onattrmodified
  • oncharacterdatamodified
  • ms-oncut
  • ms-oncopy
  • ms-onpaste
  • ms-onbeforecut
  • ms-onbeforecopy
  • ms-onbeforepaste
  • ms-onafterupdate
  • ms-onbeforeupdate
  • ms-oncellchange
  • ms-ondataavailable
  • ms-ondatasetchanged
  • ms-ondatasetcomplete
  • ms-onerrorupdate
  • ms-onrowenter
  • ms-onrowexit
  • ms-onrowsdeleted
  • ms-onrowinserted
  • ms-oncontextmenu
  • ms-ondrag
  • ms-ondragstart
  • ms-ondragenter
  • ms-ondragover
  • ms-ondragleave
  • ms-ondragend
  • ms-ondrop
  • ms-onselectstart
  • ms-onhelp
  • ms-onbeforeunload
  • ms-onstop
  • ms-onbeforeeditfocus
  • ms-onstart
  • ms-onfinish
  • ms-onbounce
  • ms-onbeforeprint
  • ms-onafterprint
  • ms-onpropertychange
  • ms-onfilterchange
  • ms-onreadystatechange
  • ms-onlosecapture
  • xul-DOMMouseScroll
  • xul-ondragdrop
  • xul-ondragenter
  • xul-ondragexit
  • xul-ondraggesture
  • xul-ondragover
  • xul-CheckboxStateChange
  • xul-RadioStateChange
  • xul-onclose
  • xul-oncommand
  • xul-oninput
  • xul-DOMMenuItemActive
  • xul-DOMMenuItemInactive
  • xul-oncontextmenu
  • xul-onoverflow
  • xul-onoverflowchanged
  • xul-onunderflow
  • xul-onpopuphidden
  • xul-onpopuphiding
  • xul-onpopupshowing
  • xul-onpopupshown
  • xul-onbroadcast
  • xul-oncommandupdate

[edit] External links

Personal tools
Namespaces
Variants
Actions
Navigation
Interaction
Toolbox
Print/export