| [ Team LiB ] |
|
21.4 Creating the Tag Library DescriptorNow 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]
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 ElementsThe first set of top-level elements, in this order, describes the library itself:
21.4.2 Validator and Listener ElementsNext 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 ElementsFollowing 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 elementsThe <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 elementsThe <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 elementsThe <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>.
21.4.3.4 Dynamic attributes elementAfter (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 elementThe 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 ElementsA 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 ElementsFunctions 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 TLDA 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 other differences are due to new features:
21.4.7 Differences Between a JSP 1.1 and a JSP 1.2 TLDIf 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:
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 ] |
|