Component Specification

The component specification is an XML document. This discussion assumes a passing familiarity with XML documents. The specification is located inside the running Java VMs class path; in a deployed application, it will be a package resource, located (along with the Java class files) in the WEB-INF/classes directory of the WAR (Web Application Archive).

These specifications can be somewhat verbose, it is strongly advised that a DTD-aware XML editor be used, rather than hand editting the files.

<specification> element

Component specification files, which use the filename extension .jwc, consist of a <specification> element.

Figure 4.5. Component specification: <specification> element

<?xml version="1.0"?>
<!DOCTYPE specification PUBLIC 
  "-//Howard Ship//Tapestry Specification 1.1//EN"
  "http://tapestry.sf.net/dtd/Tapestry_1_1.dtd">


<specification 
  allow-body="yes|no" 1
  allow-informal-parameters="yes|no" 2
  class="java-class"> 3
  
  [ <description ...> ...]
  [ <parameter ...> ...]
  [ <reserved-parameter ...> ...]
  [ <property ...> ...]
  [ <bean ...> ...]
  [ <component ...> ...]
  [ <asset ...> ...]
</specification>

1

Whether the component is allowed to have a body, that is, wrap around other components and static HTML. The default is 'yes', so this attribute is usually ommitted.

2

Whether informal parameters are allowed. Informal parameters are additional parameters beyond the ones formally defined. These are typically used with components that map directly to an HTML element, to allow additional HTML attributes to be specified. The default is 'yes', so this attribute is usually ommitted.

3

The complete class name of the component class, for example, com.skunkworx.skunkapp.Border.

Versions of the DTD

There was an earlier version of the DTD, version 1.0, which is the version used with Tapestry Release 1.0.0. Version 1.1 is more succinct and readable than version 1.0 and has a few extra features. Both versions are supported by Tapestry until at least release 1.1.0.

As previously described, the specification name is used to find the base HTML template name (by replacing the '.jwc' extension with '.html').

During development, such resources may be in the developer's work areas, but when the application is deployed, they will almost always be distributed inside a Java Archive (JAR) file or Web Application Archive (WAR) file. This is one of the ways that Tapestry eases deployment.

The <specification> element wraps around all other elements in the specification (which are used to define parameters, embedded components and assets). The following sections describe these additional elements.

<description> element

One or more <description> elements may be included in the specification. These are descriptions of the component's features and behavior, suitable for inclusion in some form of IDE [4]. Multiple descriptions are used to support multiple languages.

Figure 4.6. Component specification: <description> element

<description 
  xml:lang="language code"> 1
  ... text ... 
</description>

1

The language in which the descriptive text is written. This takes the form of a two letter code, defined by the ISO-639 standard.

<description> usage

The <description> element is really used for future expansion, towards a time when an integrated HTML / Tapestry Specification editor does exist. Also, a Javadoc doclet may be created that can read Tapestry specifications and include them with Javadoc. In the meantime, descriptions can be used like XML comments.

<parameter> element

This element is used to describe formal parameters used by a component.

Figure 4.7. Component specification: <parameter> element

<parameter
  name="name" 1
  java-class="text" 2
  required="yes|no"> 3
  [ <description ... > ...] 4
</parameter>

1

Each parameter must have a unique name. Parameter names must start with a letter and may contain letters, numbers and the underscore.

2

Identifies the Java class or type that must be provided for the parameter. This is for descriptive purposes only, there is no validation by the framework. Additionally, most components will do their best to cooerce whatever value is given them into a useful type, such as parsing a String into an int.

The java-type attribute is optional.

3

If 'yes', then the parameter must be bound when the page is loaded. The default, 'no', allows a parameter to not be bound.

Individual components may do a second check, that the bound parameter provides a non-null value.

4

Each parameter is allowed to have its own set of localized descriptions.

<reserved-parameter> element

The <reserved-parameter> element is used to identify parameter names that may not be used as informal parameters. Informal parameters may not match the name of any formal parameter, or any reserved parameter names (comparisons ignore case).

The point of this is to allow components to declare HTML attributes generated by the component to be "off limits" to informal parameters. For example, the TextField component declares that the input and name parameters are reserved, since those are generated by the component and should not be overriden in any way.

Figure 4.8. Component specification: <reserved-parameter> element

<reserved-parameter name="name"/>
			

<property> element

Allows arbitrary name / value pairs to be associated with the container (a component or application).

Figure 4.9. Component specification: <property> element

<property name="name">
  [ value ]
</property>

<bean> element

The <bean> element is used to identify helper beans for the component.

Figure 4.10. Component specification: <bean> element

<bean name="name"
  class="class"
  lifecycle="none|request|page">

  [ <description ... > ... ]
  [ <set-property ... > ... ]

</bean>

The name is the name of the bean, which must be unique for beans within the component. The bean will be accessible using the property path beans.name . Beans are instantiated as needed, the may be cached for later use. The class is the complete Java class name to instanatiate.

The default lifecycle is request, if not specified.

Any number of <set-property> elements may be specified, to intialize the properties of the bean.

<set-property> element

This element is used to set a property of a helper bean, and appears only inside the <bean> element. Properties are set just after the bean is instantiated. For poolable beans, properties are set just after the bean is retrieved from the pool.

Values for properties are specified using the <static-value> and <property-value> element.

Figure 4.11. Component specification: <set-property> element

<set-property name="name">
  [ <static-value ... > | <property-value ... > ]
</set-property>

The name attribute identifies the property to be changed. The value is provided by a <static-value> or <property-value> element.

<static-value> element

This element, which apparers only within a <set-property> element provides a static value with which to set the property.

Figure 4.12. Component specification: <static-value> element

<static-value type="boolean|int|double|String">
  [ value ]
</static-value>

The value is the simple text content inside the element. It is converted from a string representation to one of the available types (more types will be added in the future). The default is String, in which case the value is used as is, after leading and trailing whitespace is removed.

<property-value> element

This element appears inside a <set-property> element to set a property of the bean from a dynamic property of the containing component. The component property, which may be a property path, is evaulated when the bean is instantiated.

Figure 4.13. Component specifciation: <property-value> element

<property-value property-path="property path"/>

<component> element

The <component> element is used to describe an embedded component, a component identified in the containing component's HTML template.

Figure 4.14. Component specification: <component> element

<component
  id="id" 1
  type="type" 2
  copy-of="id"> 3
  [ <binding|field-binding|inherited-binding|static-binding ...> ... ]
</component>

1

Each component must have a unique identifier within its container. The id attribute must conform to an XML id: start with a letter, and contain only letters, numbers and underscores.

2

The component type is either the the complete path to a component specification, or a well known alias. All the components provided with the framework have well known aliases, at it is possible to create additional aliases in the Tapestry application specification.

3

Instead of specifying a type, a component may be a copy of one of its siblings. In this case, the new component is created by copying the type and bindings of the existing component. It is possible to specify additional bindings as well.

The component being copied from must be declared first.

You must specify either the type or copy-of attributes, but not both.

Each component must also have a type. Types are resource paths for a component specification. Specifications end with '.jwc'. An example would be /com/skunkworx/skunkapp/Banner.jwc.

Unlike HTML templates, specifications are never localized.

As a convenience, aliases may be defined for components. An alias is a short name that takes the place of the specification resource path. All built-in components for Tapestry have aliases, and an application specification may define additional aliases.

For example, the component /com/primix/tapestry/links/Action.jwc has a standard alias of Action.

Binding elements

There are four different types of bindings. The standard binding is most common, as it binds a parameter to a property of an object, and may be read, write or read/write.

Figure 4.15. Component specification: binding elements

<binding
  name="name" 1
  property-path="property-path"/> 2
  
<field-binding
  name="name"
  field-name="field-name"/> 3
  
<inherited-binding
  name="name"
  parameter-name="parameter-name"/> 4
  
<static-binding
  name="name">
  	... value ... 5
</static-binding>

1

A name of the parameter to bind. This usually matches the name of a formal parameter of the component. For components which allow informal parameters, this may be any value.

2

The name of a property reachable from the containing component.

3

The name of a public static field. This takes the form class name.field name. The class name is the complete class name (including the package names), unless the package is java.lang, in which case the package portion can be ommitted.

Field bindings are often more useful than static bindings, because the value does't have to be a convertable from a string. This means true objects, not just holders of single values, can be used, this is quite useful when dealing with the form element components.

4

The name of a formal or informal parameter of the containing component. The contained component will share the same binding. This is one of the ways in which it is possible to build complex components by combining simple ones.

5

Unlike the other binding types, the <static-binding> element wraps around its static value, which allows for maximum flexibility. It does, however, remove all leading and trailing whitespace from the value.

An example of using an <inherited-binding> is the Border component, which has a title parameter that gives the name of the page. The Border component embeds an Insert component, and uses an inherited binding to set the Insert component's value parameter to the containing Border component's title parameter.

Asset elements

Assets are a way of identifying resources whose URLs will appear in a web page. Most often, the assets are image files used with an Image or Rollover components.

Figure 4.16. Component specification: Asset elements

<context-asset
	name="name"
	path="path"/>
	
<external-asset
	name="name"
	URL="URL"/>
	
<private-asset
	name="name"
	resource-path="resource-path"/>

Assets may be stored at some arbitrary URL, may be within the same web application context as the Tapestry application, or may be stored as a resource inside Java VM class path.

In all three cases, the name must be very simple: start with a letter and contain only letters, numbers and underscores or dashes. Assets names must be unique within the component.

For external assets, the URL must be complete: it will be inserted into the HTML unchanged. In many cases, the URL can omit the http://hostname portion of the URL, if the asset is located on the same host as the web application.

For context assets the path must be relative to the servlet context. Context assets may be localized; this will be reflected in the actual file chosen and in the URL inserted into the HTML. The final URL inserted into the HTML will include the servlet context prefix and may reflect a localized path.

For private assets, the resource path must be a resource path within the Java VM class path, as with a specification or HTML template resource path. This means the asset can be stored in the WEB-INF/classes directory of the application's WAR, or inside some JAR in the classpath. Like context assets, private assets may be localized.



[4] If someone writes such an IDE, please let me know!