Skip Headers

Oracle® Application Server Containers for J2EE Support for JavaServer Pages Developer's Guide 10g Release 2 (10.1.2) B14014-02 |
| Library | Product | Contents | Index

Previous | Next |

# 8 JSP Tag Libraries

This chapter discusses custom tag libraries, covering the basic framework that vendors can use to provide their own libraries. There is also discussion of Oracle extensions and a comparison of standard runtime tags versus vendor-specific compile-time tags. The chapter consists of the following sections:

- Overview of the Tag Library Framework

- Tag Library Descriptor Files

- Tag Library and TLD Setup and Access

- Tag Handlers

- OC4J JSP Tag Handler Features

- Scripting Variables, Declarations, and Tag-Extra-Info Classes

- Validation and Tag-Library-Validator Classes

- Tag Library Event Listeners

- End-to-End Custom Tag Examples

- Compile-Time Tags

The chapter offers a detailed overview of standard tag library functionality. For complete information, refer to the Sun Microsystems JavaServer Pages Specification. For information about the tag libraries provided with OC4J, see the Oracle Application Server Containers for J2EE JSP Tag Libraries and Utilities Reference.

Custom tag syntax largely follows XML conventions. For general information about XML, you can find the specification at the following Web site:

    http://www.w3.org/XML/

## Overview of the Tag Library Framework

JavaServer Pages technology allows vendors to create custom JSP tag libraries. A tag library defines a collection of custom actions. The tags can be used directly by developers in manually coding a JSP page, or automatically by Java development tools.

This section provides an overview of the JSP tag library framework as well as a summary of tag library features introduced in the JSP 1.2 specification.

For information beyond what is provided here regarding tag libraries and the standard JavaServer Pages tag library framework, refer to the following resources:

- Sun Microsystems JavaServer Pages Specification

- Sun Microsystems Javadoc for the `javax.servlet.jsp.tagext` package, at the following Web site:

    http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/jsp/tagext/package-summary.html

### Overview of a Custom Tag Library Implementation

A custom tag library is made accessible to a JSP page through a `taglib` directive of the following general form:

    <%@ taglib uri="URI" prefix="prefix" %>

Note the following points about implementation and usage of a tag library:

- The tags of a library are defined in a tag library descriptor (TLD) file, as "Tag Library Descriptor Files" describes.

- The URI in the `taglib` directive is a pointer to the TLD file, as "Overview: Specifying a Tag Library with the taglib Directive" discusses. It is possible to use URI shortcuts, as "Use of web.xml for Tag Libraries" explains.

- The prefix in the `taglib` directive is a string of your choosing that you use in your JSP page with any tag from the library.

  Assume that the `taglib` directive specifies a prefix `oracust`:

      <%@ taglib uri="URI" prefix="oracust" %>

  Further assume that there is a tag, `mytag`, in the library. You might use `mytag` as follows:

      <oracust:mytag attr1="...", attr2="..." />

  Using the `oracust` prefix informs the JSP translator that `mytag` is defined in the TLD file that can be found through the URI specified in the above `taglib` directive.

- The entry for a tag in the TLD file provides specifications about use of the tag, including whether the tag uses attributes (as `mytag` does), and the names of those attributes.

- The semantics of a tag—the actions that occur as the result of using the tag—are defined in a tag handler class, as "Tag Handlers" describes. Each tag has its own tag handler class, and the class name is specified in the TLD file.

- A tag attribute can be of any standard Java type or an object type—either the generic `java.lang.Object` or a user-defined type.

  You typically set an attribute of a standard Java type as a string value. The appropriate conversion is handled automatically.

  You can also set an attribute of type `Object` with a string value. The string is converted to an `Object` instance and passed in to the corresponding setter method in the tag handler instance. This feature complies with the JSP specification.

  An attribute of a user-defined type must be set using a request-time expression that returns an instance of the type.

- The TLD file indicates whether a tag uses a body.

  A tag without a body is used as in the following example:

      <oracust:mytag attr1="...", attr2="..." />

  By contrast, a tag with a body is used as in the following example:

      <oracust:mytag attr1="...", attr2="..." >
         ...body...
      </oracust:mytag>

- A custom tag action can create one or more server-side objects that are available for use by the tag itself or by other JSP scripting elements, such as scriptlets. These objects are known as scripting variables.

  You can declare a scripting variable through a `<variable>` element in the TLD file or through a tag-extra-info class. See "Scripting Variables, Declarations, and Tag-Extra-Info Classes" for more information.

  A tag can create and use scripting variables with syntax such as in the following example, which creates the object `myobj`:

      <oracust:mytag id="myobj" attr1="...", attr2="..." />

- The TLD file can optionally declare a tag-library-validator class for use with the tag library. This class would have logic to validate any JSP page that uses the tag library, according to specified constraints. See "Validation and Tag-Library-Validator Classes".

- The TLD file can optionally declare one or more event listeners for use with the tag library. This functionality is offered as a convenient alternative to declaring listeners in the application `web.xml` file. See "Tag Library Event Listeners".

- The tag handler of a nested tag can access the tag handler of an outer tag, in case this is required for any of the processing or state management of the nested tag. See "Access to Outer Tag Handler Instances".

The remainder of this chapter provides details about these topics.

### Overview of Tag Library Changes Between the JSP 1.1 and 1.2 Specifications

The JSP 1.2 specification introduced features for improved tag library support in the following areas:

- Tag library descriptor features

  Features are outlined in the next section, "Summary of TLD File Changes Between the JSP 1.1 and 1.2 Specifications". "Tag Library Descriptor Files" describes TLD features in detail.

- Support for multiple tag libraries and their TLD files in a single JAR file

  According to the JSP 1.1 specification, you could not have multiple TLD files packaged in a single JAR file. The JSP 1.2 specification supports this, however. See "Tag Handlers".

- Tag handler features

  Features are summarized in "Summary of Tag Handler Changes Between the JSP 1.1 and 1.2 Specifications". Tag handler features are described in detail in "Tag Handlers".

- Tag library validators

  This feature was introduced in the JSP 1.2 specification. See "Validation and Tag-Library-Validator Classes".

- Tag library event listeners

  This feature was also introduced in the JSP 1.2 specification. See "Tag Library Event Listeners".

- Support for tag attributes of type `Object`

  The JSP 1.2 specification introduced support for tag attributes of type `java.lang.Object`. The OC4J JSP container supports this feature, as described in the previous section, "Overview of a Custom Tag Library Implementation".

Important: In Oracle Application Server 10g Release 2 (10.1.2), the OC4J JSP container by default expects JSP 1.1, not JSP 1.2, tag syntax and usage. To use JSP 1.2 features described in the following sections, specify the JSP 1.2 TLD DTD, as shown in "Overview of TLD File Validation and Features".

#### Summary of TLD File Changes Between the JSP 1.1 and 1.2 Specifications

The following list is a summary of features in TLD syntax and functionality that were introduced in the JSP 1.2 specification. These changes were not available prior to Oracle9iAS Release 2 (9.0.3). "Tag Library Descriptor Files" includes information about these features.

- The `<validator>` element and its subelements, allowing you to declare a tag-library-validator class for the tag library

- The `<listener>` element and its subelement, allowing you to declare event listeners for the tag library

- The `<variable>` subelement, and its own subelements, under the `<tag>` element, allowing you to declare scripting variables directly through the TLD

- The `<type>` subelement under the `<attribute>` subelement of the `<tag>` element, for noting the datatype of the attribute

- The `<display-name>`, `<large-icon>`, and `<small-icon>` elements, and also subelements of the same name under the `<tag>` element, for use by authoring tools

- Renamed elements since the JSP 1.1 specification, as follows:

  - The `<info>` element, and the subelement of the same name under the `<tag>` element, were renamed to `<description>`.

  - The `<tlibversion>` element was changed to `<tlib-version>`.

  - The `<jspversion>` element was changed to `<jsp-version>`.

  - The `<shortname>` element was changed to `<short-name>`.

  - The `<tagclass>`, `<teiclass>`, and `<bodycontent>` subelements under the `<tag>` element were changed to `<tag-class>`, `<tei-class>`, and `<body-content>`.

    - Notes: The OC4J JSP container enables XML validation of TLD files separately from validation of the `web.xml` file. Validation of TLD files is enabled by default; validation of `web.xml` is disabled by default. (See "JSP Configuration Parameter Descriptions" for information about the `no_tld_xml_validate` and `xml_validate` parameters.) In Oracle9iAS Release 2 (9.0.2) and prior, TLD files and `web.xml` were all validated through the `xml_validate` parameter, which was disabled by default. OC4J provides a sample XSL template that you can use with a standard XSLT program, such as `oraxsl`, to convert a JSP 1.1-compliant TLD file into one that is JSP 1.2-compliant. This template is located in the `misc` directory in the OC4J demos directory structure. You can find the demos through the following location:
          http://www.oracle.com/technology/tech/java/oc4j/demos/

#### Summary of Tag Handler Changes Between the JSP 1.1 and 1.2 Specifications

The JSP 1.1 specification documented two interfaces to be implemented by tag handlers: `Tag` for tags without bodies, and `BodyTag` for tags with bodies. The JSP 1.2 specification introduced the `IterationTag` interface, for tags that call for iteration through a tag body, but do not require access to the tag body content through a body content object. `IterationTag` extends `Tag` and is extended by `BodyTag`.

Also as of the JSP 1.2 specification, the `int` constant `EVAL_BODY_TAG`, which indicates that there is a tag body to be processed, is deprecated and replaced by `EVAL_BODY_AGAIN` and `EVAL_BODY_BUFFERED`. `EVAL_BODY_AGAIN` is used with tags that iterate through a tag body, to specify that iteration should continue. `EVAL_BODY_BUFFERED` is used with tags that require access to body content, to direct that a `BodyContent` object be created.

The JSP 1.2 specification also introduced the `TryCatchFinally` interface, which any tag handler can implement for improved data integrity and resource management when exceptions occur.

The JSP 1.2 changes were not available prior to Oracle9iAS Release 2 (9.0.3). "Tag Handlers" includes information about these new features.

## Tag Library Descriptor Files

A tag library descriptor (TLD) file is an XML-style document that defines a tag library and its individual tags. The name of a TLD file has the `.tld` extension.

A JSP container uses the TLD file in determining what action to take when it encounters a tag from the library. The `taglib` directive in a JSP page informs the JSP container where to find the TLD file. (See "Overview: Specifying a Tag Library with the taglib Directive".)

The following sections provide an overview and general information about TLD file syntax and usage, referring ahead to other sections as appropriate for more information about related topics:

- Overview of TLD File Validation and Features

- Use of the tag Element

- Other Key Elements and Their Subelements: validator and listener

For complete information, refer to the Sun Microsystems JavaServer Pages Specification.

See "Example: Using the IterationTag Interface and a Tag-Extra-Info Class" for a sample TLD file.

Note: By default, the OC4J JSP container performs XML validation of TLD files. To disable this, set the `no_tld_xml_validate` JSP configuration parameter to `true`. See "JSP Configuration Parameter Descriptions" for more information. For pretranslation, use the `ojspc -noTldXmlValidate` option, described in "Option Descriptions for ojspc".

### Overview of TLD File Validation and Features

The OC4J JSP container uses the `DOCTYPE` declaration of a TLD file to determine which TLD DTD version to validate against, unless TLD validation has been disabled. By default in Oracle Application Server 10g Release 2 (10.1.2), the JSP container assumes the JSP 1.1 TLD DTD. To use the JSP 1.2 TLD DTD, list the following as the system ID (DTD location):

    http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd

Here is an example:

    <!DOCTYPE taglib
            PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
            "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">

When TLD validation is enabled, the XML parser must be able to reference the appropriate DTD, which it can do with the above `DOCTYPE` declaration for JSP 1.2. TLD validation is enabled if the JSP `no_tld_xml_validate` parameter has its default `false` setting, or, for pretranslation, if the `ojspc -noTldXmlValidation` flag is not used.

Note: According to the JSP specification, use an absolute URL to specify the system ID. If a TLD file does not use a public external `DOCTYPE` declaration with an absolute URL, the default in Oracle Application Server 10g Release 2 (10.1.2) is to assume that the JSP 1.1 TLD DTD is intended.

A TLD file provides definitions for the tag library as a whole as well as for each individual tag. For each tag, it defines the tag name, its attributes (if any), its scripting variables (if any), and the name of the class that handles tag semantics. See "Use of the tag Element".

For the library as a whole, TLD definitions can include a tag-library-validator class and event listeners. See "Other Key Elements and Their Subelements: validator and listener".

A TLD file also provides additional definitions for the library as a whole, as follows.

Note: The `<tag>`, `<validator>`, and `<listener>` elements and the elements listed below are top-level subelements under the `<taglib>` root element of the TLD file.

- The required `<tlib-version>` element specifies the version number of the tag library (whatever version number you want to give it).

- The required `<jsp-version>` element specifies the JSP version upon which this tag library depends (such as 1.2).

- The `<uri>` element can specify a string value that uniquely identifies this tag library. In particular, this is useful in situations where multiple tag libraries and their TLD files are packaged in a single JAR file. See "Packaging and Accessing Multiple Tag Libraries in a JAR File".

- The required `<short-name>` element specifies a convenient default name for the library, for possible use by authoring tools. You could also use the short name as a preferred tag prefix for the library, for use in the `taglib` directive.

- There are also additional elements that you can use, typically for authoring tools: the `<display-name>` element for a display name of the tag library, and the `<large-icon>` and `<small-icon>` elements for the file names (`.jpg` or `.gif`) of a large icon, a small icon, or both. Icon file locations are relative to the TLD file.

- The `<description>` element can provide a description of the tag library.

  Note: Several descriptive elements were added to the JSP 1.2 TLD DTD. In addition to the `<description>` element directly under the root `<taglib>` element, there are `<description>` subelements under the `<tag>`, `<variable>`, and `<attribute>` elements. There is also an `<example>` subelement under the `<tag>` element. These subelements can provide information for developers who wish to use the tag library. In particular, a TLD can be processed, such as through an XSLT style sheet, to provide developer documentation from the material in the descriptive elements. This information can be displayed in the help windows of tools such as Oracle JDeveloper, for example.

### Use of the tag Element

Each tag of a tag library is specified in a `<tag>` element under the root `<taglib>` element of the TLD file. There must be at least one `<tag>` element in a TLD file. This section describes its usage and subelements.

#### Subelements of the tag Element

The subelements of a `<tag>` element define a tag, as follows:

- The required `<name>` subelement specifies the name of the tag.

- The required `<tag-class>` subelement specifies the name of the corresponding tag handler class. See "Tag Handlers" for information about tag handler classes.

- The `<body-content>` subelement indicates how the tag body (if any) should be processed. See the example and accompanying discussion in "Sample tag Element and Use of Its body-content Subelement".

- Each `<variable>` subelement (if any), with its further subelements, defines a scripting variable. See "Scripting Variables, Declarations, and Tag-Extra-Info Classes" for information about scripting variables. The `<variable>` element is for relatively uncomplicated situations, where the logic for the scripting variable does not require a tag-extra-info class. The variable name is specified through either the `<name-given>` subelement, to specify the name directly, or the `<name-from-attribute>` subelement, to specify the name of a tag attribute that specifies the variable name. There is also a `<variable-class>` subelement to specify the class of the variable, a `<scope>` subelement to specify the scope of the variable, and a `<declare>` subelement to specify whether the variable is to be newly defined. See "Variable Declaration Through TLD variable Elements" for more information. Another subelement under `<variable>` is an optional `<description>` element.

- Each `<tei-class>` subelement (if any) specifies the name of a tag-extra-info class that defines a scripting variable. This is for situations where declaring the variable through a `<variable>` element is not sufficient. See "Variable Declaration Through Tag-Extra-Info Classes" for more information.

- Each `<attribute>` subelement (if any), with its further subelements, provides information about an attribute of the tag—a parameter that you can specify when you use the custom tag. Subelements of `<attribute>` include the `<name>` element to specify the attribute name, the `<type>` element to optionally note the Java type of the attribute value, the `<required>` element to specify whether the attribute is required (default `false`), and the `<rtexprvalue>` element to specify whether the attribute can accept runtime expressions as values (default `false`). See the example and accompanying discussion below. Another subelement under `<attribute>` is an optional `<description>` element.

Notes: As of Oracle Application Server 10g Release 2 (10.1.2), the OC4J JSP container ignores the `<type>` element. It is for informational use only, for anyone examining the TLD file. Additionally, note the following: For literal attribute values, where `<rtexprvalue>` specifies `false`, the `<type>` value (if any) should always be `java.lang.String`. When `<rtexprvalue>` specifies `true`, then the type of the tag handler property corresponding to this tag attribute determines what you should specify for the `<type>` value (if any).

- As with the tag library as a whole, each tag can have its own `<display-name>`, `<large-icon>`, and `<small-icon>` subelements for use by authoring tools.

- The `<description>` subelement can provide a description of the tag.

- The `<example>` subelement can provide an example of how to use the tag.

Notes: A custom tag name must qualify as an `NMTOKEN` according to the XML specification. For example, it cannot start with a numeric character. Attribute names must follow naming conventions for XML attributes, and their setter methods in tag handler classes must follow the JavaBeans specification.

#### Sample tag Element and Use of Its body-content Subelement

Here is a sample TLD file entry for a tag `myaction`:

    <tag>
      <name>myaction</name>
      <tag-class>examples.MyactionTag</tag-class>
      <tei-class>examples.MyactionTagExtraInfo</tei-class>
      <body-content>JSP</body-content>
      <attribute>
        <name>attr1</name>
        <required>true</required>
      </attribute>
      <attribute>
        <name>attr2</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
      </attribute>
    </tag>

According to this entry, the tag handler class is `MyactionTag` and the tag-extra-info class is `MyactionTagExtraInfo`. The attribute `attr1` is required; the attribute `attr2` is optional and can take a runtime expression as its value.

The `<body-content>` element indicates how the tag body (if any) should be processed. There are three choices:

- A value of `empty` indicates that the tag uses no body. In this case, the OC4J JSP translator will return an exception if there is a tag body.

- A value of `JSP` (the default) indicates that the tag body should be processed as JSP source code and translated.

- A value of `tagdependent` indicates that the tag body should not be translated. Any text in the body is treated as template data.

Consider the following example:

    <foo:bar>
       <%=blah%>
    </foo:bar>

If the `bar` tag has a `<body-content>` value of `JSP`, then the body is processed by the JSP translator, and the expression is evaluated. With a `<body-content>` value of `tagdependent`, the JSP translator does not process the body. In this case, the characters "`<`", "`%`", "`=`", and "`>`" have no special meaning—they are treated as literal characters, along with the rest of the body, and are part of the JSP `out` object passed straight through to the tag handler.

There are additional considerations for JSP XML documents. In this case, because the document is parsed by the XML parser, it is not appropriate to implement support for a value of `tagdependent`. This value is essentially meaningless in a JSP XML document.

One reason for this is that in XML, there is already a convenient mechanism for escaping body content—using the `CDATA` token. But beyond that, there are many scenarios where it would actually be undesirable to pass content straight through as a `tagdependent` implementation would do. Consider an example using a tag for SQL queries, with traditional syntax:

    <foosql:query ... >
       select ... where salary > 1000
    </foosql:query>

Compare this to the following JSP XML syntax:

    <foosql:query ... >
       <![CDATA[select ... where salary > 1000]]>
    </foosql:query>

In the traditional syntax, a `<body-content>` value of `tagdependent` would result in the query statement being passed straight through to the JSP `out` object, presumably the desired result.

In the XML syntax, the `CDATA` token (or, alternatively, a "`&gt`;" escape character) is required, because otherwise the character "`>`" has special meaning to the XML parser.

In this example, if an implementation of `tagdependent` were used, the entire body would be passed through to the `out` object:

    <![CDATA[select ... where salary > 1000]]>

But presumably, the information that should really be passed through is only the SQL query itself:

    select ... where salary > 1000

This is what would happen by processing the body through a `<body-content>` value of `JSP`, and using the `CDATA` token for the XML parser. This is more appropriate behavior than what would happen with a `tagdependent` implementation.

See "Details of JSP XML Documents" for more information about JSP XML syntax.

### Other Key Elem ents and Their Subelements: validator and listener

The TLD `<validator>` and `<listener>` elements were introduced in the JSP 1.2 specification.

A `<validator>` element and its subelements specify information about a tag-library-validator (TLV) class that can validate JSP pages that use this tag library. The `<validator>` element has three subelements: `<validator-class>`, `<description>`, and `<init-param>`. The `<init-param>` subelement has the same functionality as `<init-param>` subelements within `<servlet>` elements in the `web.xml` file. It has `<param-name>` and `<param-value>` subelements to specify each parameter. See "Validation and Tag-Library-Validator Classes" for more information.

A `<listener>` element and its `<listener-class>` subelement specify an event listener for use with the tag library, such as in creating and destroying resource pools used by the library. See "Tag Library Event Listeners" for more information.

## Tag Library and TLD Setup and Access

The following sections discuss the packaging, placement, and access of tag libraries and their TLD files:

- Overview: Specifying a Tag Library with the taglib Directive

- Specifying a Tag Library by Physical Location

- Packaging and Accessing Multiple Tag Libraries in a JAR File

- Use of web.xml for Tag Libraries

- Oracle Extensions for Tag Library Sharing and Persistent TLD Caching

- Example: Multiple Tag Libraries and TLD Files in a JAR File

Notes: It is highly recommended to place TLD files under the application `/WEB-INF` directory. In future releases this will be enforced. If you use tag library JAR files at the application level that are intended to supersede JAR files in the well-known tag library location (global level), then you must specify that the application class loader search local classes first. In the application `orion-web.xml` file, in the `<web-app-class-loader>` element, set the `search-local-classes-first` attribute to a value of "`true`". In OC4J standalone, if you add a tag library JAR file to the `/WEB-INF/lib` directory while OC4J is running, you must use a `tags_reuse_default` flag value of "`none`" or "`compiletime`" to avoid a `ClassCastException`. You must also force retranslation of relevant JSP pages (such as by touching the `.jsp` files or removing the corresponding `.class` files).

### Overview: Specifying a Tag Library with the ta glib Directive

This section summarizes the use of `taglib` directives, comparing functionality under the JSP 1.1 specification to functionality under the JSP 1.2 and later specifications.

Import a custom library into a JSP page by using a `taglib` directive of the following general form:

    <%@ taglib uri="URI" prefix="prefix" %>

The `prefix` setting specifies a string of characters that stipulates when tags from this library are being used. For example, if `mytag` is in a library that has a specified prefix of `oracust`, use `mytag` as follows:

    <oracust:mytag attr1="..." attr2="..." >
    ...
    </oracust:mytag>

Note: Prefixes must follow the naming conventions of the XML namespaces specification.

The JSP 1.1 specification stated that the `uri` setting can indicate a file location as in either of the following scenarios, either directly or through a "shortcut" URI:

- It can indicate the physical location, within a WAR file structure, of the TLD file that defines the desired tag library.

- It can indicate the physical location of the JAR file that contains the components and TLD file of the desired tag library. Under the JSP 1.1 specification, there can be only one tag library and only one TLD file in the JAR file.

See "Specifying a Tag Library by Physical Location" for more information.

Beginning with the JSP 1.2 specification, the `uri` setting can still indicate the physical location of a TLD file or the location of a JAR file containing one tag library and its TLD file, but it can also be used as follows:

- It can specify one of multiple tag libraries packaged in a single JAR file, by specifying a value that matches the `<uri>` element value in one of the TLD files in the JAR file. In this case, the `uri` setting is intended to be a unique key, not a pointer to a physical location.

As under JSP 1.1, you can also use a shortcut URI.

See "Packaging and Accessing Multiple Tag Libraries in a JAR File" for more information. For information about shortcut URIs, see "Use of web.xml for Tag Libraries".

### Specifyi ng a Tag Library by Physical Location

As first defined in the JSP 1.1 specification, the `taglib` directive of a JSP page can fully specify the name and physical location, within a WAR file structure, of the TLD file that defines a particular tag library, as in the following example:

    <%@ taglib uri="/WEB-INF/oracustomtags/tlds/mytld.tld" prefix="oracust" %>

Specify the location as application-relative by starting with "`/`" as in this example. See "Requesting a JSP Page" for discussion of application-relative syntax.

Be aware that the TLD file should be in the `/WEB-INF` directory or a subdirectory.

Alternatively, as also defined since the JSP 1.1 specification, the `taglib` directive can specify the name and application-relative physical location of a JAR file instead of a TLD file, where the JAR file contains a single tag library and the TLD file that defines it. In this scenario, the JSP 1.1 specification mandated that the TLD file must be located and named as follows in the JAR file:

    META-INF/taglib.tld

The JSP 1.1 specification also mandated that the JAR file must be located in the `/WEB-INF/lib` directory.

Here is an example of a `taglib` directive that specifies a tag library JAR file:

    <%@ taglib uri="/WEB-INF/lib/mytaglib.jar" prefix="oracust" %>

Also see "Packaging and Accessing Multiple Tag Libraries in a JAR File", following, which describes a scenario introduced in the JSP 1.2 specification.

Note: In either scenario discussed in this section, the `taglib` directive can specify a "shortcut" URI that corresponds to the complete URI value according to settings in the `web.xml` file. See "Use of web.xml for Tag Libraries".

### Packa ging and Accessing Multiple Tag Libraries in a JAR File

The preceding section, "Specifying a Tag Library by Physical Location", discusses the JSP 1.1 scenarios of using a `taglib` directive to specify a TLD file by physical location, or to specify a JAR file that contains a single tag library and its TLD file.

Adding to these scenarios, the JSP 1.2 specification introduced the packaging of multiple tag libraries, and the TLD files that define them, in a single JAR file. Inside the JAR file, these TLD files must be located under the `/META-INF` directory or a subdirectory.

A single TLD file in a JAR file can be packaged as `/META-INF/taglib.tld`, or you can use another name as desired. (In JSP 1.1, the `taglib.tld` naming convention was a requirement.)

In a JAR file with multiple TLD files, the TLD files must be uniquely named or be in different subdirectories under `META-INF`.

Here are a couple of possibilities, for example, for packaging three TLD files in a JAR file:

    META-INF/abctags.tld
    META-INF/deftags.tld
    META-INF/ghitags.tld

or:

    META-INF/abc/taglib.tld
    META-INF/def/taglib.tld
    META-INF/ghi/taglib.tld

In each TLD file, there is a `<uri>` element under the root `<taglib>` element. Use this feature as follows:

- The `<uri>` element must specify a value that is to be matched by the `uri` setting of a `taglib` directive in any JSP page that wants to use the corresponding tag library.

- To avoid unintended results, each `<uri>` value should be unique across all `<uri>` values in all TLD files on the server.

The value of the `<uri>` element can be arbitrary. It is simply used as a key and does not indicate a physical location. By convention, however, its value is of the form of a physical location, such as in the following example:

    <uri>http://www.mycompany.com/j2ee/jsp/tld/myproduct/mytags.tld</uri>

A `<uri>` value must follow the XML namespace convention.

A JAR file with multiple TLD files must be placed in the `/WEB-INF/lib` directory or in an OC4J "well-known" tag library location as described in "Oracle Extensions for Tag Library Sharing and Persistent TLD Caching". During translation, the JSP container searches these two locations for JAR files, searches each JAR file for TLD files, and accesses each TLD file to find its `<uri>` element.

Notes: A `<uri>` element and the corresponding `taglib` directive can specify a "shortcut" URI setting. This corresponds to settings in the `web.xml` file, as "Use of web.xml for Tag Libraries" explains. A JSP 1.2-compliant container, such as the OC4J JSP container, supports the multiple TLD file packaging mechanism for JSP 1.1 TLD files as well as JSP 1.2 TLD files.

#### Example: URI Settings for Multiple Tag Libraries in a JAR File

Consider a JAR file, `myapptags.jar`, that includes the following TLD files:

    META-INF/mytaglib1.tld
    META-INF/mytaglib2.tld

Assume that `mytaglib1.tld` specifies the following:

    <taglib>
       <tlib-version>1.0</tlib-version>
       <jsp-version>1.2</jsp-version>
       <short-name>shorty</short-name>
       <uri>http://www.foo.com/jsp/mytaglib1</uri>
       <description>example TLD</description>
       <tag>
          <name>mytag1</name>
          ...
       </tag>
       ...
    </taglib>

To use `mytag1` or any other tag defined in `mytaglib1.tld`, a JSP page could have the following `taglib` directive:

    <%@ taglib uri="http://www.foo.com/jsp/mytaglib1" prefix="myprefix1" %>

URI values in this scenario (multiple tag libraries in a single JAR file) are used as keywords only. They can be arbitrary.

For a more complete example, see "Example: Multiple Tag Libraries and TLD Files in a JAR File".

### Use of w eb.xml for Tag Libraries

The Sun Microsystems Java Servlet Specification describes a standard deployment descriptor for servlets: the `web.xml` file. JSP pages can use this file in specifying the location or URI identifier of a JSP TLD file.

For JSP tag libraries, the `web.xml` file can include `<taglib>` elements and two subelements:

- `<taglib-uri>`

- `<taglib-location>`

For the scenario of an individual TLD file, or the scenario of a JAR file that contains a single tag library and its TLD file, the `<taglib-location>` subelement indicates the application-relative physical location (by starting with "`/`") of the TLD file or tag library JAR file. See "Specifying a Tag Library by Physical Location" for related information.

For the scenario of a JAR file that contains multiple tag libraries and their TLD files, a `<taglib-location>` subelement indicates the unique identifier of a tag library. In this case, the `<taglib-location>` value actually indicates a key, not a location, and corresponds to the `<uri>` value in the TLD file of the desired tag library. See "Packaging and Accessing Multiple Tag Libraries in a JAR File" for related information.

The `<taglib-uri>` subelement indicates a shortcut URI to use in `taglib` directives in your JSP pages, with this URI being mapped to the physical location or URI identifier specified in the accompanying `<taglib-location>` subelement.

Following is a sample `web.xml` entry for a TLD file:

    <taglib>
       <taglib-uri>/oracustomtags</taglib-uri>
       <taglib-location>/WEB-INF/oracustomtags/tlds/mytld.tld</taglib-location>
    </taglib>

This entry makes `/oracustomtags` equivalent to `/WEB-INF/oracustomtags/tlds/mytld.tld` in `taglib` directives in your JSP pages.

Given this example, the following directive in your JSP page results in the JSP container finding the `/oracustomtags` URI in `web.xml` and, therefore, finding the accompanying name and location of the TLD file (`mytld.tld`):

    <%@ taglib uri="/oracustomtags" prefix="oracust" %>

This statement enables you to use any of the tags of this custom tag library in a JSP page.

See the Sun Microsystems Java Servlet Specification and the Sun Microsystems JavaServer Pages Specification for more information about the `web.xml` deployment descriptor.

Important: Generally speaking, the `<taglib>` element in `web.xml` is required in the case of a TLD file that is located in a JSP "well-known" tag library location and has `<listener>` elements. This is the only way that the TLD file can be found and accessed in order to activate its listeners. This is not the case, however, if you use persistent TLD caching. See "Oracle Extensions for Tag Library Sharing and Persistent TLD Caching" and "Tag Library Event Listeners".

### Oracle Exten sions for Tag Library Sharing and Persistent TLD Caching

As an extension of standard JSP "well-known URI" functionality described in the JSP specification, the OC4J JSP container supports the use of one or more directories, known as well-known tag library locations, where you can place tag library JAR files to be shared across multiple Web applications.

There is also a persistent caching feature for TLD files, with a global cache for TLD files in any well-known tag library locations, as well as an application-level cache for any application that uses TLD caching.

The use of TLD caching speeds performance at application startup and during JSP page translation. You might typically turn it off, however, under either of the following circumstances:

- Your application does not use tag libraries.

or:

- You have pretranslated the JSP pages and none of the TLD files use `<listener>` elements for tag library event listeners. (See "Tag Library Event Listeners".)

The following sections provide additional information:

- TLD Caching and Well-Known Tag Library Locations

- TLD Cache Features and Files

#### TLD Caching and Well-Known Tag Library Locations

TLD caching is enabled or disabled through the `jsp-cache-tlds` attribute of the `<orion-web-app>` element, at a global level through this attribute in the `global-web-application.xml` file, or at an application level through this attribute in the application `orion-web.xml` file.

By default, TLD caching is enabled at a global level through the default setting `jsp-cache-tlds="true"` in `global-web-application.xml`. This is also the default setting in the `orion-web.xml` file of each application, but you can disable TLD caching for any particular application with a setting of `jsp-cache-tlds="false"` in `orion-web.xml`. This overrides the global setting.

Alternatively, you can disable TLD caching at a global level with a "`false`" setting in `global-web-application.xml`, then optionally enable TLD caching for any particular application with a "`true`" setting in `orion-web.xml`.

A setting of "`standard`" searches for TLD files only in `/WEB-INF` or subdirectories other than `/WEB-INF/classes` or `/WEB-INF/lib`. The "`true`" setting, by contrast, searches all application files for TLD files.

Note: By default, `orion-web.xml` inherits its `jsp-cache-tlds` setting from `global-web-application.xml`.

If TLD caching is enabled, you can specify one or more well-known tag library locations using a semicolon-delimited list of directory paths in the `jsp-taglib-locations` attribute of the `<orion-web-app>` element in `global-web-application.xml`. See "OC4J Configuration Parameters for JSP" for additional information about this attribute.

Important: Use the `jsp-taglib-locations` attribute only in `global-web-application.xml`, not in `orion-web.xml`.

If TLD caching is disabled, the well-known tag library location is limited to a single directory, using functionality that existed prior to the availability of TLD caching. In this case, the well-known location is determined by the `well_known_taglib_loc` JSP configuration parameter. See "JSP Configuration Parameters" for additional information about this parameter.

In an Oracle Application Server environment, the default well-known location is `ORACLE_HOME``/j2ee/home/jsp/lib/taglib` (assuming `ORACLE_HOME` is defined).

Important: For any application to pick up files in the well-known location or locations, the directory or directories that are specified in `jsp-taglib-locations` or the directory that is specified in `well_known_taglib_loc` must be added to the `path` attribute setting of the `<library>` element in the OC4J global `application.xml` file in the configuration files directory (`j2ee/home/config` by default in OC4J standalone). See the Oracle Application Server Containers for J2EE User's Guide for information about `application.xml`. If a TLD file is present both in the well-known location and under the `/WEB-INF` directory of an application, the `/WEB-INF` copy takes precedence and is used. If TLD files with the same URI value are present in or under the `/WEB-INF` directory and also in a JAR file in the `/WEB-INF/lib` directory, the decision of which one to use is indeterminate. Avoid this situation.

#### TLD Cache Features and Files

For any application that uses TLD caching, whether it is enabled at the global level or at the application level, there are two levels of caching, and two aspects of caching at each level.

Caching levels:

- There is a global cache for TLD files that are in JAR files in any well-known tag library locations.

- There is an application-level cache for TLD files under the application `/WEB-INF` directory.

  At the application level, tag library JAR files, which include TLD files, must be in the `/WEB-INF/lib` directory. Individual TLD files can be directly in `/WEB-INF` or in any subdirectory, but preferably not in `/WEB-INF/lib` or `/WEB-INF/classes`.

Caching aspects at each level:

- There is a file containing resource information for the relevant location—the well-known location for the global cache, or `/WEB-INF` or `/WEB-INF/lib` for the application-level cache. Because of this feature, JAR files do not have to be scanned more than once. The file contains two types of entries:

  - There is a list of all resources (tag library JAR files) that includes a timestamp for each resource so that any change to any resource can be detected. There is also an indication ("`true`" or "`false`") of whether each resource includes a TLD file.

  - There is a list of TLD files, where each entry consists of a TLD name, TLD URI value if present, and tag library listeners if present. (See "Tag Library Event Listeners".)

- There is a serialized DOM representation of each TLD file. Because of this feature, TLD files do not have to be parsed more than once.

The global cache is always located in a directory called `tldcache`, parallel to the configuration directory. The `tldcache` directory contains the following:

- There is a file, `_GlobalTldCache`, that contains resource information, as described above, for any well-known locations.

- There are DOM representations of the TLD files that are in well-known locations. For each TLD file that is in a JAR file in a well-known location, the DOM representation is in a subdirectory according to the name of the JAR file, with a file name according to the name of the TLD file. For example, if `email.tld` is found in `ojsputil.jar` in a well-known location, then its DOM representation would be in the following file (file name `email` in directory `ojsputil_jar`):

      ORACLE_HOME/j2ee/home/jsp/lib/taglib/persistence/ojsputil_jar/email

  This is for an Oracle Application Server environment, where `ORACLE_HOME` is defined. In OC4J standalone, the `j2ee` directory is relative to where OC4J is installed.

The application-level cache is in the directory indicated by the `jsp-cache-directory` setting in either `global-web-application.xml` or `orion-web.xml`. (See "OC4J Configuration Parameters for JSP" for information about `jsp-cache-directory`.) This directory contains the following:

- There is a file, `_TldCache`, that contains resource information, as described above, for TLD files under the `/WEB-INF` directory—either in JAR files in `/WEB-INF/lib`, or individually in `/WEB-INF` or any subdirectory, but preferably not `/WEB-INF/lib` or `/WEB-INF/classes`.

- There are DOM representations of the TLD files under `/WEB-INF`. For TLD files that are in JAR files in the `/WEB-INF/lib` directory, the DOM representations go into subdirectories under the directory indicated by `jsp-cache-directory`, in the same type of scheme as described for the global cache. For individual TLD files under `/WEB-INF`, the DOM representations go directly in the `jsp-cache-directory` location.

  Notes: TLD changes at the global level are reflected only after OC4J is restarted. TLD changes at the application level are reflected immediately in an OC4J standalone environment, but only after the application is restarted in an Oracle Application Server environment. You can increase the OC4J verbosity level to see information regarding construction of TLD caches and regarding any TLD URIs that are duplicated. Level 4 provides some information; level 5 provides additional information. You can use Oracle Enterprise Manager 10g to set the verbosity level. The default level is 3.

### Example: Multiple Tag Libraries and TLD Files in a JAR File

This section presents an example of tag library packaging. This is a situation where multiple tag libraries are packaged in a single JAR file. The JAR file includes tag handler classes, tag-library-validator classes, and TLD files for multiple libraries. The following shows the contents and structure of the JAR file:

    examples/BasicTagParent.class
    examples/ExampleLoopTag.class
    examples/BasicTagChild.class
    examples/BasicTagTLV.class
    examples/TagElemFilter.class
    examples/XMLViewTagTLV.class
    examples/TagFilter.class
    examples/XMLViewTag.class
    META-INF/xmlview.tld
    META-INF/exampletag.tld
    META-INF/basic.tld
    META-INF/MANIFEST.MF

#### Key TLD File Entries for Multiple-Library Example

This section illustrates the `<uri>` elements of the TLD files.

The `basic.tld` file includes the following:

    <taglib>

      <tlib-version>1.0</tlib-version>
      <jsp-version>1.2</jsp-version>
      <short-name>basic</short-name>
      <uri>http://xmlns.oracle.com/j2ee/jsp/tld/demos/basic.tld</uri>

      ...

    </taglib>

The `exampletag.tld` file includes the following:

    <taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">

      <tlib-version>1.0</tlib-version>
      <jsp-version>1.2</jsp-version>
      <short-name>example</short-name>
      <uri>http://xmlns.oracle.com/j2ee/jsp/tld/demos/exampletag.tld</uri>

      ...

    </taglib>

The `xmlview.tld` file includes the following:

    <taglib>

      <tlib-version>1.0</tlib-version>
      <jsp-version>1.2</jsp-version>
      <short-name>demo</short-name>
      <uri>http://xmlns.oracle.com/j2ee/jsp/tld/demos/xmlview.tld</uri>

      ...

    </taglib>

#### Key web.xml File Entries for Multiple-Library Example

This section shows the `<taglib>` elements of the `web.xml` deployment descriptor. These map the full URI values, as seen in the `<uri>` elements of the TLD files in the previous section, to shortcut URI values used in the JSP pages that access these libraries.

    ...
    <taglib>
      <taglib-uri>/oraloop</taglib-uri>
      <taglib-location>http://xmlns.oracle.com/j2ee/jsp/tld/demos/exampletag.tld
      </taglib-location>
    </taglib>
    <taglib>
      <taglib-uri>/orabasic</taglib-uri>
      <taglib-location>http://xmlns.oracle.com/j2ee/jsp/tld/demos/basic.tld
      </taglib-location>
    </taglib>
    <taglib>
      <taglib-uri>/oraxmlview</taglib-uri>
      <taglib-location>http://xmlns.oracle.com/j2ee/jsp/tld/demos/xmlview.tld
      </taglib-location>
    </taglib>
    ...

#### JSP Page taglib Directives for Multiple-Library Example

This section shows the appropriate `taglib` directives, which reference the shortcut URI values defined in the `web.xml` elements listed in the preceding section.

The page `basic1.jsp` includes the following directive:

    <%@ taglib prefix="basic" uri="/orabasic" %>

The page `exampletag.jsp` includes the following directive:

    <%@ taglib prefix="example" uri="/oraloop" %>

The page `xmlview.jsp` includes the following directive:

    <%@ taglib prefix="demo" uri="/oraxmlview" %>

## Tag Handlers

The following sections describe tag handlers, which define the semantics of actions that result from the use of custom tags:

- Overview of Tag Handlers

- Attribute Handling, Conversions from String Values

- Custom Tag Processing, with or without Tag Bodies

- Summary of Integer Constants for Body Processing

- Simple Tag Handlers without Iteration

- Simple Tag Handlers with Iteration

- Tag Handlers That Access Body Content

- TryCatchFinally Interface

- Access to Outer Tag Handler Instances

### Overview of Tag Handlers

A tag handler is an instance of a Java class that directly or indirectly implements the standard `javax.servlet.jsp.tagext.Tag` interface. Depending on whether there is a tag body and how that body is to be processed, the tag handler implements one of the following interfaces, in the `javax.servlet.jsp.tagext` package:

- `Tag`: This interface defines the basic methods for all tag processing, but does not include tag body processing.

- `IterationTag`: This interface extends `Tag` and is for iterating through a tag body.

- `BodyTag`: This interface extends `IterationTag` and is for accessing the tag body content itself.

A tag handler class might implement one of these interfaces directly, or might extend a class (such as one of the support classes provided by Sun Microsystems) that implements one of them.

Each custom tag has its own handler class. By convention, the name of the tag handler class for a tag `abc`, for example, is `AbcTag`.

The TLD file of a tag library specifies the name of the tag handler class for each tag in the library. See "Tag Library Descriptor Files".

A tag handler instance is typically created by the JSP page implementation instance, by use of a zero-argument constructor, and is a server-side object used at request-time. The tag handler has properties that are set by the JSP container, including the page context object for the JSP page that uses the custom tag, and a parent tag handler object if the use of this tag is nested within an outer tag. A tag handler, as applicable, supports parameter-passing, evaluation of the tag body, and access to other objects in the JSP page, including other tag handlers.

"Example: Using the IterationTag Interface and a Tag-Extra-Info Class" includes code for a sample tag handler class.

Note: The JSP specification does not mandate whether multiple uses of the same custom tag within a JSP page should use the same tag handler instance or different instances. This is left to the discretion of JSP vendors. See "OC4J JSP Tag Handler Features" for information about the Oracle implementation.

### Attribute Handling, Conversions from String Values

A tag handler class has an underlying property for each attribute of the custom tag. These properties are somewhat like JavaBean properties, with at least a setter method.

Recall that there are two approaches in setting a tag attribute:

- The first approach is where the attribute is a non-request-time attribute, set using a string literal value:

      nrtattr="string"

  For a non-request-time attribute, if the underlying tag handler property is not of type `String`, the JSP container will try to convert the string value to a value of the appropriate type.

  Because tag attributes correspond to bean-like properties, their processing, such as for these type conversions from string values, is similar to that of bean properties. See "Bean Property Conversions from String Values".

- The second approach is where the attribute is a request-time attribute that is set using a request-time expression:

      rtattr="<%=expression%>"

  For request-time attributes, there is no conversion. A request-time expression can be assigned to the attribute, and to its corresponding tag handler property, for any property type. This would apply to a tag attribute whose type is user-defined, for example.

### Custom Tag Processing, with or without Tag Bodies

A custom tag, as with a standard JSP tag, might or might not have a body. In the case of a custom tag, even when there is a body, its content might not have to be accessed by the tag handler.

There are four scenarios:

1. There is no body.

   In this case you need only a single tag, not a start-tag and end-tag. Following is a general example:

       <oracust:mytag attr1="...", attr2="..." />

   This is equivalent to the following, which is also permissible:

       <oracust:mytag attr1="...", attr2="..." ></oracust:abcdef>

   In this case, the tag handler should implement the `Tag` interface.

   The `<body-content>` setting for this tag in the TLD file should be `empty`.

2. There is a body; access of the body content by the tag handler is not required; the body is executed no more than once.

   In this case, there is a start-tag and an end-tag with a body of statements in between, but the tag handler does not process the body. Body statements are passed through for normal JSP processing only. Following is a general example of this scenario:

       <foo:if cond="<%= ... %>" >
       ...body executed if cond is true, but body content not accessed by tag handler...
       </foo:if>

   In this case, the tag handler should implement the `Tag` interface.

   The `<body-content>` setting for this tag in the TLD file should be `JSP` (the default) or `tagdependent`, depending on whether the body content should be translated or treated as template data, respectively.

3. There is a body; access of the body content by the tag handler is not required; the body is executed multiple times (iterated).

   This is the same as the second scenario, except there is iterative processing of the tag body.

       <foo:myiteratetag ... >
       ...body executed multiple times, according to attribute or other settings,
       but body content not accessed by tag handler...
       </foo:myiteratetag>

   In this case, the tag handler should implement the `IterationTag` interface.

   The `<body-content>` setting for this tag in the TLD file should be `JSP` (the default) or `tagdependent`, depending on whether the body content should be translated or treated as template data, respectively.

4. There is a body that must be processed by the tag handler.

   Again, there is a start-tag and an end-tag with a body of statements in between; however, the tag handler must access the body content.

       <oracust:mybodytag attr1="...", attr2="..." >
       ...body accessed and processed by tag handler...
       </oracust:mybodytag>

   In this case, the tag handler should implement the `BodyTag` interface.

   The `<body-content>` setting for this tag in the TLD file should be `JSP` (the default) or `tagdependent`, depending on whether the body content should be translated or treated as template data, respectively.

   No tes: In the first scenario, where there is no body, the action is known as an empty action. In the second, third, and fourth scenarios, where there is a body, the action is known as a non-empty action. In the first, second, and third scenarios, where no body content processing is required by the tag handler, the handler is known as a simple tag handler. For additional information about the `<body-content>` element, see "Use of the tag Element".

### Summary of Integer Constants for Body Processing

The tag handler interfaces that are described in the following sections specify methods that you must implement, as applicable, to return appropriate `int` constants, depending on the situation.

The possible return values from the `doStartTag()` method, which is defined in the `Tag` interface and inherited by the `IterationTag` and `BodyTag` interfaces, are as follows:

- `SKIP_BODY`: Use this value if there is no body or if evaluation of the body should be skipped.

- `EVAL_BODY_INCLUDE`: Use this value to evaluate the body and pass it through to the current JSP `out` object. There is no special processing of the body content; no body content object is created.

- `EVAL_BODY_BUFFERED` (for `BodyTag` classes only): Use this value to create a `BodyContent` object for the content of the tag body, used for evaluation and processing of the content.

- `EVAL_BODY_TAG`: This is deprecated (formerly used if there is a body that requires special processing by the tag handler). Use `EVAL_BODY_AGAIN` or `EVAL_BODY_BUFFERED`, which both have the same `int` value as `EVAL_BODY_TAG`.

The possible return values from the `doAfterBody()` method, defined in the `IterationTag` interface and inherited by the `BodyTag` interface, are as follows:

- `SKIP_BODY`: Use this value to skip evaluation of the body or, when iterating through the body, to stop iterating.

- `EVAL_BODY_AGAIN`: Use this value to continue iterating through the body.

The possible return values from the `doEndTag()` method, defined in the `Tag` interface and inherited by the `IterationTag` and `BodyTag` interfaces, are as follows:

- `SKIP_PAGE`: Use this value to skip the rest of the page after the tag. This completes the request.

- `EVAL_PAGE`: Use this value to evaluate the remainder of the page after the tag.

### Simple Tag Ha ndlers without Iteration

For a custom tag that does not have a body, or has a body whose content does not require access and special processing by the tag handler, the tag handler is referred to as a simple tag handler. The tag handler class can implement the following standard interface:

- `javax.servlet.jsp.tagext.Tag`

However, if there is a tag body that is to be iterated, then the tag handler should implement the `IterationTag` interface instead. See "Simple Tag Handlers with Iteration".

The standard `javax.servlet.jsp.tagext.TagSupport` class implements the `Tag` interface, but also implements the `IterationTag` interface. Because of this, it is inefficient to use the `TagSupport` class for a tag that does not iterate through the tag body. This is especially important to consider when migrating code from a JSP 1.1 environment to a JSP 1.2 environment, in case you created tag handlers that extended `TagSupport` under JSP 1.1. For simple tag handlers not requiring body iteration, it is best to implement the `Tag` interface from scratch.

The `Tag` interface defines methods for the following key functions:

- Set up the JSP page context object (`pageContext` property).

- Set or get the parent tag handler—the handler for the closest enclosing tag, if applicable (`parent` property).

- Set up the tag attributes.

- Conditionally process the tag body, as appropriate, according to the return value of the `doStartTag()` method. (See immediately following.)

- Conditionally process the remainder of the JSP page after the tag, as appropriate, according to the return value of the `doEndTag()` method. (See immediately following.)

- Release state information.

For complete information, see the Sun Microsystems `Tag` interface Javadoc at:

    http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/jsp/tagext/Tag.html

In particular, the `Tag` interface specifies the following key methods:

- `doStartTag()`

- `doEndTag()`

The tag developer provides code for these methods in the tag handler class, as appropriate, to be executed as the start-tag and end-tag, respectively, are encountered. The JSP page implementation class generated by the JSP translator includes appropriate calls to these methods.

Implement action processing—whatever you want the action tag to accomplish—in the `doStartTag()` method. The `doEndTag()` method implements any appropriate post-processing. In the case of a tag without a body, essentially nothing happens between the execution of these two methods.

The `Tag` interface also specifies getter and setter methods for the `pageContext` and `parent` properties. The JSP page implementation instance invokes the `setPageContext()` and `setParent()` methods before invoking the `doStartTag()` and `doEndTag()` methods.

The `doStartTag()` method returns an `int` value. For a tag handler class implementing the `Tag` interface, this value is one of the following:

- `SKIP_BODY`: Do not evaluate the body, if any. This is the only option if the TLD file specifies a `<body-content>` setting of `empty` for the tag associated with this handler.

- `EVAL_BODY_INCLUDE`: Evaluate the body and pass it through to the current JSP `out` object.

The `doEndTag()` method also returns an `int` value, one of the following:

- `SKIP_PAGE`: Skip the rest of the page after the tag. If the request was originally from another page, from which the current page was forwarded to or included, only the remainder of the current page evaluation is skipped.

- `EVAL_PAGE`: Evaluate the remainder of the page after the tag.

### Simple Tag Ha ndlers with Iteration

For a custom tag that has a body that does not require access and special processing by the tag handler, but does require repeated reevaluation such as for iteration, the tag handler class can implement the following standard interface:

- `javax.servlet.jsp.tagext.IterationTag`

The `IterationTag` interface extends the `Tag` interface. A class that implements the `IterationTag` interface is still known as a simple tag handler.

The following standard support class implements the `IterationTag` interface, as well as the `java.io.Serializable` interface, and can be used as a base class:

- `javax.servlet.jsp.tagext.TagSupport`

In addition to implementing appropriate methods from the `Tag` and `IterationTag` interfaces, the `TagSupport` class includes a convenience method, `findAncestorWithClass()`, that calls the `getParent()` method defined in the `Tag` interface.

Note: It is not advisable to extend the `TagSupport` class if your tag handler does not have to support body iteration. Because `TagSupport` implements the `IterationTag` interface, there is looping logic that would be unnecessary. In addition to being generally inefficient, this increases the likelihood of methods exceeding a Java 64K size limit.

The `IterationTag` interface inherits basic tag-handling functionality, including the `doStartTag()` and `doEndTag()` methods, from the `Tag` interface. See "Simple Tag Handlers without Iteration".

The `IterationTag` interface also defines the following additional key method:

- `doAfterBody()`

This method is called after each evaluation of the tag body, to see if the body should be evaluated again. It returns one of the following `int` values:

- `SKIP_BODY`: Stop iterating; do not reevaluate the tag body. Call `doEndTag()` instead. The `SKIP_BODY` setting is also used when the body is not to be evaluated in the first place, and is the only option if the TLD file specifies a `<body-content>` setting of `empty` for the tag associated with this handler.

- `EVAL_BODY_AGAIN`: Continue iterating; reevaluate the tag body. After the body is evaluated, the `doAfterBody()` method is called again.

Notes: In the JSP 1.1 specification, the `doAfterBody()` method was defined in the `BodyTag` interface. Moving this method definition to the `IterationTag` interface, beginning with the JSP 1.2 specification, allows a simple iteration tag handler to avoid the overhead of maintaining a `BodyContent` object. For a complete example of `IterationTag` usage, see "Example: Using the IterationTag Interface".

### Tag Handlers That Access Body Content

For a custom tag with body content that the tag handler must be able to access, the tag handler class can implement the following standard interface:

- `javax.servlet.jsp.tagext.BodyTag`

The following standard support class implements the `BodyTag` interface, as well as the `java.io.Serializable` interface, and can be used as a base class:

- `javax.servlet.jsp.tagext.BodyTagSupport`

This class implements appropriate methods from the `Tag`, `IterationTag`, and `BodyTag` interfaces.

Note: Do not use the `BodyTag` interface (or `BodyTagSupport` class) if your tag handler does not actually require access to the body content. This would result in the needless overhead of creating and maintaining a `BodyContent` object. Depending on whether iteration through the body is required, use the `Tag` interface or the `IterationTag` interface (or `TagSupport` class) instead.

#### BodyTag Features

The `BodyTag` interface inherits basic tag-handling functionality from the `Tag` interface, including the `doStartTag()` and `doEndTag()` methods and their defined return values. It also inherits functionality from the `IterationTag` interface, including the `doAfterBody()` method and its defined return values. See "Simple Tag Handlers without Iteration" and "Simple Tag Handlers with Iteration".

Along with its inherited features, the `BodyTag` interface adds functionality to capture execution results from the tag body. Evaluation of a tag body is encapsulated in an instance of the `javax.servlet.jsp.tagext.BodyContent` class. The page implementation object creates this instance as appropriate. See "BodyContent Objects".

As with the `Tag` interface, the `doStartTag()` method specified in the `BodyTag` interface supports `int` return values of `SKIP_BODY` and `EVAL_BODY_INCLUDE`. For `BodyTag`, this method also supports an `int` return value of `EVAL_BODY_BUFFERED`. To summarize the meanings:

- `SKIP_BODY`: Do not evaluate the body.

- `EVAL_BODY_INCLUDE`: Evaluate the body and pass it through to the JSP `out` object without the body content being made available to the tag handler. This is essentially the same behavior as in an `EVAL_BODY_INCLUDE` scenario with a tag handler that implements the `IterationTag` interface.

- `EVAL_BODY_BUFFERED`: Create a `BodyContent` object for processing of the tag body content.

The `BodyTag` interface also adds definitions for the following methods:

- `setBodyContent()`: Set the `bodyContent` property (a `BodyContent` instance) of the tag handler.

- `doInitBody()`: Prepare to evaluate the tag body.

If the `doStartTag()` method returns `EVAL_BODY_BUFFERED`, the JSP page implementation instance executes the following steps, in order:

1. It creates a `BodyContent` instance.

2. It calls the `setBodyContent()` method of the tag handler, to pass the `BodyContent` instance to the tag handler.

3. It calls the `doInitBody()` method of the tag handler to perform initialization, if any, related to the `BodyContent` instance.

These steps occur before the tag body is evaluated. While the body is evaluated, the JSP `out` object will be bound to the `BodyContent` object.

After each evaluation of the body, as for tag handlers implementing the `IterationTag` interface, the page implementation instance calls the tag handler `doAfterBody()` method. This involves the following possible return values:

- `SKIP_BODY`: Stop iterating; do not reevaluate the tag body. Call `doEndTag()` instead. The JSP `out` object is restored from the page context.

- `EVAL_BODY_AGAIN`: Continue iterating; reevaluate the tag body. When the body is evaluated, it is passed through to the current JSP `out` object. After the body is evaluated, the `doAfterBody()` method is called again.

Once evaluation of the body is complete, for however many iterations are appropriate, the page implementation instance invokes the tag handler `doEndTag()` method.

#### BodyContent Objects

For tag handlers implementing the `BodyTag` interface, evaluation results from the tag body are made accessible to the tag handler through an instance of the `javax.servlet.jsp.tagext.BodyContent` class. This class extends the `javax.servlet.jsp.JspWriter` class.

A `BodyContent` instance is created through the `pushBody()` method of the JSP page context.

The `BodyContent` class, in addition to inheriting `JspWriter` features, adds methods to accomplish the following:

- Return its contents as a `java.io.Reader` object (`getReader()` method).

- Write its contents into a `java.io.Writer` object (`writeOut()` method).

- Convert its contents into a `String` object (`getString()` method).

- Clear its contents (`clearBody()` method).

Typical uses for a `BodyContent` object include the following:

- Convert its contents into a `String` instance and then use the string as a value for an operation.

- Write its contents into the JSP `out` object that was active as of when the start-tag was encountered.

### TryCatchFinally Interface

For data integrity and resource management when exceptions occur during tag processing, the JSP 1.2 specification introduced the `javax.servlet.jsp.tagext.TryCatchFinally` interface. Implementing this interface in your tag handlers is particularly useful for tags that must handle errors and for ensuring the proper release of resources.

The `TryCatchFinally` interface specifies the following methods:

- `void doCatch(java.lang.Throwable throw)`

  This method can be invoked on a tag handler when a `Throwable` error occurs during evaluation of a tag body or during a call to the `doStartTag()`, `doEndTag()`, `doAfterBody()`, or `doInitBody()` method. The `Throwable` object that was encountered is taken as input by the `doCatch()` method. This method would not be invoked if the `Throwable` error occurs during a call to a setter method.

  The `doCatch()` method can throw an exception (the original `Throwable` exception or a new exception) to be propagated through an error chain.

- `void doFinally()`

  This method is invoked regardless of whether a `Throwable` error, as discussed for the `doCatch()` method, occurs. It would not be invoked, however, if a `Throwable` error occurs during a call to a setter method.

  The `doFinally()` method should not throw an exception.

Following is a typical `TryCatchFinally` invocation (from the Sun Microsystems JavaServer Pages Specification, Version 1.2):

     h = get a Tag();  // get a tag handler, perhaps from pool

     h.setPageContext(pc);  // initialize as desired
     h.setParent(null);
     h.setFoo("foo");

     // tag invocation protocol; see Tag.java
     try {
       h.doStartTag()...
       ....
       h.doEndTag()...
     } catch (Throwable t) {
       /* React to exceptional condition; invoked if exception occurs between
          doStartTag() and doEndTag(). */
       h.doCatch(t);
     } finally {
       // restore data invariants and release pre-invocation resources
       h.doFinally();
       /* doFinally() is almost always called, unless Throwable error occurs
          during setter method, or Java thread terminates. */
     }

### Access to Outer Tag Handler Instances

Where nested custom tags are used, the tag handler instance of the nested tag has access to the tag handler instance of the outer tag, which might be useful in any processing and state management performed by the nested tag.

This functionality is supported through the static `findAncestorWithClass()` method of the `javax.servlet.jsp.tagext.TagSupport` class. Even though the outer tag handler instance is not named in the JSP page context, it is accessible because it is the closest enclosing instance of a given tag handler class.

Consider the following JSP code example:

    <foo:bar1 attr="abc" >
       <foo:bar2 />
    </foo:bar1>

Within the code of the `bar2` tag handler class (class `Bar2Tag`, by convention), you can have a statement such as the following:

    Tag bar1tag = TagSupport.findAncestorWithClass(this, Bar1Tag.class);

The `findAncestorWithClass()` method takes the following as input:

- The `this` object that is the class handler instance from which `findAncestorWithClass()` was called (a `Bar2Tag` instance in the example)

- The name of the `bar1` tag handler class (presumed to be `Bar1Tag` in the example), as a `java.lang.Class` instance

The `findAncestorWithClass()` method returns an instance of the appropriate tag handler class, in this case `Bar1Tag`, as a `javax.servlet.jsp.tagext.Tag` instance.

It is useful for a `Bar2Tag` instance to have access to the outer `Bar1Tag` instance in case the `Bar2Tag` needs the value of a `bar1` tag attribute or needs to call a method on the `Bar1Tag` instance.

## OC4J JSP Tag Handler Features

This section describes OC4J JSP extended features for tag handler pooling and code generation size reduction. It covers the following topics:

- Disabling or Enabling Runtime or Compile-Time Tag Handler Reuse

- Tag Handler Code Generation

### Disabling or Enabling Runtime or Compile-Time Tag Handler Reuse

To improve performance, you can specify that tag handler instances be reused within each JSP page. This is sometimes referred to as tag handler instance pooling. As of Oracle Application Server 10g Release 2 (10.1.2), there are two models for this:

- Runtime model: The logic and patterns of tag handler reuse is determined at runtime, during execution of the JSP pages. Tag handler reuse is within `application` scope.

- Compile-time model: The logic and patterns of tag handler reuse is determined at compile-time, during translation of the JSP pages. This is an effective way to improve performance for an application with very large numbers of tags within the same page (hundreds of tags, for example).

The JSP `tags_reuse_default` configuration parameter is relevant in either case. See "JSP Configuration Parameters" for further information about this parameter and how to set it.

#### Key Points Regarding Tag Handler Reuse

Be aware of the following points about tag handler reuse:

- In the current implementation, the default `tags_reuse_default` setting is `runtime`, for use of the runtime model.

- If you switch from the runtime model (`tags_reuse_default` value of `runtime`) to the compile-time model (`tags_reuse_default` value of `compiletime` or `compiletime_with_release`), or from the compile-time model to the runtime model, you must retranslate the JSP pages.

- The JSP container also supports tag handler reuse in a servlet 2.0 environment. In that environment, the default `tags_reuse_default` setting is `none`, for no tag handler reuse.

- Any given tag handler instance processes only one request at a time.

#### Enabling or Disabling the Runtime Model for Tag Handler Reuse

The runtime model can be enabled in either of two ways:

- Use the default `tags_reuse_default` value of `runtime`. (For backward compatibility, a setting of `true` is also supported and is equivalent to `runtime`.)

or:

- If `tags_reuse_default` has a value of `none`, you can override this in any particular JSP page by setting the `oracle.jsp.tags.reuse` attribute in the JSP page context to `true`. For example:

      pageContext.setAttribute("oracle.jsp.tags.reuse", new Boolean(true));

You can also disable the runtime model in either of two ways:

- Set `tags_reuse_default` to a value of `none`. This also disables the compile-time model. (For backward compatibility, a setting of `false` is also supported and is equivalent to `none`.)

or:

- If `tags_reuse_default` has a value of `runtime`, you can override this in any particular JSP page by setting the `oracle.jsp.tags.reuse` attribute in the JSP page context to `false`. For example:

      pageContext.setAttribute("oracle.jsp.tags.reuse", new Boolean(false));

  Notes: Remember to retranslate your JSP pages when switching from the compile-time model to the runtime model for tag handler reuse. You can use separate `oracle.jsp.tags.reuse` settings in different pages, or even in different sections of the same page. The `oracle.jsp.tags.reuse` attribute is ignored with a `tags_reuse_default` setting of `compiletime` or `compiletime_with_release`.

#### Enabling or Disabling the Compile-Time Model for Tag Handler Reuse

You can switch to the compile-time model for tag-handler reuse in one of two ways:

- Set the `tags_reuse_default` configuration parameter to `compiletime`.

or:

- Set the `tags_reuse_default` configuration parameter to `compiletime_with_release`.

A `compiletime_with_release` setting results in the tag handler `release()` method being called between uses of the same tag handler within the same page. This method releases state information, with details according to the tag handler implementation. If the tag handler is coded in such a way as to assume a release of state information between tag usages, for example, then a `compiletime_with_release` setting would be appropriate. If you are unsure about the implementation of the tag handler and about which compile-time setting to use, you might consider experimentation.

To disable the compile-time model, set `tags_reuse_default` to a value of `none`. This also disables the runtime model.

Notes: Remember to retranslate your JSP pages when switching from the runtime model to the compile-time model for tag handler reuse. The page context `oracle.jsp.tags.reuse` attribute is ignored with a `tags_reuse_default` setting of `compiletime` or `compiletime_with_release`.

### Tag Handler Code Generation

The Oracle JSP implementation reduces the code generation size for custom tag usage. In addition, there is a JSP configuration flag, `reduce_tag_code`, that you can set to `true` for even further size reduction.

Be aware, however, that when this flag is enabled, the code generation pattern does not maximize tag handler reuse. Although you can still improve performance by setting `tags_reuse_default` to `true` as described in "Disabling or Enabling Runtime or Compile-Time Tag Handler Reuse", the effect is not maximized when `reduce_tag_code` is also `true`.

See "JSP Configuration Parameters" for further information about these parameters and how to set them.

## Scripting Variables, Declarations, and Tag-Extra-Info Classes

A custom tag action can create one or more server-side objects, known as scripting variables, that are available for use by the tag itself or by other scripting elements, such as scriptlets and other tags. A scripting variable can be defined either through a `<variable>` element in the TLD file of the tag library, for elementary cases, or through a tag-extra-info class, for cases where the logic for the scripting variable is more complex.

This section covers the following topics:

- Using Scripting Variables

- Scripting Variable Scopes

- Variable Declaration Through TLD variable Elements

- Variable Declaration Through Tag-Extra-Info Classes

### Using Scripting Variables

Objects that are defined explicitly in a custom tag can be referenced in other actions through the JSP page context, using the object ID as a handle. Consider the following example:

    <oracust:foo id="myobj" attr1="..." attr2="..." />

This statement results in the object `myobj` being available to scripting elements in the page, according to the declared scope of `myobj`. (See "Scripting Variable Scopes".) The `id` attribute is a translation-time attribute. You can specify a variable in one of two ways:

- Provide a `<variable>` element for the variable in the TLD file, to specify the name and type of the variable along with additional information. See "Variable Declaration Through TLD variable Elements".

- Create a tag-extra-info class, to specify the name and type of the variable along with additional information and related logic. Specify the tag-extra-info class name in a `<tei-class>` element in the TLD file. See "Variable Declaration Through Tag-Extra-Info Classes".

Generally, the more convenient `<variable>` mechanism will suffice.

The JSP container enters `myobj` into the page context, where it can later be obtained by other tags or scripting elements using syntax such as the following:

    <oracust:bar ref="myobj" />

The `myobj` object is passed through the tag handler instances for the `foo` and `bar` tags. All that is required is knowledge of the name of the object (`myobj`).

Note: In the example, `id` and `ref` are merely sample attribute names; there are no special predefined semantics for these attribute names. It is up to the tag handler to define attribute names and create and retrieve objects in the page context.

### Scripting Variable Scopes

Specify the scope of a scripting variable in the `<variable>` element or tag-extra-info class of the tag that creates the variable. It can be one of the following `int` constants:

- `NESTED`: Use this setting for the scripting variable to be available between the start-tag and end-tag of the action that defines it.

- `AT_BEGIN`: Use this setting for the scripting variable to be available from the start-tag to the end of the page.

- `AT_END`: Use this setting for the scripting variable to be available from the end-tag to the end of the page

### Variable Declaration Through TLD va riable Elements

The JSP 1.1 specification mandated that use of a scripting variable for a custom tag requires the creation of a tag-extra-info (TEI) class. See "Variable Declaration Through Tag-Extra-Info Classes". The JSP 1.2 specification, however, introduced a simpler mechanism—a `<variable>` element in the TLD file where the associated tag is defined. This is sufficient for most cases, where logic related to the variable is simple enough to not require use of a TEI class.

The `<variable>` element is a subelement under the `<tag>` element that defines the tag that uses the variable.

You can specify the name of the variable in one of two ways:

- Use a `<name-given>` subelement under `<variable>` to specify the variable name directly.

or:

- Use a `<name-from-attribute>` subelement under `<variable>` to specify a tag attribute whose value, at translation-time, will specify the variable name.

Along with `<name-given>` and `<name-from-attribute>`, the `<variable>` element has the following subelements:

- The `<variable-class>` element specifies the class of the variable. The default is `java.lang.String`.

- The `<declare>` element specifies whether the variable is to be a newly declared variable, in which case the JSP translator will declare it. The default is `true`. If `false`, then the variable is assumed to have been declared earlier in the JSP page through a standard mechanism such as a `jsp:useBean` action, a JSP scriptlet, a JSP declaration, or some custom action.

- The `<scope>` element specifies the scope of the variable: `NESTED`, `AT_BEGIN`, or `AT_END`, as described in "Scripting Variable Scopes". The default is `NESTED`.

Here is an example that declares two scripting variables for a tag `myaction`. Note that details within the `<tag>` element that are not directly relevant to this discussion are omitted:

    <tag>
       <name>myaction</name>
       ...
       <attribute>
         <name>attr2</name>
         <required>true</required>
       </attribute>
       <variable>
          <name-given>foo_given</name-given>
          <declare>false</declare>
          <scope>AT_BEGIN</scope>
       </variable>
       <variable>
          <name-from-attribute>attr2</name-from-attribute>
          <variable-class>java.lang.Integer</variable-class>
       </variable>
    </tag>

The name of the first variable is hardcoded as `foo_given`. By default, it is of type `String`. It is not to be newly declared, so is assumed to exist already, and its scope is from the start-tag to the end of the page.

The name of the second variable is according to the setting of the required `attr2` attribute. It is of type `Integer`. By default, it is to be newly declared and its scope is `NESTED`, between the `myaction` start-tag and end-tag.

See "Tag Library Descriptor Files" for more information about related TLD syntax.

### Variable Declaration Through Tag-Ext ra-Info Classes

For a scripting variable with associated logic that is at least somewhat complicated, the use of a `<variable>` element in the TLD file to declare the variable might be insufficient. In this case, you can specify details regarding the scripting variable in a subclass of the `javax.servlet.jsp.tagext.TagExtraInfo` abstract class. This manual refers to such a subclass as a tag-extra-info class. Tag-extra-info classes support additional validation of tag attributes and provide additional information about scripting variables to the JSP runtime.

The JSP container uses tag-extra-info instances during translation. The TLD file specifies any tag-extra-info classes to use for scripting variables of a given tag. Use `<tei-class>` elements, as in the following example:

    <tag>
      <name>loop</name>
      <tag-class>examples.ExampleLoopTag</tag-class>
      <tei-class>examples.ExampleLoopTagTEI</tei-class>
      <body-content>JSP</body-content>
      <description>for loop</description>
      <attribute>
         ...
      </attribute>
      ...
    </tag>

The following are related classes, also in the `javax.servlet.jsp.tagext` package:

- `TagData`: An instance of this class contains translation-time attribute value information for a tag instance.

- `VariableInfo`: Each instance of this class contains information about a scripting variable that is declared, created, or modified by a tag at runtime.

- `TagInfo`: An instance of this class contains information about the relevant tag. The class is instantiated from the TLD file and is available only at translation time. `TagInfo` has methods such as `getTagName()`, `getTagClassName()`, `getBodyContent()`, `getDisplayName()`, and `getInfoString()`.

You can refer to the following location for further information:

    http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/jsp/tagext/package-summary.html

Note: It is uncommon to use `TagInfo` instances in a tag-extra-info implementation, although it might be useful if you want to map a single tag-extra-info class to multiple tag libraries and TLD files, for example.

The following methods of the `TagExtraInfo` class are related:

- `boolean isValid(TagData data)`

  The JSP translator calls this method for translation-time validation of the tag attributes, passing it a `TagData` instance.

- `VariableInfo[] getVariableInfo(TagData data)`

  The JSP translator calls this method during translation, passing it a `TagData` instance. This method returns an array of `VariableInfo` instances, with one instance for each scripting variable the tag creates.

- `void setTagInfo(TagInfo info)`

  Calling this method sets a `TagInfo` instance as an attribute of the tag-extra-info class. This method is typically called by the JSP container.

- `TagInfo getTagInfo()`

  Use this method to retrieve the `TagInfo` attribute of the tag-extra-info class, assuming the `TagInfo` attribute was previously set.

The tag-extra-info class constructs each `VariableInfo` instance with the following information regarding the scripting variable:

- Its name

- Its Java type (not a primitive type)

- A boolean value indicating whether the variable is to be newly declared, in which case the JSP translator will declare it

- Its scope

Important: As of the OC4J 10.1.2 implementation, you can have the `getVariableInfo()` method return either a fully qualified class name (FQCN) or a partially qualified class name (PQCN) for the Java type of the scripting variable. FQCNs were required in previous releases, and are still preferred to avoid confusion in case there are duplicate class names between packages. Primitive types are not supported.

See "Sample Tag-Extra-Info Class: ExampleLoopTagTEI.java" for sample code of a tag-extra-info class.

## Validation and Tag-Lib rary-Validator Classes

The JSP 1.2 specification introduced a feature to optionally associate a "validator" class with each tag library. These classes are referred to as tag-library-validator (TLV) classes. The purpose of a TLV class is to validate any JSP page that uses the tag library, verifying that the page adheres to any constraints that you wish to impose through your implementation of the TLV class. Although it is probably typical for a TLV class to check for constraints regarding use of the associated tag library only, there is no limitation. The TLV class can check any aspect of a JSP page.

A tag-library-validator class must be a subclass of the `javax.servlet.jsp.tagext.TagLibraryValidator` class.

The following sections discuss tag library validation and TLV classes:

- TLD validator Element

- Key TLV-Related Classes and the validation() Method

- TLV Processing

- Validation Mechanisms

### TLD validator Element

To specify a TLV class for a tag library, use a `<validator>` element in the TLD file. The `<validator>` element has the following subelements:

- The `<validator-class>` subelement specifies the TLV class name.

- The `<description>` subelement can be used to provide documentation about the TLV class.

- The `<init-param>` subelement and its own subelements—`<param-name>` and `<param-value>`—can be used to set initialization parameters for the TLV class. This is similar to how `<init-param>` subelements work within `<servlet>` elements in the application deployment descriptor (`web.xml`). There is also an optional `<description>` subelement under the `<init-param>` element.

The following `<validator>` element examples are from the Sun Microsystems JavaServer Pages Standard Tag Library, Version 1.0 specification.

#### Example 1

This is an example of a TLV class (`ScriptFreeTLV`) that can disallow JSP declarations, JSP scriptlets, JSP expressions, and runtime expressions according to the settings of its initialization parameters. In this case, JSP expressions and runtime expressions will be allowed, but not JSP declarations or JSP scriptlets.

    <validator>
       <validator-class>
          javax.servlet.jsp.jstl.tlv.ScriptFreeTLV
       </validator-class>
       <init-param>
          <param-name>allowDeclarations</param-name>
          <param-value>false</param-value>
       </init-param>
       <init-param>
          <param-name>allowScriptlets</param-name>
          <param-value>false</param-value>
       </init-param>
       <init-param>
          <param-name>allowExpressions</param-name>
          <param-value>true</param-value>
       </init-param>
       <init-param>
          <param-name>allowRTExpressions</param-name>
          <param-value>true</param-value>
       </init-param>
    </validator>

#### Example 2

This is an example of a TLV class (`PermittedTagLibsTLV`) that allows tag library usage only as specified in its initialization parameter. The use of the tag library with which the TLV class is associated is allowed implicitly. In addition, the TLV class allows the libraries specified in a list, with entries separated by white space, in its initialization parameter setting. In this case, it allows only the `core`, `xml`, `fmt`, and `sql` JSTL libraries.

    <validator>
       <validator-class>
          javax.servlet.jsp.jstl.tlv.PermittedTaglibsTLV
       </validator-class>
       <init-param>
          <param-name>permittedTaglibs</param-name>
          <param-value>
             http://java.sun.com/jstl/core
             http://java.sun.com/jstl/xml
             http://java.sun.com/jstl/fmt
             http://java.sun.com/jstl/sql
          </param-value>
       </init-param>
    </validator>

### Key TLV-Related Classes and the validation() Method

As the introduction mentions, a TLV class is a subclass of the `javax.servlet.jsp.tagext.TagLibraryValidator` class.

The following related classes are also in the `javax.servlet.jsp.tagext` package:

- `PageData`: An instance of this class is generated by the JSP translator and contains information corresponding to the XML view of the page being translated.

- `ValidationMessage`: An instance of this class contains an error message from a TLV instance, being returned through the TLV `validate()` method.

Here is the key method of a TLV class:

- `ValidationMessage[] validate (String prefix, String uri, PageData page)`

  The JSP container calls this method each time it encounters a `taglib` directive that points to a TLD file that has a `<validator>` element. The method takes as input the tag library prefix, the TLD URI, and the `PageData` object (XML view) of the page. If errors are encountered during validation, the `validate()` method returns an array of validation messages. Because the OC4J JSP container supports the optional `jsp:id` attribute, the `jsp:id` values are included in the validation messages.

  See the next section, "TLV Processing", for more information.

### TLV Processing

As each `taglib` directive is encountered in a JSP page during translation, the JSP container searches the associated TLD file for a `<validator>` element that specifies a TLV class. If one is found, the container executes the following steps during the translation. See the preceding section, "Key TLV-Related Classes and the validation() Method", for background information about classes and methods discussed here.

1. The TLV class is instantiated, with initialization parameter settings according to any `<init-param>` subelements of the `<validator>` element.

2. The XML view of the JSP page is exposed to the TLV instance. (See "Details of the JSP XML View".)

3. The `validate()` method of the TLV instance is called to validate the JSP page. (See the next section, "Validation Mechanisms".) If this method encounters any errors, it returns an array of `ValidationMessage` instances. If there are no errors, the method can return `null` or an empty `ValidationMessage[]` array.

   Note: The OC4J JSP container implements an optional JSP 1.2 feature for improved reporting of validation errors—the `jsp:id` attribute. See "The jsp:id Attribute for Error Reporting During Validation" for information.

4. Each time a custom tag belonging to this library (the library associated with the TLV class) is encountered, it is checked for a tag-extra-info class. If one is specified, then it is instantiated by the JSP container and its `isValid()` method is called to validate the attributes of the tag. The `isValid()` method returns `true` if this validation is successful, or `false` if not.

### Validation Mechanisms

The XML view of a JSP page cannot generally be validated against a DTD and does not include a `DOCTYPE` statement. There are various namespace-aware mechanisms that you can use for validation. One mechanism in particular is the W3C XML Schema language. Refer to the W3C Web site for information:

    http://www.w3.org/XML/

More elementary mechanisms might be suitable as well, such as simply verifying that only a certain set of elements are used in a JSP page, or that a certain set of elements are not used in a page.

## Tag Lib rary Event Listeners

The servlet specification describes the use of the following types of event listeners:

- Servlet context listener, implementing interface `javax.servlet.ServletContextListener`

- Servlet context attribute listener, implementing interface `javax.servlet.ServletContextAttributeListener`

- HTTP session listener, implementing interface `javax.servlet.http.HttpSessionListener`

- HTTP session attribute listener, implementing interface `javax.servlet.http.HttpSessionAttributeListener`

In servlet 2.3 functionality, you can specify event listeners in the application `web.xml` file. As a result of this, they are registered with the servlet container and notified of relevant state changes. Servlet context listeners, for example, are notified of changes in the application `ServletContext` object, such as application startup or shutdown. See the Oracle Application Server Containers for J2EE Servlet Developer's Guide for additional information about the event listeners.

The JSP 1.2 specification, for convenience in packaging and deploying tag libraries, introduced support for `<listener>` elements in TLD files. You can use these elements to specify event listeners, as an alternative to specifying them in the `web.xml` file. The following sections describe these features:

- TLD listener Element

- Activation of Tag Library Event Listeners

- Access of TLD Files for Event Listener Information

### TLD listener Element

In a TLD file, each `<listener>` element is at the top level underneath the root `<taglib>` element. The `<listener>` element has one subelement, the required `<listener-class>` element, which specifies the listener class to be instantiated. This would be a class that implements the `ServletContextListener`, `ServletContextAttributeListener`, `HttpSessionListener`, or `HttpSessionAttributeListener` interface.

Following is an example:

    <taglib>
    ...
       <listener>
          <listener-class>mypkg.MyServletContextListener</listener-class>
       </listener>
    ...
    </taglib>

### Activation of Tag Library Event Listeners

When an application starts, the servlet container will make a call to the JSP container to perform the following:

1. Find and access TLD files.

2. Read TLD files to find their `<listener>` elements.

3. Instantiate and register the listeners.

This is a convenient way to manage application-level and session-level resources that are associated with the usage of a particular tag library. The functionality is essentially the same as for servlet context listeners specified in the `web.xml` file.

Notes: For event listeners specified in TLD files, the order in which the listeners are registered is undefined, but they are all registered prior to application startup and they are all registered after listeners that are specified in the `web.xml` file. If a TLD file is present within the WAR file structure, it will be scanned for listeners, and any listeners will be registered, even if the associated tag library is not actually used in the application.

### Access of TLD Files for Event Listener Information

You must take certain standard measures to ensure that the JSP container can access TLD files to find their `<listener>` elements. For general information about TLD file location, accessibility, and packaging, see "Tag Library and TLD Setup and Access". That section includes information about OC4J well-known tag library locations.

Also, generally speaking, for any TLD in the well-known tag library directory, you must specify the tag library in a `<taglib>` element in the application `web.xml` file if you want the application to activate any listeners specified in the TLD file. Without this step, TLD files in the shared directory are not accessed to search for their `<listener>` elements. This is to protect against needless performance impact for any application that does not use a tag library that happens to be in the shared directory. The `<taglib>` element in `web.xml` is not required, however, if you are using persistent TLD caching (described in "Oracle Extensions for Tag Library Sharing and Persistent TLD Caching").

## End-to-End Custom Tag Examples

The following sections provide complete examples of custom tag usage, including sample JSP pages, tag handler classes, and tag library descriptor files:

- Example: Using the IterationTag Interface

- Example: Using the IterationTag Interface and a Tag-Extra-Info Class

Note: These examples are for illustrative purposes only and do not necessarily reflect the most realistic or efficient approaches.

### Example: Us ing the IterationTag Interface

This sample shows the use of a custom tag, `myIterator`, to make the current item in a collection available as a scripting variable. It defines a scripting variable through a `<variable>` element in the TLD file.

For complete information about this example, including unpacking and deploying it, refer to the following Oracle Technology Network Web site:

    http://www.oracle.com/technology/tech/java/oc4j/htdocs/how-to-jsp-iterationtag.html

(You must register for membership, but registration is free of charge.)

#### Sample JSP Page: exampleiterator.jsp

The following JSP page uses the `myIterator` tag:

    <%@ page contentType="text/html;charset=windows-1252"%>
    <HTML>
    <HEAD>
    <TITLE>
    JSP 1.2 IterationTag Sample
    </TITLE>
    </HEAD>
    <%@ taglib uri="/WEB-INF/exampleiterator.tld" prefix="it"%>
    <BODY>

    <% java.util.Vector vector = new java.util.Vector();
       vector.addElement("One");
       vector.addElement("Two");
       vector.addElement("Three");
       vector.addElement("Four");
       vector.addElement("Five");
    %>
      Collection to Iterate over is <%=vector%> ..... <p>

     <B>Iterating ...</B><br>
     <it:myIterator collection="<%= vector%>" >
          Item  <B><%= item%></B><br>
     </it:myIterator>
    </p>
    </BODY>
    </HTML>

#### Sample Tag Handler Class: MyIteratorTag.java

In this sample tag handler class, `MyIteratorTag`, the `doStartTag()` method checks whether the collection is null. If not, it retrieves the collection object. If the iterator contains at least one element, then `doStartTag()` makes the first item in the collection available as a page-scope object and returns `EVAL_BODY_INCLUDE`. This alerts the JSP container to add the contents of the tag body to the response object and to call the `doAfterBody()` method.

This class extends the tag handler support class `TagSupport`, which implements the `IterationTag` interface.

    package oracle.taglib;

    import java.util.*;
    import javax.servlet.jsp.*;
    import javax.servlet.jsp.tagext.*;

    /**
     * MyIteratorTag extends TagSupport. The TagSupport class in JSP 1.2 implements the IterationTag
     */

    public class MyIteratorTag extends TagSupport
    {
      private Iterator iterator;
      private Collection _collection;

      public void setCollection(Collection collection)
      {
            this._collection = collection;
      }

      public int doStartTag() throws JspTagException
      {
        if (_collection == null)
        {
          throw new JspTagException("No collection with name "
            + _collection
            + " found");
        }

        iterator = _collection.iterator();
        if (iterator.hasNext())
        {
          pageContext.setAttribute("item", iterator.next());
          return EVAL_BODY_INCLUDE;
        }
        else
        {
           return SKIP_BODY;
        }
      }

      public int doAfterBody()
      {

         if (iterator.hasNext())
         {
          pageContext.setAttribute("item", iterator.next());
          return EVAL_BODY_AGAIN;
         }
         else
         {
          return SKIP_BODY;
         }
      }

    }

#### Sample Tag Library Descriptor File: exampleiterator.tld

Here is a sample TLD file to define the `myIterator` tag. This example takes advantage of the JSP 1.2 feature allowing definition of scripting variables directly in TLD files through `<variable>` elements. This TLD file defines the scripting variable `item` of type `java.lang.Object`. (In a JSP 1.1 environment, this would require use of a tag-extra-info class.) The variable is to be newly declared.

The `myIterator` tag has an attribute `collection` to specify the collection. This attribute is required and can be set as a runtime expression. The tag also has a `<body-content>` value of `JSP`, which means the JSP translator should process and translate the body code.

For JSP 1.2 syntax, be sure to specify the JSP 1.2 tag library DTD path.

    <?xml version = '1.0' encoding = 'windows-1252'?>
    <!DOCTYPE taglib
            PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
            "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">

    <taglib>
       <tlib-version>1.0</tlib-version>
       <jsp-version>1.2</jsp-version>
       <short-name>iterate</short-name>
       <description>This tag lib implements new JSP 1.2 IterationTag
                    interface</description>
       <tag>
          <name>myIterator</name>
          <tag-class>oracle.taglib.MyIteratorTag</tag-class>
          <body-content>JSP</body-content>
          <attribute>
              <name>collection</name>
              <required>true</required>
              <rtexprvalue>true</rtexprvalue>
          </attribute>
          <variable>
            <name-given>item</name-given>
            <variable-class>java.lang.Object</variable-class>
            <declare>true</declare>
            <!-- default scope: nested -->
            <description>Scripting Variable item</description>
          </variable>
        </tag>
    </taglib>

### Example: Us ing the IterationTag Interface and a Tag-Extra-Info Class

This section provides an end-to-end example of the definition and use of a custom tag, `loop`, that is used to iterate through the tag body a specified number of times. It defines a scripting variable through a tag-extra-info class.

This example includes the following:

- JSP source code for a page that uses the tag

- Source code for the tag handler class

- Source code for the tag-extra-info class

- TLD file

Note: Sample code here uses extended datatypes in the `oracle.jsp.jml` package. For information, refer to the Oracle Application Server Containers for J2EE JSP Tag Libraries and Utilities Reference.

#### Sample JSP Page: exampletag.jsp

Following is a sample JSP page, `exampletag.jsp`, that uses the `loop` tag, specifying that the outer loop is to be executed five times and the inner loop three times:

    <%@ taglib uri="/WEB-INF/exampletag.tld" prefix="foo" %>
    <% int num=5; %>
    <br>
    <pre>
    <foo:loop index="i" count="<%=num%>">
    body1here: i expr: <%=i%>
               i property: <jsp:getProperty name="i" property="value" />
      <foo:loop index="j" count="3">
      body2here: j expr: <%=j%>
      i property: <jsp:getProperty name="i" property="value" />
      j property: <jsp:getProperty name="j" property="value" />
      </foo:loop>
    </foo:loop>
    </pre>

#### Sample Tag Handler Class: ExampleLoopTag.java

This section provides source code for the tag handler class, `ExampleLoopTag`. Note the following:

- The tag handler class extends the standard `TagSupport` class to implement the `IterationTag` interface.

- The `doStartTag()` method returns the integer constant `EVAL_BODY_INCLUDE` so that the tag body (essentially, the loop) is processed.

- After each pass through the loop, the `doAfterBody()` method increments the counter. It returns `EVAL_BODY_AGAIN` if there are more iterations left, and `SKIP_BODY` after the last iteration.

- This class does not define a `doEndTag()` method. The underlying implementation from `TagSupport` is used.

Here is the code:

    package examples;

    import javax.servlet.jsp.*;
    import javax.servlet.jsp.tagext.*;
    import java.util.Hashtable;
    import java.io.Writer;
    import java.io.IOException;
    import oracle.jsp.jml.JmlNumber;

    public class ExampleLoopTag
        extends TagSupport
    {

        String index;
        int count;
        int i;
        JmlNumber ib;

        public ExampleLoopTag() {
          resetAttr();
        }

        public void release() {
          resetAttr();
        }

        private void resetAttr() {
          index=null;
          count=0;
          i=0;
          ib=null;
        }

        public void setIndex(String index)
        {
          this.index=index;
        }
        public void setCount(String count)
        {
          this.count=Integer.parseInt(count);
        }

        public int doStartTag() throws JspException {
            ib=new JmlNumber();
            pageContext.setAttribute(index, ib);
            i++;
            ib.setValue(i);
            return EVAL_BODY_INCLUDE;
        }

        public int doAfterBody() throws JspException {
            if (i >= count) {
                return SKIP_BODY;
            } else
                pageContext.setAttribute(index, ib);
            i++;
            ib.setValue(i);
            return EVAL_BODY_AGAIN;
        }
    }

#### Sample Tag-Extra-Info Class: ExampleLoopTagTEI.java

This section provides the source code for the tag-extra-info class that describes the scripting variable used by the `loop` tag.

A `VariableInfo` instance is constructed that specifies the following for the variable:

- The variable name is according to the `index` attribute.

- The variable is of the type `oracle.jsp.jml.JmlNumber`, which you must specify as a fully qualified class name.

- The variable is to be newly declared (by the JSP translator).

- The variable scope is `NESTED`.

In addition, the tag-extra-info class has an `isValid()` method that determines whether the `count` attribute is valid. It must be an integer.

    package examples;

    import javax.servlet.jsp.tagext.*;

    public class ExampleLoopTagTEI extends TagExtraInfo {
        public VariableInfo[] getVariableInfo(TagData data) {
            return new VariableInfo[]
                {
                    new VariableInfo(data.getAttributeString("index"),
                                     "oracle.jsp.jml.JmlNumber",
                                     true,
                                     VariableInfo.NESTED)
                };
        }

        public boolean isValid(TagData data)
        {
          String countStr=data.getAttributeString("count");
          if (countStr!=null)   // for request-time case
          {
            try {
              int count=Integer.parseInt(countStr);
            }
            catch (NumberFormatException e)
            {
              return false;
            }
          }
          return true;
        }
    }

#### Sample Tag Library Descriptor File: exampletag.tld

This section presents the TLD file for the tag library. In this example, the library consists of only one tag, `loop`.

This TLD file follows JSP 1.2 syntax, specifying the following for the `loop` tag:

- The tag handler class is `examples.ExampleLoopTag`.

- The tag-extra-info class is `examples.ExampleLoopTagTEI`.

- The `body-content` specification is `JSP`. This means that the JSP translator should process and translate the body code.

- There are attributes `index` and `count`, both required. The `count` attribute can be a request-time JSP expression.

Here is the TLD file:

    <?xml version = '1.0' encoding = 'ISO-8859-1'?>
    <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
     "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
    <taglib>
      <tlib-version>1.0</tlib-version>
      <jsp-version>1.2</jsp-version>
      <short-name>simple</short-name>
      <description>
           A simple tab library for the examples
      </description>
      <!-- example tag -->
      <!-- for loop -->
      <tag>
        <name>loop</name>
        <tag-class>examples.ExampleLoopTag</tag-class>
        <tei-class>examples.ExampleLoopTagTEI</tei-class>
        <body-content>JSP</body-content>
        <description>for loop</description>
        <attribute>
            <name>index</name>
            <required>true</required>
        </attribute>
        <attribute>
            <name>count</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
      </tag>
    </taglib>

## Compile-Time Tags

Standard tag libraries, as described in the JSP specification, use a runtime support mechanism. They are typically portable, not requiring any particular JSP container.

It is also possible, however, for vendors to support custom tags through vendor-specific functionality in their JSP translators. Such tags are not portable to other containers.

It is generally advisable to develop standard, portable tags that use the runtime mechanism, but there might be scenarios where tags using a compile-time mechanism are appropriate, as this section discusses.

### General Compile-Time Versus Runtime Considerations

The JSP specification describes a runtime support mechanism for custom tag libraries. This mechanism, using an XML-style TLD file to specify the tags, is covered earlier in this chapter. Creating and using a tag library that adheres to this model generally assures that the library will be portable to any standard JSP environment.

There are, however, reasons to consider compile-time implementations:

- A compile-time implementation can produce more efficient code.

- A compile-time implementation allows the developer to catch errors during translation and compilation, instead of the user seeing them at runtime.

### JSP Compile-Time Versus Runtime JML Library

Important: The JML tag library is deprecated in the OC4J 10.1.2 implementation and will be desupported in future implementations.

OC4J provides a portable tag library called the JSP Markup Language (JML) library. This library uses the standard JSP 1.2 runtime mechanism.

However, the JML tags are also supported through a compile-time mechanism. This is because the tags were first introduced with JSP implementations that preceded the JSP 1.1 specification, which is when the runtime mechanism was introduced. The compile-time tags are still supported for backward compatibility.

The general advantages and disadvantages of compile-time implementations apply to the Oracle JML tag library as well. There might be situations where it is advantageous to use the compile-time JML implementation. There are also a few additional tags in that implementation, and some additional expression syntax that is supported.

The Oracle Application Server Containers for J2EE JSP Tag Libraries and Utilities Reference describes both the runtime version and the compile-time version of the JML library.