[ Team LiB ] Previous Section Next Section

21.4 Creating the Tag Library Descriptor

Now you have a good idea about what the Java classes for tag library functions and both simple and classic tag handlers looks like. When the JSP container processes a page, it converts EL functions and custom action elements into code that creates and calls the correct classes. To do this, it needs information about which tag handler implements which custom action element, and which Java method corresponds to an EL function. It gets this information from the Tag Library Descriptor (TLD). As you will see in Chapter 22, the JSP container also uses the TLD information to verify that the attribute list for an action element is correct.

The TLD is an XML file with information about all custom actions and functions in a library. A JSP page that uses a custom tag library must identify the corresponding TLD and the namespace prefix used for the actions and functions in the page with the taglib directive:

<%@ taglib prefix="ora" uri="orataglib" %>
...
<ora:addCookie name="userName" value="${param.userName}" />
...
${ora:toCelsius(param.f)}

The uri attribute identifies the TLD, in one of several ways that I describe later in this section. The prefix attribute assigns a prefix to use for the action elements and functions included in the library.

The JSP container then uses the TLD to find the information it needs to generate code for invoking the correct class when it encounters action elements and functions with a matching prefix.

Example 21-13 shows a part of the JSP 2.0 version of the TLD for the custom actions in this book. Some changes were made to the format of the TLD between JSP 2.0 and JSP 1.2, as well as between JSP 1.1 and 1.2; I describe the differences at the end of this section. A JSP 2.0 container is required to accept a TLD in the JSP 1.1 and 1.2 formats as well.

Example 21-13. Tag Library Descriptor (TLD)
<?xml version="1.0" encoding="ISO-8859-1" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
  version="2.0">

  <description>
    A tag library for the examples in the O'Reilly JSP book
  </description>
  <tlib-version>3.0</tlib-version>
  <short-name>ora</short-name>
  <uri>orataglib</uri>
  
  <tag>
    <description>
       Processes the patterns specified as attributes to render a
       calendar for the specified month.
    </description>
    <name>calendar</name>
    <tag-class>com.ora.jsp.tags.MonthCalendarTag</tag-class>
    <body-content>empty</body-content>

    <attribute>
      <name>date</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
    </attribute>
    ...
    <attribute>
      <description>
        A fragment used as a pattern for days in the previuous and following
        months, evaluated to get full weeks.
      </description>
      <name>padPattern</name>
      <required>false</required>
      <fragment>true</fragment>
    </attribute>
    ...
  </tag>
  ...
  <function>
    <description>
       Converts from Fahrenheit to Celsius
    </description>
    <name>toCelsius</name>
    <function-class>com.ora.jsp.util.TempConverter</function-class>
    <function-signature>double toCelsius(double)</function-signature>
  </function>
  ...
</taglib>

At the top of the TLD file, you find a standard XML declaration. Next follows the <taglib> root element with namespace and XML Schema declarations and the version of the JSP specification the tag library is compliant with. An XML Schema defines the rules for how elements in an XML file must be used, such as the order of the elements, which elements are mandatory and which are optional, if an element can be included multiple times, etc. If you're not familiar with XML, don't worry about this. Just accept the fact that you need to copy the first two elements in Example 21-13 faithfully into your own TLD files. With regards to the order of the elements, just define them in the order in which they are described here. Whether an element is mandatory or optional is also spelled out in the description of each element that follows. If you're curious about the formal XML Schemas, it's available online at http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd.[2]

[2] The XML Schema allows additional extension elements to be used that are not described here, because they are intended for use by tool vendors and their content is proprietary. See the JSP specification and the XML Schema for details about these elements.

The root element of the TLD file must be the <taglib> element. This element encloses more specific elements that describe the library as such, as well as the individual tag handlers and functions.

21.4.1 General Library Elements

The first set of top-level elements, in this order, describes the library itself:

  • The optional <description> element can provide a short description of the library, perhaps something a tool may display to help users decide if the library is what they are looking for.

  • The <display-name> element is an optional element, containing a name of the library suitable for display by an authoring tool.

  • An <icon> element with nested <small-icon> and <large-icon> elements can optionally be used to name image files containing icons for the library, again something a page-authoring tool may use. The values are file paths for files containing either GIF or JPEG images, interpreted as relative to the TLD file. The small icon should be 16x16 pixels, and the large 32x32 pixels.

  • The <tlib-version> element is mandatory and specifies the tag library version. The version should be specified as a series of numbers separated by dots. In other words, the normal conventions for software version numbers, such as 1.1 or 2.0.3, should be used.

  • The <short-name> element is intended for use by page-authoring tools. It's a mandatory element that should contain the default prefix for the action elements. In Example 21-13, the value is ora, meaning that an authoring tool by default generates custom action elements using the ora prefix, for instance <ora:menuItem page="page1.jsp">. A tool may also use the element value as the value of the prefix attribute if it generates the taglib directive in the JSP page. The element value must not include whitespace characters or other special characters, or start with a digit or underscore.

  • The <uri> element value can be used as the default for the uri attribute in a taglib directive generated by an authoring tool. It's an optional element, following the same character rules as the <short-name> element. While the element is optional according to the Schema, it's required for the tag library auto-discovery feature introduced in JSP 1.2. More about this feature later, but because of this, I recommend you always include this element.

21.4.2 Validator and Listener Elements

Next comes an optional <validator> element, with nested <description>, <validator-class>, and <init-param> elements. I describe how to use these elements in Chapter 22.

Another optional element is the <listener> element, with a mandatory <listener-class> element. These elements are also described in detail in Chapter 22.

21.4.3 Tag Elements

Following the general tag library elements, any number of <tag> elements can be used to describe tag handlers implemented as Java classes. The <tag> element contains other elements that describe different aspects of the custom action. In order, they are <description>, <display-name>, <icon>, <name>, <tag-class>, <tei-class>, <body-content>, <variable>, <attribute>, <dynamic-attributes>, and <example>.

21.4.3.1 General tag elements

The <description>, <display-name>, and <icon> elements are all optional and can be used to describe each tag handler in the same way as for the tag library itself.

The <name> element is mandatory and contains the name for the corresponding custom action element in the JSP pages. It must be a name that is unique among all Java tag handlers and tag files in the tag library.

The <tag-class> element, also mandatory, contains the fully qualified class name for the tag handler class.

Actions that introduce variables or do special syntax validation, as described in Chapter 22, may need a TagExtraInfo subclass in addition to the tag handler class. The optional <tei-class> element specifies the fully qualified class name for the TagExtraInfo subclass. This class is rarely needed.

The <body-content> is mandatory for JSP 2.0. It can contain one of four values: empty, JSP, scriptless, or tagdependent.

The empty value means that the action body must be empty. If a custom action backed by this tag handler is included in a page with a body, an error message is displayed.

If the body can contain JSP elements, such as EL expressions, standard and custom actions as well as scripting elements, the JSP value must be used. If it can contain EL expressions and actions but not scripting elements, use the scriptless value. Note that if the value is set to JSP, the tag handler must be implemented using the classic tag handler API. All JSP elements in a JSP or scriptless body are processed and the result is handled as specified by the tag handler (processed by the tag handler or sent through to the response body). JSP is the default value in case you omit the <body-content> element.

The fourth alternative is tagdependent; this value means that the body can contain content that looks like JSP elements but the container shouldn't evaluate them. Typically, this value is used when the tag handler processes the body and the content may contain characters that could be confused with JSP elements, such as:

SELECT * FROM MyTable WHERE Name LIKE '<%>'.

If a tag that expects this kind of body content is declared as JSP, the <%> is likely to confuse the JSP container. The tagdependent value can avoid this risk for confusion, but note that it also disables the processing of valid JSP elements. Hence, this value is rarely used. Special characters can be escaped instead, as described in Appendix A, to avoid potential confusion.

21.4.3.2 Variable elements

The <variable> element, with its nested <description>, <name-given>, or <name-from-attribute>, <variable-class>, <declare>, and <scope> elements, can provide information about variables a custom action exposes as scripting variables. I describe this in detail in Chapter 22.

21.4.3.3 Attribute elements

The <tag> element must also contain an <attribute> element for each action attribute it supports. Each <attribute> element in turn contains nested elements that describe the attribute: <description>, <name>, <required>, <rtexprvalue>, and <type> or <fragment>.

  • The optional <description> element can describe the purpose and use of the attribute, the same as for all other places where this element may appear in the TLD.

  • The mandatory <name> element specifies the attribute name, which must be unique among all attributes for the tag handler.

  • The optional <required> element tells whether the attribute is required. The values true, false, yes, and no are valid, with false being the default.

  • The <rtexprvalue> element is an optional element that can have the same values as the <required> element. If it's true or yes, a request-time expression (an EL or Java expression) can specify the attribute value, for instance:

    attr="${param.par}"
    attr='<%= request.getParameter("par") %>'

    The default value is false.

  • The optional <type> element can specify the attribute's Java type for attributes that allow a request-time expression as its value. The value must be the fully qualified name of the Java class or interface for the corresponding setter method in the tag handler class. This element is intended to be used only by authoring tools and documentation generating tools in JSP 2.0; the container doesn't have to use it, but it may report an error if the specified type doesn't match the type of the attribute in the tag handler class.

  • If the attribute value should be handled as a fragment (as described earlier in this chapter), you must include the <fragment> element with the value true or yes. The default value is false.

21.4.3.4 Dynamic attributes element

After (or instead of) the <attribute> elements, you can use the <dynamic-attributes> element with the value true or yes to specify that the tag handler accepts undeclared attributes, as described earlier in this chapter. If you omit this element it defaults to false.

21.4.3.5 Example element

The final subelement for the <tag> element is the optional <example> element. As the name implies, it can provide an example of how the custom action can be used. Tools can use this information, for instance display it as part of a tool tip for the action or include it in automatically generated documentation.

21.4.4 Tag File Elements

A TLD can also include declarations of tag files, described in Chapter 11, with any number of <tag-file> elements following the <tag> elements, if any. The <tag-file> element contains other elements that describe different aspects of the custom action. In order, they are <description>, <display-name>, <icon>, <name>, <path>, and <example>.

The <description>, <display-name>, and <icon> elements are all optional and can be used to describe each tag file in the same way as for other tag library artifacts.

The <name> element is mandatory and contains the name for the corresponding custom action element in the JSP pages. It must be a name that is unique among tags and tag files in the tag library.

The mandatory <path> element contains the path to the tag file. If the tag file is packaged together with the TLD in a JAR file, it must start with /META-INF/tags, and consequently, the tag file must be located somewhere in this structure in the JAR file. If the tag file and the TLD reside directly in the web application structure (e.g., during development), the path must start with /WEB-INF/tags.

An optional <example> element can be used to include an example of how the custom action implemented by the tag file should be used, just as for the <tag> element.

21.4.5 Function Elements

Functions used in EL expressions are mapped to static methods in a Java class using any number of <function> elements after the <tag-file> elements, if any. As with the other main elements, a number of nested elements define the details: <description>, <display-name>, <icon>, <name>, <function-class>, <function-signature>, and <example>.

The optional <description>, <display-name>, and <icon> elements can be used to describe the function in the same way as for all other items.

The mandatory <name> element contains the function name. Each function must have a unique name within the tag library.

The name of the class that contains the implementation of the function is specified by the mandatory <function-class> element as a fully qualified class name (i.e., including the package name).

The mandatory <function-signature> element specifies the function parameters and return type in the format returnType functionName(parameterType, ...), e.g.:

java.lang.String truncate(java.lang.String, int)

The optional nested <example> element is used the same as in all other elements.

21.4.6 Differences Between a JSP 1.2 and a JSP 2.0 TLD

A JSP 2.0 container is required to accept a TLD in the JSP 1.1 or 1.2 format, but you must use the new JSP 2.0 format in order to take advantage of the new features, such as tag files and functions.

Some of the differences between the JSP 1.2 and JSP 2.0 TLD file format are due to the fact that JSP 2.0 uses XML Schema for declaration (and validation) of the elements while JSP 1.2 used a Document Type Definition (DTD) for the same purpose. The switch to XML Schema applies to all descriptor files in the specifications grouped under the J2EE 1.4 umbrella, allowing for shared type definitions and grouping rules for the elements they have in common. The following differences can be attributed to the switch to XML Schema:

  • The namespace and schema declarations in the <taglib> root element replace the DTD DOCTYPE declaration, for consistency with all other J2EE 1.4 configuration files.

  • The <jsp-version> element is replaced by the version attribute in the <taglib> root element.

  • The order and grouping of the description elements are changed: the <description> and <display-name> elements have switched places and an <icon> element has been added to contain the <small-icon> and <large-icon> elements. This group of elements now also always appear as the first nested elements where they are supported; in the JSP 1.2 spec they were sometimes included in the middle of more specific elements.

  • The <body-content> element is mandatory, because the default used in previous versions of the specification is invalid for the new simple tag handler type.

The other differences are due to new features:

  • The scriptless value for the <body-content> element is added to support the new simple tag handler API.

  • The <fragment> element is added to support the new fragment attribute feature.

  • The <tag-file> top-level element is added to support the new tag file feature.

  • The <function> top-level element is added to declare EL functions.

21.4.7 Differences Between a JSP 1.1 and a JSP 1.2 TLD

If you're jumping from JSP 1.1 directly to JSP 2.0, you may feel that the list above is incomplete. That's because a number of things changed between JSP 1.1 and 1.2 as well.

Most of the differences were name changes for some elements for consistency with the naming conventions used in other J2EE descriptor files. More precisely, hyphens were added to separate words in element names, and the <info> element was replaced with the <description> element that is used for the same purpose in other descriptors. The following table summarizes these name changes:

JSP 1.1

JSP 1.2

<tlibversion>
<tlib-version>
<jspversion>
<jsp-version>
<shortname>
<short-name>
<info>
<description>
<tagclass>
<tag-class>
<teiclass>
<tei-class>
<bodycontent>
<body-content>

A number of new elements were also added to allow more descriptive information in the TLD. This information may be used by page-authoring tools and also by tools that generate user documentation from the TLD: <display-name>, <small-icon>, <large-icon>, <example>, <type>, and <variable>. How to use these new elements is described earlier in this section.

    [ Team LiB ] Previous Section Next Section