External Box Basics
In this chapter we create a simple external component, which displays the current time. There is no user input.
The goal is to familiarize with the steps needed to create any kind of external component.
Setting the development environment up
The following libraries are needed:
- Internal—supplied by PROS:
- externalComponentsFramework.jar
- External—third parties libraries:
- struts.jar—Struts web GUI framework
- javax.servlet.jar—servlet API, used by Struts
- jboss-aop-jdk50-client.jar—AOP facilities
Creating the Controller
The purpose of this class is to supply a method in which the current time will be taken from the system time. Then this time will be formatted and set as a tile attribute to be displayed in the JSP.
We start by subclassing the ExternalSelectorAbs class:
package com.cameleon.demo;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.tiles.ComponentContext;
import com.cameleon.configuratorui.external.ExternalControllerAbs;
publicclass TimeController extends ExternalControllerAbs {
protectedvoid process(ComponentContext tileContext,
HttpServletRequest request, HttpServletResponse response,
ServletContext servletContext) {
// TODO Auto-generated method stub
}
}
All our logic will be placed in the process method. In our case the code is no more than a few lines – enough to take the current time and format it into a readable string:
// Get the current time and date
long time = System.currentTimeMillis();
Date date = new Date(time);
// Format the time and date
DateFormat dtFormat = DateFormat.getInstance();
String formattedDate = dtFormat.format(date);
// Put the string value in the tile context
tileContext.putAttribute("dateTime", formattedDate);
The string “dateTime” on the last line is the identifier of the tile context attribute. The formatted date string can be later retrieved by the JSP by using this identifier.
Creating the View
HOW TO DESIGN THE JSP?
You can now prepare the presentation of the tile – a JSP file is created under the project folder pages/jsp. The easiest way is to start by copying the JSP sample supplied with the external components framework under the name extComponentSample.jsp.
You can duplicate this file and rename it to match our component purpose (‘timer.jsp’ in our example).
The code of timer.jsp is:
<%-----------------------------------------------------------------------------
- Date: 07/05/2007
- Copyright Notice: eConfigurator
- Description: External Selector Sample
%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/tags/struts-tiles" prefix="tiles"%>
<%@ taglib uri="/tags/struts-logic" prefix="logic"%>
<%@ taglib uri="/tags/struts-bean" prefix="bean"%>
<%-- Error handling --%>
<%@ include file="/WEB-INF/tiles/handleError.inc"%>
<%-- Error handling --%>
<tiles:importAttribute name="exception" ignore="true"/>
<%-- Display any content only if there is no exception raised from Controller class --%>
<logic:empty name="exception">
<%-- External component JSP code goes here --%>
</logic:empty>
Exception managing mechanism
The process method in the controller is wrapped in a try/catch block inside
the ExternalControllerAbs base class. If an exception occurs, it is put as an attribute (named ‘exception’) in the tile context and the corresponding JSP is processed.
The JSP contains 2 sections allowing to return:
- Either the external component code.
- Or the code of an error page.
In our case the code inside the JSP is a simple display of the attribute (type String) saved by the controller in the tile context.
It must be placed inside the ‘logic:notEmpty’ tag by using the ‘bean:write’ tag once the tile context has been imported into the page context.
<tiles:useAttribute name="dateTime"/>
<bean:write name="dateTime"/>
HOW TO ASSEMBLE THE TILE?
In order for the Struts Tiles framework to recognize the controller and JSP as a tile, some configuration is needed. This assembling is done in a configuration file called tiles-defs.xml
The following tiles-defs.xml is created under pages/cfg directory in the project:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<tiles-definitions>
<definition
name=".timer"
path="/externalComponents/timer/jsp/timer.jsp"
controllerClass="com.cameleon.demo.TimeController"
/>
</tiles-definitions>
Definition's path attribute
It corresponds to the context dependent path (starting from the root directory of the web application) to the JSP page of the tile.
Since the external components are deployed in the externalComponents folder in the ConfiguratorUI war, this is the starting point of the path. The next folder corresponds to the folder under which the current component is deployed, then the jsp folder under which our jsp is located.
controllerClass attribute
It corresponds to the full package-qualified name of the controller class of the tile.
Definition's name attribute
It corresponds to the identifier later used by in the Layout XML file to identify which tile has to be inserted in the rendered page.
HOW TO DESIGN THE CSS?
The Cascading Style Sheet associated to the tile is also part of the View layer. It is located under the pages/css folder in the project.
At runtime, the Configurator UI generates a <div> element in which the code generated by the JSP is inserted.
This <div> is associated to a main CSS Class whose name corresponds to the 'cssName’ attribute value of the element indicated in the Layout file.
<div class=”myClassName” …>
In our example, we choose ‘timer’ as CSS main class name.
.timer {
background-color: lightBlue;
border: 1px solid grey;
text-align: center;
width: 99%;
height: 100%;
}
Packaging and deploying the component
Our component is now ready to be deployed into the ConfiguratorUI application.
The classes, which are part of the external component, need to be compiled into a jar.
The pages directory of the project, which contains the css, jsp and configuration files, must be copied and gathered into the cameleonUI.war/ externalComponents/timer folder.
It means that all the external component JS functions will be available without any specific script declaration <script src=”myScriptLink”> tag.
It is important to minify the JS scripts used in external components to improve the performances.
Next time JBoss is started and the ConfiguratorUI is deployed, a special initialization servlet will be started.
The purpose of this servlet is to:
- find any deployed external components located under the war’s externalComponents directory
- merge their configuration files found under the cfg directory with the configuration files of the application.Warning: In order for the servlet to execute the merge, a property in the cameleon.properties file must be set.
The merge.properties file can be found in the file. The next property key/value pair must be present in order for the servlet to run:
# Common parameters
# disable the init method if equal true
externalComponents.transform.disable=false
When the first deployment is finished, this property can be set to “true” until the next time external component is deployed into the ConfiguratorUI application.
Running the new component
The external component is now ready to be displayed into the ConfiguratorUI application page. For the testing purpose the component will be positioned in the left part of the home page, just above the vertical selector:
<leftPart mode="on" cssName="leftPart" heightPercent="70" widthPercent="26"
autosize="off">
<externalBox mode="on" tile=".timer" cssName="timer" widthPercent="100"
heightPercent="15" autosize="off"/>
<!-- ... -->
</leftPart>
The “tile” attribute corresponds to the definition name that we gave to the component’s definition in the tiles-defs.xml.
The “cssName” attribute is used to specify the CSS main class that the ConfiguratorUI will generate for this tile. It’s recommended to give a unique name within the application.
Then you can write CSS for elements within this tile by always starting the CSS rule with the given CSS main class name (as it corresponds to the class associated to the parent container.)
The “cssName” attribute is also used to specify the location of the CSS file which is associated with the tile (in the “section layout” > “localizedLayout” > “componentStylesheet” of the Configurator UI model XML file).
<layout>
<localizedLayout lang="EN,FR">
<!-- ... -->
<componentStyleSheet>
<!-- ... -->
<css name="timer">externalComponents/timer/css/timer.css</css>
</componentStyleSheet>
</localizedLayout>
</layout>
The generated HTML code for the tile is the following one:
The JSP code that is simply printing the date is wrapped in a <div> with generated html id attribute and with the class name specified in the Layout file (cssName attribute).
Another <div> is wrapped around the first one for positioning purposes (width and height attributes coming from the Layout file).
The specified CSS file is added dynamically to the document head.
