How-to write and use
a Tiles Definition Factory

Author : Cedric Dumoulin

Date : 2 Jan. 2003

Rev : 3 Jan. 2003

1Introduction

The Tiles framework allows writing and using your own Tiles definition factory.

A Tiles definition factory is used to serve a "definition" when requested by a Tiles tag or by the struts forward (from the TilesRequestProcessor).

To write a definition factory, you need to:

  • Write your factory by implementing the DefinitionsFactory interface
  • Create an instance of your factory and register it to be used by the application

2Write your factory

To write a Tiles definition factory, you should implement the DefinitionsFactory interface. This interface defines a life cycle for the factory, and a method to get a definition by its name.

You should implements:

  • public ComponentDefinition getDefinition(String name, ServletRequest request, ServletContext servletContext)
  • This is the method calls by tags and Struts RequestProcessor. It takes as parameter the name of the requested definition, the current request and the current servletContext. It returns a ComponentDefinition.
  • public void init(DefinitionsFactoryConfig config, ServletContext servletContext)
  • This method is called immediately after the creation of the factory, when this creation is done with TilesUtil.createFactory(…). This method is used to initialize the factory. For example, in the default factory, this method is used to read the xml file containing definitions.
  • public void destroy()
  • This method is normally called when the server shut down. Unfortunately this is not always the case, so don't rely on it. You can simply do nothing in the implementation.
  • public void setConfig(…)
  • This method can be used to change the factory configuration dynamically. An implementation doesn't need to implement such behavior, so it is possible to simply throw an exception.
  • public DefinitionsFactoryConfig getConfig()
  • Get the definition factory config.

The main method of the factory is getDefinition( name, …). This method returns a ComponentDefinition. This class represents a definition and provides getter and setter for the properties of a definition. Only properties used by jsp tags and TilesRequestProcessor are presents. Other properties like "extends" don't exist (In fact, these missing properties are meaningful only in Tiles configuration files, and are resolved while creating the ComponentDefinitioninstances).

The getDefinition( name, …)method should return a definition according to the specified name. It is also possible to return a definition according to the name and to some attributes stored in the provided request context or servlet context. As example, it is possible to write a method returning a definition taking into account the requested name, and the user local set in the request context.

3Register your Factory

To use your brand new factory, you need to create an instance, initialize it and register it in appropriate place.

There is a method TilesUtil.createDefinitionsFactory(…) class doing all of that for you.

Furthermore, if you use Struts you can specify the factory classname in the struts config file.

3.1With Struts 1.1

In the struts config file, declare the TilesPlugin and add the appropriate property:

<plug-in className="org.apache.struts.tiles.TilesPlugin" >

<set-property property="definitions-config"

value="/WEB-INF/tiles-defs.xml,

/WEB-INF/tiles-tests-defs.xml,/WEB-INF/tiles-tutorial-defs.xml,

/WEB-INF/tiles-examples-defs.xml" />

<set-property property="moduleAware" value="true" />

<set-property property="factoryClassname" value="your.factory.Classname" />

</plug-in>

You can pass additional attributes to your factory by adding them to the plugin:

<set-property property="anotherProperty" value="aValue" />

You access them in your factory from the config object:

config.getAttribute(String name)

This config object is passed to the factory by its init( config, …) method.

3.2Without Struts

You need to find a place where you perform all the initialization. A common practice is to do it in the init() method of a servlet.

You can create your factory instance by calling the appropriate method in TilesUtil. createDefinitionsFactory(…) . This method requires a DefinitionsFactoryConfig object containing the name of the factory in its factoryClassname property. You can set this property with config.setFactoryClassname(classname).

A possible way is as follow:

DefinitionsFactoryConfig config = new DefinitionsFactoryConfig()

config.setFactoryClassname("your.factory.Classname" );

TilesUtil.createDefinitionsFactory(servletContext, config);

You can

You can also initialize your definitionFactory object from a config file or from the web.xml file:

DefinitionsFactoryConfig factoryConfig = readFactoryConfig(servletConfig);

An implementation of this method can be found in DefinitionUtils (but it is deprecated).