Apache Tobago Tutorial


Tobago aids developers in creating web applications with a consistent look and feel. Therefore it provides the developer with a collection of comfortable high-level components, which can be positioned with a layout manager. The goal is to approximate the appearance of classical desktop applications. Tobago is based on a strict separation of structure and design. The developer describes the structure of a page and which controls it contains, the representation of the page and its style is handled by Tobago. The developer can customize the design and style through themes. Currently Tobago only contains themes for HTML clients. To achieve output independence, the views should be developed without any HTML, CSS, or JavaScript. A Tobago page normally contains only JSF and Tobago tags. Features, styling and design via HTML, CSS, or JavaScript are handled by the theme.

The development of Tobago started in 2002. With the introduction of the JSF standard it was decided to base Tobago on JSF. By 2005, Tobago was released as an open-source project and became a sub project of Apache MyFaces in 2006.

We will be referencing a simple address book application throughout this chapter to demonstrate the various features of Tobago.

Tobago is a constantly maturing project with rich potential to fill a unique niche in the MyFaces family — feel free to sign up on the MyFaces mailing lists[1] or sign up to the JIRA[2] and participate in the process. Additionally, you can also check out the MyFaces project website to find out about future releases.

The Tobago project contains several examples like the demo, the address book and the blank example. The demo example demonstrates many of the important features of Tobago and acts as the online documentation. The address book example is a small self-contained web application. Finally, there is the blank example, which is a minimal Tobago application that can act as a starting point for a new application. The Tobago download page links to the example archive, which contains a precompiled web application archive (WAR) for the blank example and the demo. The source for the blank example can be obtained from the Subversion repository. Checking out the blank example for Tobago is achieved by entering the following command in the shell:

svn checkout \
  http://svn.apache.org/repos/asf/myfaces/tobago/trunk/example/blank/ \
  blank

For building the blank example Java 5 and Maven 2 (at least 2.0.6) are needed. Running Tobago applications in a Java 1.4 environment is supported, too. The Tobago distribution contains bytecode transformed jars, which were generated with Retrotranslator.

A Tobago application is a standard web application and needs a web application descriptor (WEB-INF/web.xml). As a JSF application the web.xml file has to include a servlet definition for the FacesServlet and a corresponding servlet mapping. During development it is convenient to serve the resources for Tobago like images, scripts, and style sheets directly out of the theme jars. To accomplish this, the web.xml file needs to contain the definition for the Tobago ResourceServlet and the corresponding servlet mapping. For a production environment it is advised to extract the theme resources and let the servlet container or web server serve these resources directly — see the section called “Advanced Assembly”.

The JSF specific configuration for Tobago is contained in the faces-config.xml file inside the Tobago core jar. To make the configuration available for JSF the tobago-core.jar has to be placed into the web application. The Tobago specific configuration is defined in the WEB-INF/tobago-config.xml file. A minimal configuration should at least specify the default theme for the Tobago application.

<tobago-config>
  <theme-config>
    <default-theme>speyside</default-theme>
  </theme-config>
</tobago-config>

A Tobago web application needs to package many libraries. First of all, the Tobago core jar and theme jars should be made available in the application. Some themes depend on each other, for example to be able to use the Speyside theme the Scarborough theme and Standard theme have to be included as well. These dependencies are defined in the META-INF/tobago-theme.xml files inside the theme jars.

Tobago depends on several Jakarta Commons libraries:

  • commons-beanutils

  • commons-collections

  • commons-digester

  • commons-fileupload

  • commons-io

  • commons-lang

  • commons-logging

Additionally a JSF implementation has to be selected. For MyFaces the following additional libraries have to be included:

  • myfaces-api

  • myfaces-impl

  • commons-codec

  • commons-el

  • jstl

Finally, a logging mechanism has to be selected. All Tobago examples use log4j as a default.

The Tobago project leverages Maven for all build management and Maven is the easiest way to build a web application with Tobago. The project descriptor (pom.xml) or project object model (POM) of Tobago defines all necessary dependencies and the Maven repository server and its mirrors provide the appropriate jars. For more information on Maven see the Maven web site[3] and the book Better builds with Maven[4].

The POM for the blank example specifies the packaging of the project as "war". The dependencies for the web application are managed by the <dependencies> element in the POM Maven automatically takes care of the dependencies through its transitivity mechanism. The POM comprises all necessary information needed to compile and package a web application archive. Use the following command in the shell:

mvn package

This results in a WAR archive in the target directory, where Maven stores its build artifacts and intermediary files. Moreover Maven can be used to deploy the WAR on an application server as well. The Tobago example POM, which is the parent POM of the blank example, contains the necessary information to deploy a WAR on an embedded Jetty server. By executing

mvn jetty:run-exploded

a Jetty server is started via Maven and the WAR is deployed on this servlet container. The server listens on the port 8080 and the web application can accessed under the URL http://localhost:8080/tobago-example-blank/.

Tobago makes use of the extensibility of JSF to achieve its decoupling from the rendering tier. It provides its own tag library, components and render kit. Besides the JSP tag library, an alternative rendering technology called Facelets can be used, too. The extension folder in the Tobago repository contains the support library to use Facelets instead of JSP.

Because of the strict separation between structure and design, it is possible to use an application with different themes. This allows the developer to execute applications that can render different corporate designs for different portals while keeping the view source unchanged. This mechanism is easier than adapting plain CSS in the sense that various stylesheet themes/skins have to be referenced and loaded based on environmental parameters.

Besides the basic input controls HTML provides, Tobago offers additional high level controls, which a traditional desktop application developers would recognize. These controls will be described in the following sections.

Tobago also contains a deprecated tree control. The API of this tree control does not really fit to the other controls. But the sandbox already contains a version of the future tree control, which will be introduced in Tobago 1.1.

HTML offers a large set of input controls which form the basis of Tobago's controls. This base includes single line text input fields, text areas, labels, radio buttons, check boxes, links, buttons, and so on. The Tobago demo shows these controls in action. A precompiled WAR for the demo is part of the example distribution and the Tobago web site links to a server with a live version. See Figure 1, “Basic controls”:


A single line input control can be rendered with the <tc:in> tag. The extended version can be accessed with <tx:in>. In general the extension library, which is usually referenced by the tx prefix, provides convenience variants of controls. For the <tc:in> control the extended version <tx:in> contains boilerplate code for rendering labels. For form like input views nearly every input control has a corresponding label. The label is connected to the input control. If the label is clicked the input control gains focus.

<tx:in
    label="#{bundle.name}"
    value="#{address.name}"
    required="false" readonly="false"
    disabled="false" rendered="true" />

The label attribute determines the textual description for the control. It is laid out with a grid layout manager. The theme specifies the default label width, but it can be overwritten with the labelWidth attribute. If the label contains an underscore character the following character will become an access key. This is visualized by underlining the access key character. If the access key is pressed together with the Alt key the corresponding input field gains focus. The value attribute contains the content of the input control. The required attribute controls validation and allows the theme to render a special marker for required input. The required feature is rendered as a small box with a check mark inside the input field to inform the user to enter information into this field. Read-only controls do not allow the user to modify the value of the input control. A disabled control cannot gain focus, the label is rendered in a fashion to highlight the disabled nature of the input control and the user cannot copy content from the input control. The rendered attribute manages if the control is rendered at all. If the control is not rendered the layout manager can distribute the resulting space to other controls. For password fields the respective attribute can be set to true. If a page contains multiple input controls the first control will be focused by default. This behavior can be overwritten by setting the focus attribute of an input control to true.


Tobago supports different ways to use commands. The basic versions are <tc:button> and <tc:link>; others include toolbars and menus, which are described in later sections.

<tc:button label="Delete" action="#{controller.delete}"
    image="image/delete.png" defaultCommand="false">
  <f:facet name="confirmation">
    <tc:out value="Do you want to delete it?" />
  </f:facet>
</tc:button>

The label attribute defines the text on the button. The action attribute points to a method which is executed if the button is pressed. By means of the image attribute the button can be decorated with an icon. The image can be placed relatively to the root of the web application or the resource manager can be used to locate the image — see the section called “Resource Management”. The <tc:button> control supports the confirmation facet, which generates a message dialog. Only if the confirmation question is answered with OK, the action is executed. If the defaultCommand attribute is set to true the button will be activated as soon as the Enter key is pressed.

Tobago includes a double request prevention mechanism. After a button or link is clicked in the client, the page is blocked to avoid duplicate clicks. If the server request takes longer than expected a transitioning effect is shown. First the page is faded out and later a progress animation is presented. To turn this effect off the transition attribute can be set to false.

A generic <tc:command> control can be used for event facets for select controls like <tc:selectBooleanCheckbox>, <tc:selectOneRadio>, <tc:selectManyCheckbox>, and <tc:selectOneChoice>. This is how the theme changing in the footer of the address book example is realized. If a new theme is selected, a change event is triggered, the page is submitted, and the action of the <tc:command> inside the change facet is called:

<tx:selectOneChoice label="#{bundle.footerTheme}" value="#{controller.theme}">
  <f:selectItems value="#{controller.themeItems}" />
  <f:facet name="change">
    <tc:command action="#{controller.themeChanged}"/>
  </f:facet>
</tx:selectOneChoice>

Besides the change event select controls also support the click event. The click event is triggered if someone clicks on the control. The actual value does not need to change to trigger the event.

The <tc:sheet> component allows to display tabular data. The address book uses it to provide an overview of all stored addresses.

<tc:sheet columns="1*;1*;1*" value="#{controller.currentAddressList}"
    var="address" state="#{controller.selectedAddresses}"
    sortActionListener="#{controller.sheetSorter}" rows="25"
    showRowRange="left" showPageRange="right" showDirectLinks="center">
  <tc:column id="firstName" label="#{bundle.listFirstName}" sortable="true"
      rendered="#{controller.renderFirstName}">
    <tc:out value="#{address.firstName}" />
  </tc:column>
  <tc:column id="lastName" label="#{bundle.listLastName}" sortable="true"
      rendered="#{controller.renderLastName}">
    <tc:out value="#{address.lastName}" />
  </tc:column>
  <tc:column id="dayOfBirth" label="Birthday" sortable="true"
      rendered="#{controller.renderDayOfBirth}">
    <tc:out value="#{address.dayOfBirth}">
      <f:convertDateTime pattern="#{bundle.editorDatePattern}" />
    </tc:out>
  </tc:column>
</tc:sheet>

The value attribute links to a list model in the controller providing the data for the sheet. The <tc:sheet> contains three <tc:column> tags which describe the columns of the sheet. The label of the column is rendered as a header cell. The var attribute inside <tc:sheet> defines a local variable address, which refers to a row in the data model and can be used in the definition of the columns.


In the example, each column uses a <tc:out> tag to render the data for the sheet cell by accessing the appropriate property of the row object. Instead of <tc:out> arbitrary input controls can be used like <tc:in>, <tc:selectBooleanCheckbox>, or <tc:selectOneChoice>.

The various attributes of the sheet which start with 'show' configure the navigational elements of the sheet — showDirectLinks for example allows the user to directly jump to the desired page of the sheet.

The state attribute refers to a SheetState object. Tobago binds information about the state of the sheet to this object — like which rows are selected. This allows the developer to react on the selection inside the business logic. In the address book example there is a toolbar above the sheet. The toolbar contains a delete action among others. This delete action is dependent on the selected rows in the sheet. The attribute selectable of the sheet controls the selection mode for the sheet. Possible values are none, single, and multi. The default value is multi and allows multiple rows to be selected. The following code fragment show the method bound to the delete button and describes how to access the selected rows:

public String deleteAddresses() throws AddressDaoException {
  List<Integer> selection = selectedAddresses.getSelectedRows();
  if (selection.size() < 1) {
    FacesMessage error 
        = new FacesMessage("Please select at least one address.");
    FacesContext.getCurrentInstance().addMessage(null, error);
    return null;
  }
  for (int i = selection.size() - 1; i >= 0; i--) {
    Address address = currentAddressList.get(selection.get(i));
    addressDao.removeAddress(address);
  }
  // ...
  return OUTCOME_LIST;
}

The sortable attribute of the <tc:column> activates sorting for the related column. If the data for the sheet is a List or an array the data can be sorted implicitly. The sortActionListener attribute allows implementation of sorting in the business logic. The respective method binding has to point to a public action listener method which takes an ActionEvent as a parameter and returns void. The method will receive a SortActionEvent, which denotes the column triggering the sort event. However, information about the sort direction is contained in the SheetState.

To mimic the appearance of a desktop application it is common to place a menu bar at the top of the page. This can be done with the <tc:menuBar> tag inside the menuBar facet of the <tc:page>. A menu bar can contain <tc:menu> tags, which can be nested to produce sub menus. Actions can be bound with method bindings to <tc:menuItem> tags. A menu item can be disabled and can encapsulate icons. An underscore in the label marks the following character as an access key, which can be activated together with the Alt key.

In the address book example the settings menu contains single selections created by <tx:menuRadio> to choose the current theme and language. Additionally it demonstrates how to use a check box menu item <tc:menuCheckbox> to change the mode of the application.

<tc:menuBar id="menuBar">
  <tc:menu label="_File">
    <tc:menuItem label="_New" action="#{controller.createAddress}" image
        ="image/org/tango-project/tango-icon-theme/16x16/actions/contact-new.png"/>
    <tc:menuItem label="_Add Dummy Addresses"
        action="#{controller.addDummyAddresses}"/>
    <tc:menuSeparator/>
    <tc:menuItem label="_Logout" image
        ="image/org/tango-project/tango-icon-theme/16x16/actions/system-log-out.png"/>
  </tc:menu>

  <tc:menu label="_Settings">
    ...
    <tc:menu label="_Theme">
      <tx:menuRadio action="#{controller.themeChanged}"
          value="#{controller.theme}">
        <f:selectItems value="#{controller.themeItems}"/>
      </tx:menuRadio>
    </tc:menu>
    <tc:menuCheckbox label="Simple _Mode" value="#{controller.simple}"/>
  </tc:menu>
  ...
</tc:menuBar>

The placement of components on a page is done with the help of a layout manager. The functionality of a layout manager is similar to those found in Swing. The standard layout manager for Tobago is <tc:gridLayout>. It can be bound to a container tag with a layout facet.

The grid layout manager divides the area of the page into a rectangular grid. This grid can be controlled with the rows and columns attributes of the <tc:gridLayout> tag. The syntax is similar to the multi-length notation known from HTML[5] and consists of a semicolon separated list of layout tokens.

A layout token may be an absolute length in pixels like 100px, a percentage length like 50%, a relative length like 2* or * as a shorthand for 1*, or the value fixed. Relative lengths are served by the layout manager from the remaining available space, which is distributed proportionally based on the number before the *.

If the layout manager has 400 pixels to lay out the columns with the following layout tokens 2*;*;100px, it first claims 100px for the third column and distributes the remaining 300 pixels in the ratio 2:1, ending up in 200 pixel for the first column and 100 pixels for the second column. The layout token fixed instructs the layout manager to take the required pixel size of the contained control. A <tx:in> control normally has a fixed height. To place multiple <tx:in> controls one below the other without superfluous spacing the layout manager can be instructed with fixed layout tokens to use exactly the required vertical space for a <tx:in>. For a more concrete example see the following code fragment based on the editor view of the address book:

<tc:panel>
  <f:facet name="layout">
    <tc:gridLayout columns="*" rows="fixed;fixed;fixed;*"/>
  </f:facet>
  <tf:in ... />
  <tf:in ... />
  <tf:in rendered="#{! controller.simple}" ... />
  <tf:textarea ... />
</tc:panel>

The grid consists of one column and four rows. The first three rows use a fixed height which is implied by the theme and contained controls. The fourth row takes the remaining vertical space.

One of the main reasons to use a layout manager is its ability to optimally manage the available space. The layout manager knows, for example, if controls have a fixed height and which can grow if there is enough space.

Since the layout manager is targeted specifically at JSF it can flexibly react on the rendered attribute of components. If the address book application is in simple mode some of the components are not rendered. The layout manager automatically distributes the newly available space to the remaining dynamic components, which are laid out with relative or percentage lengths.

If a control should utilize multiple adjacent grid cells, it can be wrapped with a <tc:cell> tag. With the spanX and spanY attributes of a <tc:cell> control the layout manager can be instructed to make the contained control span multiple cells in X and Y direction.


Tobago allows the developer to specify the structure of a page. Additionally, the look of a page is controlled by the selected theme. A theme defines the colors, dimensions, behavior, and graphics of controls. Tobago comes with a selection of themes. These are Scarborough, Speyside, Charlotteville, and Richmond — named after settlements on Tobago. Scarborough is the basic theme which tries to directly rely on the standard features of HTML. Speyside is the main theme, where most development focus is targeted at. You will want to use this theme to start a new web application with. The remaining themes Charlotteville and Richmond are mainly variations of Speyside.

Themes can be used to make an application follow the corporate design of a company or give the user the ability to change the look and feel of an application to their preferences. The address book example demonstrates how to make the theme selectable by the user. A select box displays the available themes, which are configured in the tobago-config.xml file, and a button triggers an action in the controller to set the theme in the Tobago ClientProperties object:

public String themeChanged() {
  FacesContext facesContext = FacesContext.getCurrentInstance();
  ClientProperties client 
      = ClientProperties.getInstance(facesContext);
  client.setTheme(theme);
  return null;
}

For Tobago, resources are images, style sheets, scripts, and string resources. These resources can be dependent on the locale, browser, or the theme. The resource manager collects all resource locations. When a resource is requested, the resource manager determines the inclusion order. A resource can be available in different themes and multiple locales. The resource manager first looks under the selected theme with the used browser and locale. If the resource is not found, the fallback locale is used to continue the search. After all fallback locales are examined the fallback for the browser is used and the locales are searched again. After all fallback browsers are searched the fallback for the theme is used and the search starts again with the locales until all fallback themes are processed. The result is cached for later reuse.

For resources such as images, the resource manager stops with the first match. For style sheets and scripts the resource manager returns a list of resources in the order they were found. This establishes a powerful defaulting mechanism.

By relying on the resource manager the developer can provide localized images with different text values for a button. The locale of the view is used to determine the correct language version of the image. The resource manager supports the XML format for property files, easing the use of special characters in string resources. The evaluation of the theme in inclusion order can be used to support different corporate wordings. If each client has its own theme string resources for the different themes can arrange the words in different ways — for example: email, e-mail, or eMail.

In the tobago-config.xml file, additional paths can be specified for inclusion by the resource manager. In this way you can add your own resources or even overwrite or extend existing resources. But changing existing themes this way may result in compatibility issues when switching to a newer version of Tobago, since the theme files are not stable yet and do not count as an official external API.

<tobago-config>
  <theme-config>
    <default-theme>speyside</default-theme>
  </theme-config>
  <resource-dir>tobago-resource</resource-dir>
</tobago-config>

The resource directory denotes a folder inside the WAR relative to the root. Paths for resources have to follow this pattern:

<content-type>/<theme>/<browser>/<directory>/<resource-name>(_<locale>)?.<extension>

Currently only html is supported as a content type, although the sandbox contains the beginnings for WML support. For the address book example there are two variants of an empty portrait with instructions how to upload a real portrait.

tobago-resource/html/standard/standard/image/empty-portrait.png
tobago-resource/html/standard/standard/image/empty-portrait_de.png

The first image is the default image with instructions in English. In the second image the instructions are localized in German. The first standard in the path denotes the fallback theme and the second standard represents the fallback browser. The directory part in the pattern stands for an arbitrary sub-path — in this example for the folder image.

Several controls like <tc:in>, <tc:panel>, or <tc:column> support the markup attribute. It allows the developer to apply logical styles to a control. Which markup values are supported is defined per theme in the theme-config.xml file. If a theme does not define supported markup for a renderer, it inherits the markup from the fallback theme. The Standard theme defines number for <tc:in> and <tc:out>, and strong and deleted for <tc:out>. The markup number is usually used to format numbers right aligned, strong is used to emphasize content, and deleted marks text as no longer available normally by crossing it out. The visual representation of markup is up to the theme and therefore it will fit to the overall look and feel of the theme.

To add new markup you can write your own theme. Choose the theme you want to extend and specify the selected theme as fallback theme. The Example theme extends Speyside and adds markup for columns.

<tobago-theme>
  <name>example</name>
  <deprecated-name>
    org.apache.myfaces.tobago.context.ExampleTheme
  </deprecated-name>
  <resource-path>org/apache/myfaces/tobago/renderkit</resource-path>
  <fallback>speyside</fallback>
  <renderers>
    <renderer>
      <name>Column</name>
      <supported-markup>
        <markup>new</markup>
      </supported-markup>
    </renderer>
  </renderers>
</tobago-theme>

To realize the visualization of the markup Tobago will add certain CSS style classes into the generated HTML for the marked control. The theme has to provide the styling information. The style class name results from the following naming rule "tobago-" + rendererName.toLower() + "-markup-" + markupName:

.tobago-column-markup-new {
  background-color: yellow;
}

For the Example theme it was decided to render a new column with a yellow background.

The address book example uses a different way to add markup. In this case three markup values — ok, warn, and error — are defined for the <tc:progress> control directly in the tobago-config.xml file. The administration area contains a progress bar to visualize the memory utilization of the virtual machine. Depending on the percentage value of the memory usage the business logic assigns different markup values for the progress bar to classify the state of the memory utilization.


The resource directory contains style sheets for visualizing the markup values as different background colors — green for ok, yellow for warn, and red for error. The Speyside theme for example is extended by the html/speyside/standard/style/style.css file.

The ideal place to start when you want to create your own Tobago control is the sandbox. To access the sandbox you have to check it out:

svn checkout \ 
    http://svn.apache.org/repos/asf/myfaces/tobago/trunk/sandbox \
    sandbox

Alternatively if you have checked out the complete Tobago source tree you can find the sandbox directory right under the root directory. In this section we will create an HTML control in the sandbox as an example. The new control will be a slider for entering integer numbers.

This control consists of a slider bar with an attached number input field. If you move the slider the number field is changed accordingly and vice versa. Figure 10, “Slider control for entering numbers” shows a preview of the control. You can find the complete code in the Tobago sandbox.


We are starting with the user interface component of the control and will name it: UIInputNumberSlider[6]. Like all JSF components, Tobago components must extend UIComponent[7]. Because we want to create an input component we can extend UIInput[8] which is a (non direct) subclass of UIComponent. The class UIInput is already an implementation of EditableValueHolder[9] which saves us a lot of work.

The JSF runtime environment needs the component type as an identifier for creating instances of components. Tobago components need to store this information in the component itself in the constant COMPONENT_TYPE. This constant is processed by the Tobago annotation visitor that is used in the build process to create the faces-config.xml file.

We also implement some additional properties into our component: min, max, readonly and disabled. The property min specifies the smallest and the property max the largest number that can be entered. With the property readonly set the user cannot modify the value of the slider. The same is true for the property disabled. But in this case the complete control appears deactivated. All properties should be value binding enabled which makes their getters a little bit more complicated. To ensure that our component state is saved between requests we have to override the state holder methods of UIInput.

The following code shows some parts of our component class:

public class UIInputNumberSlider extends javax.faces.component.UIInput {

  public static final String COMPONENT_TYPE
      = "org.apache.myfaces.tobago.InputNumberSlider";

  private Boolean readonly;
  private Boolean disabled;
  private Integer min;
  private Integer max;

  public Boolean isReadonly() {
    if (readonly != null) {
      return readonly;
    }
    ValueBinding vb = getValueBinding(TobagoConstants.ATTR_READONLY);
    if (vb == null) {
      return false;
    } else {
      return (Boolean.TRUE.equals(vb.getValue(getFacesContext())));
    }
  }

  public void setReadonly(Boolean readonly) {
    this.readonly = readonly;
  }
  ...
  public void restoreState(FacesContext context, Object state) {...}
  public Object saveState(FacesContext context) {...}
}

There are two ways in JSF to render a component. The first one is to implement the encoding and decoding between UI component and the view in the UI component directly. This is called the direct implementation programming model. The second method is to delegate the task to an appropriate renderer which is called the delegating programming model. The delegated programming model keeps your components independent from the view technology and is preferred for Tobago components.

A renderer in JSF must be a subclass of type Renderer[10]. For Tobago components this is different: their renderers must also implement the interface LayoutInformationProvider[11] to get the renderer to work with the Tobago layout management. With this interface Tobago renderers provide the layout manager with certain information about the sizing of the component that is rendered. The required methods have a default implementation in the class LayoutableRendererBase[12] which uses properties that are provided by the theme configuration of the used theme (tobago-theme-config.properties). We name our renderer InputNumberSliderRenderer and extend from LayoutableRendererBase. Following the Tobago naming convention the renderer must end with "Renderer".

When using the LayoutableRendererBase the theme configuration is a good place to provide the information needed for the layout. The implementation searches the configuration for properties with the following pattern: renderer name without "Renderer" + "." + key. All values are interpreted as pixels. Table 1, “Recognized keys for LayoutableRendererBase” specifies some of the recognized keys.


If LayoutableRendererBase does not find a value for a renderer it searches for default properties: "Tobago." + key. We could (but will not) specify a width padding of five pixels for our control by adding the property InputNumberSlider.paddingWidth=5 in the theme configuration of the sandbox theme. Please note that the resource location mechanism as described in the section called “Resource Management” is used to find a property.

The Tobago theme configuration is not only used by RendererBase, but properties of own renderers can be specified there. For example we define the percentage of the width of the slider of our control in the tobago-theme-config.xml: InputNumberSlider.sliderWidthPercent=66. This means the slider gets 66 percent of the width of our control and the input field 34 percent. The value can be accessed in the renderer with the following line of code:

int sliderWidthPercent
    = ThemeConfig.getValue(facesContext, component, "sliderWidthPercent");

The Tobago theming mechanism locates renderers by their location in the package structure. Normally all Tobago renderers are located under the root package org.apache.myfaces.tobago.renderkit. Below this, the location depends on the output technology, the theme and browser.

We use the sub package html.sandbox.standard.tag because we are writing an HTML control for the sandbox theme. Package standard means that all browsers (Mozilla, Internet Explorer etc.) will be served by this renderer. The last package tag is obligatory for historical reasons.

The code for encoding/decoding in the renderer is quite long so only some interesting fragments are shown in code snippet. All encoding is done in the method encodeEnd. First the properties of the component are retrieved. Then the response writer is used to generate the HTML input field of our control. The response writer for Tobago components is the TobagoResponseWriter[13] which is created by the Tobago render kit. It provides the component developer with additional convenience methods and handles escaping. The decoding is done in the method decode and retrieves the value of the input field back from the HTTP request.

Example 1. Renderer for the slider bar control

package org.apache.myfaces.tobago.renderkit.html.sandbox.standard.tag;

public class InputNumberSliderRenderer extends LayoutableRendererBase {

  public void encodeEnd(FacesContext facesContext, UIComponent component)
      throws IOException {
    String currentValue = getCurrentValue(facesContext, component);
    boolean readonly
        = ComponentUtil.getBooleanAttribute(component, ATTR_READONLY);
    boolean disabled
        = ComponentUtil.getBooleanAttribute(component, ATTR_DISABLED);
    TobagoResponseWriter writer
        = HtmlRendererUtil.getTobagoResponseWriter(facesContext);
    ...
    writer.startElement(HtmlConstants.INPUT);
    String inputIdAndName = getIdForInputField(facesContext, component);
    writer.writeNameAttribute(inputIdAndName);
    writer.writeIdAttribute(inputIdAndName);
    if (currentValue != null) {
      writer.writeAttribute(HtmlAttributes.VALUE, currentValue, false);
    }
    writer.writeAttribute(HtmlAttributes.READONLY, readonly);
    writer.writeAttribute(HtmlAttributes.DISABLED, disabled);
    writer.endElement(HtmlConstants.INPUT);
    ...
  }

  public void decode(FacesContext context, UIComponent component) {
    UIInput uiInput = (UIInput) component;
    ...
    String inputId = getIdForInputField(context, component);
    Map requestParameterMap
        = context.getExternalContext().getRequestParameterMap();
    if (requestParameterMap.containsKey(inputId)) {
      String newValue = (String) requestParameterMap.get(inputId);
      uiInput.setSubmittedValue(newValue);
    }
  }

  private String getIdForInputField(
        FacesContext context, UIComponent component) {...}
}

When the HTML output in the renderer is generated the question how to size the elements arises. It is not a good idea to hard code static width or height information because the layout manager determines how much space the control should occupy. But how can a renderer know how much space it should use?

Tobago creates a "style map" for each component and adds it to the components attributes. This style map contains values for the width and the height of the control determined by the layout manager. In the renderer this map can be accessed and the values can be taken into account when creating HTML elements. The following source snippet demonstrates the usage of the style map.

HtmlStyleMap style = (HtmlStyleMap) component.getAttributes().get("style");
int width = style.getInt("width");

All JSF implementations must support JSP as page description language for JSF pages. This is also standard for writing Tobago pages. A different view technology that does not depend on JSP is also available — Facelets. To allow an author to use our control we need to define a JSP tag — a custom action. This is done by writing one class and one interface: the tag class itself and a tag declaration interface which is Tobago specific.

We start with the tag class. All JSP custom actions in JSF that correspond to a UI component in the component tree must either subclass UIComponentTag[14] or UIComponentBodyTag[15] depending on whether they need support for body content functionality or not. Our action has no body content so we want to subclass UIComponentTag. Again there is an opportunity to save some effort if we extend from TobagoTag[16] which extends from UIComponentTag. This class already implements the handling for the properties readonly and disabled.

Our tag is named InputNumberSliderTag[17] and consists of four new properties (min, max, value and valueChangeListener) with their getter/setters, an implementation of getComponentType, a release method and a setProperties method.

Tag classes in Tobago are dumb gateways between the view technology (JSP) and the render independent UI component. No output should be generated in the JSP tag directly. This is done only in appropriate renderers. The advantage with this approach is that we can use a different view technology like Facelets without changing our code.

Next thing is the declaration of the tag. Therefore it implements an interface InputNumberSliderTagDeclaration[18]. This interface describes our tag and its attributes with annotations. Tobago's build process uses this declaration to generate a faces-config.xml and a tag library description (TLD) for our component with the help of the annotation processing tool (apt). The interface is annotated with a @Tag annotation with a name attribute. The specified value "numberSlider" is the name of the JSP tag. The next annotation @UIComponentTag makes it clear that the tag belongs to a component with an associated renderer. The attributes rendererType and uiComponent specify the type of the renderer and the class of the UI component. Please note that the Tobago render kit will add the suffix "Renderer" to the renderer type to find a matching renderer class.

After the interface, the properties that are defined for the tag are annotated. By convention, the setter of the property is used. The @TagAttribute annotation describes a property that is part of the JSP tag. The @UIComponentTagAttribute annotation specifies a component property. Our properties appear in both the tag and the component. With the additional annotation attribute type we define the type of the properties.

Tobago has many predefined tag attribute declarations. We make use of them by extending the needed interfaces like IsReadonly or HasValue:


To enable security for a Tobago application you can either write your own login mechanism or use the standard way provided by the servlet specification. The later way has a small drawback because the name attribute for an HTML input control normally cannot be controlled via JSF or Tobago. For form based authentication the servlet specification requires the input fields of a login dialog to have the names j_username and j_password, respectively. Since we cannot influence the names of <tc:in> controls directly we have to resort to a hack. We subsequently change the rendered field names with JavaScript inside the browser.

<tx:in id="j_username" label="Username"/>
<tx:in id="j_password" password="true" label="Password"/>

...

<tc:script onload="initLoginForm();">
  function initLoginForm() {
    var user = document.getElementById("page:j_username");
    user.name = "j_username";
    var pass = document.getElementById("page:j_password");
    pass.name = "j_password";
    var form = document.getElementById("page::form");
    form.action 
        = "${pageContext.request.contextPath}/j_security_check";
  }
</tc:script>

The onload attribute instructs Tobago to execute the passed JavaScript function after the HTML page was loaded.

Tobago provides an extension package tobago-security to secure method bindings with annotations. Currently it is not sufficient to include the jar in the classpath, since the order in which the faces-config.xml files from libraries in the classpath are evaluated is depending on the JSF implementation. The faces-config.xml file of tobago-security defines alternatives for command components with security handling. The easiest way is to copy the component redefinitions into the faces-config.xml file of the web application.

With the tobago-security package a method can be marked with @RolesAllowed to designate the necessary roles for a business functionality. The method binding will only be evaluated if the user has the appropriate role. Likewise the class can be marked with @RolesAllowed to secure all methods. In the address book example the Admin toolbar button points to a method in the AdminController. This method is annotated with the required role admin:

@RolesAllowed("admin")
public String admin() {
  return OUTCOME_ADMIN;
}

If the user of the application has not the role admin the button is disabled and the method binding will not be evaluated. Additionally the annotations @DenyAll and @PermitAll are supported. These security annotations are part of the Common Annotations specification (JSR250.)

The <tc:page> tag acts as a global form. Therefore, for simple pages without control dependencies no explicit form has to be used. The <tc:form> control allows nesting of forms and creates dependencies between controls.

If a form is submitted only the contained model references are updated, other values are temporarily stored. With <tc:form> partial validation can be realized, because validation is limited to controls inside a <tc:form>. As a result sub forms provide an alternative to immediate for input controls. In the address book example changes to the theme and the language are isolated to sub forms to avoid conflicts with validations elsewhere on the page:

<tc:form>
  <tx:selectOneChoice label="Theme" value="#{controller.theme}">
  <f:selectItems value="#{controller.themeItems}" />
    <f:facet name="change">
      <tc:command action="#{controller.themeChanged}"/>
    </f:facet>
  </tx:selectOneChoice>
</tc:form>

To avoid the reloading of complete pages, Tobago has a renderedPartially attribute to update only parts of the page. For <tc:tabGroup> controls this can be achieved by configuring the switching type to reloadTab. Tobago also supports a more generic way to update container controls like <tc:panel>, <tc:box>, <tc:popup>, or <tc:sheet> using <tc:attribute> with the name renderedPartially and a value with a comma separated list of identifier paths of the respective containers. An identifier path is a colon separated list of ids of nested naming containers. An absolute path of ids has to begin with a colon character followed by the id of the <tc:page> control. If the path does not start with a colon it is a relative path from the current naming container. By using multiple colon characters at the beginning of the path parent naming containers can be accessed. The action of the command has to return null as an outcome, because the current view has to be used again. Only a sub-tree of the view is updated.

The following code fragment shows a simple example where an input control is enabled depending on the state of a checkbox.

<tc:page id="page">
  <tc:box label="Container" id="box">
    <tx:selectBooleanCheckbox label="Enable" 
        value="#{controller.miscEnabled}">
      <f:facet name="change">
        <tc:command>
          <tc:attribute name="renderedPartially" value=":page:box"/>
        </tc:command>
      </f:facet>
    </tx:selectBooleanCheckbox>

    <tx:in label="Misc." disabled="#{!controller.miscEnabled}"/>
  </tc:box
</tc:page>

Instead of reloading the whole page, only the surrounding container <tc:box> of the <tx:in> control is updated, if the value of the checkbox changes. The absolute id path of the box, which should be updated, is set as renderedPartially attribute of the command.

Additionally, <tc:panel> controls can be reloaded on a regular basis to be able to display changes over time. To accomplish this, the panel has to be provided with a reload facet. This facet has to contain a <tc:reload> tag to specify the frequency for the reload in milliseconds.

<tc:panel>
  <f:facet name="reload">
    <tc:reload frequency="5000"/>
  </f:facet>
  ...
</tc:panel>

The address book uses the reload facility on an administration page to regularly display the memory utilization of the virtual machine.

As described in the the section called “Getting Started”, themes can be served directly out of the theme jars with the help of a special servlet. Generally streaming static resources poses a slight overhead, but using the servlet also provides a simple way to define HTTP expire headers for the static resources. The expiration period can be specified in seconds as an init-param for the servlet.

<servlet>
  <servlet-name>ResourceServlet</servlet-name>
  <servlet-class>
     org.apache.myfaces.tobago.servlet.ResourceServlet</servlet-class>
  <init-param>
    <param-name>expires</param-name>
    <param-value>14400</param-value>
  </init-param>
</servlet>

Instead of streaming the resources with a servlet they can be unpacked and supplied by the servlet container directly. Alternatively a web server like the Apache HTTP server can be set up in front of the servlet container. The web server can intercept the URLs for the static resources and serve them instead of the servlet container. If the themes are unpacked, only the resources should be unpacked not the class files or property files. But the jars still have to be put into the classpath in order to provide the necessary implementation files for the theme.

Besides the MyFaces JSF implementation Tobago also works with other JSF implementations like the reference implementation (RI) from Sun. The POM for the address book example provides three profiles for different JSF implementations. The default is MyFaces. There is an additional profile for the SUN RI. The third profile assumes that the container provides an implementation for JSF.

Tobago allows developing rich web applications with a rich set of controls. The development is easy and independent of the view technology. Nevertheless the web application makes use of technologies like Ajax without making any effort. The ease of development enables Tobago to be used for rapid prototyping, because the views can be designed without the need to program any lines of Java code.

In the near future the tree from the sandbox will become part of the standard Tobago distribution and you can expect more useful controls to follow. With MyFaces focusing on fulfilling the JSF specification 1.2 Tobago will aim for JSF 1.2 compatibility as well. Another goal is to attain a form of integration with other component sets like Tomahawk. Currently adding such controls to a Tobago application works only limited, partly because there is no way to add the necessary layout and theming information for external controls.