<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>TagSupport Class</title>
</head>

<body>
<div id="Description">
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr valign="top">
<td class="NAME"> TagSupport Class</td>
<td class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"></td>
</tr>
<tr>
<td class="usage" colspan="2">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Class name:</td>
</tr>
<tr>
<td colspan="2" class="description"><p>
<span class="LITERAL">javax.servlet.jsp.tagext.TagSupport</span>
</p></td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Extends:</td>
</tr>
<tr>
<td colspan="2" class="description"><p>
None
</p></td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Implements:</td>
</tr>
<tr>
<td colspan="2" class="description"><p>
<span class="LITERAL">Tag</span>, <span class="LITERAL">java.io.Serializable</span>
</p></td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Implemented by:</td>
</tr>
<tr>
<td colspan="2" class="description"><p>
Internal container-dependent class. Most containers use the reference implementation of the class (developed in the Apache Jakarta project).
</p></td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Description</td>
</tr>
<tr>
<td colspan="2" class="description"><p>
<span class="LITERAL">TagSupport</span> is a support class that provides default implementations for all <span class="LITERAL">Tag</span> interface methods. It's intended to be used as a superclass for tag handlers that do not need access to the body contents of the corresponding custom action elements.
</p></td>
</tr>
<tr>
<td colspan="2" class="CLEARSEPARATION">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="DESCRIPTIONTITLE">Example</td>
</tr>
<tr>
<td colspan="2" class="description"><p>
An example of a custom action that can be implemented as a simple tag handler (that is, just implementing the <span class="LITERAL">Tag</span> interface) is an action that adds a cookie to the HTTP response. Let's call this action <span class="LITERAL">&lt;ora:addCookie&gt;</span>. The tag handler class is called <span class="LITERAL">com.ora.jsp.tags.generic.AddCookieTag</span> and extends the <span class="LITERAL">TagSupport</span> class to inherit most of the <span class="LITERAL">Tag</span> interface method implementations:
</p>
<span class="PROGRAMLISTING"><pre>package com.ora.jsp.tags.generic;

import javax.servlet.http.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import com.ora.jsp.util.*;

public class AddCookieTag extends TagSupport {</pre></span>
<p>
The <span class="LITERAL">&lt;ora:addCookie&gt;</span> action has two mandatory attributes, <span class="LITERAL">name</span> and <span class="LITERAL">value</span>, and one optional attribute, <span class="LITERAL">maxAge</span>. Each attribute is represented by an instance variable and a standard property setter method:
</p>
<span class="PROGRAMLISTING"><pre>    private String name;
    private String value;
    private String maxAgeString;

    public void setName(String name) {
        this.name = name;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public void setMaxAge(String maxAgeString) {
        this.maxAgeString = maxAgeString;
    }</pre></span>
<p>
All setter methods set the corresponding instance variables.
</p>
<p>
The purpose of the custom action is to create a new <span class="LITERAL">javax.servlet.Cookie</span> object with the <span class="LITERAL">name</span>, <span class="LITERAL">value</span>, and <span class="LITERAL">maxAge</span> values specified by the attributes and add the cookie to the response. The tag handler class overrides the <span class="LITERAL">doEndTag()</span> method to carry out this work:
</p>
<span class="PROGRAMLISTING"><pre>    public int doEndTag() throws JspException {
        int maxAge = -1;
        if (maxAgeString != null) {
            try {
                maxAge = Integer.valueOf(maxAgeString).
                  intValue();
            }
            catch (NumberFormatException e) {
                throw new JspException("Invalid maxAge: " + 
                    e.getMessage());
            }
        }
        sendCookie(name, value, maxAge,
            (HttpServletResponse) pageContext.getResponse());
        return EVAL_PAGE;
    }

    private void sendCookie(String name, String value, 
      int maxAge,
        HttpServletResponse res) {
        Cookie cookie = new Cookie(name, value);
        cookie.setMaxAge(maxAge);
        res.addCookie(cookie);
    }</pre></span>
<p>
The <span class="LITERAL">maxAge</span> attribute is optional, so before the corresponding <span class="LITERAL">String</span> value is converted to an <span class="LITERAL">int</span>, a test is performed to see if it's set. Similar tests are not necessary for the <span class="LITERAL">name</span> and <span class="LITERAL">value</span> variables because the web container verifies that all mandatory attributes are set in the custom action. If a mandatory attribute is not set, the web container refuses to process the page-so you can always be sure that a variable corresponding to a mandatory attribute has a value. Whether an attribute is mandatory is specified in the TLD for the library.
</p>
<p>
The tag handler class should also implement the <span class="LITERAL">release()</span> method, to release all references to objects it has acquired:
</p>
<span class="PROGRAMLISTING"><pre>public void release() {
    name = null;
    value = null;
    maxAgeString = null;
    super.release();
}</pre></span>
<p>
The <span class="LITERAL">release()</span> method is called when the tag handler is no longer needed. The <span class="LITERAL">AddCookieTag</span> class sets all its properties to <span class="LITERAL">null</span> and calls <span class="LITERAL">super.release()</span> to let the <span class="LITERAL">TagSupport</span> class do the same. This makes all property objects available for garbage collection.
</p>
<p>
A <span class="LITERAL">TagSupport</span> method that's not needed for this example but can be handy in other situations is the <span class="LITERAL">findAncestorWithClass()</span> method. It can be used by a tag handler for a nested action element to find its parent. The nested tag handler can then call methods implemented by the parent tag handler class to get from or provide information to the parent. For example, it can provide the <span class="LITERAL">&lt;jsp:param&gt;</span> elements nested within the body of <span class="LITERAL">&lt;jsp:forward&gt;</span> and <span class="LITERAL">&lt;jsp:include&gt;</span> standard JSP action elements. An equivalent custom action for a nested parameter element could be implemented with a tag handler that uses the <span class="LITERAL">findAncestorWithClass()</span> method like this:
</p>
<span class="PROGRAMLISTING"><pre>import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
public class ParamTag extends TagSupport {
    private String name;
    private String value;

    public void setName(String name) {
        this.name = name;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public int doEndTag() throws JspException {
        Tag parent = findAncestorWithClass(this, 
          ParamParent.class);
        if (parent == null) {
            throw new JspException("The param action is not " +
                "enclosed by a supported action type");
        }
        ParamParent paramParent = (ParamParent) parent;
        paramParent.setParam(name, URLEncoder.
          encode(value));
        return EVAL_PAGE;
    }
}</pre></span> </td>
</tr>
</table>
</div>
<div id="TagSupport">
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="main">
<tr>
<td valign="top" class="NAME">TagSupport()</td>
<td valign="top" class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"> </td>
</tr>
<tr>
<td valign="top" colspan="2" class="usage"><span class="LITERAL">public TagSupport()</span></td>
</tr>
<tr>
<td valign="top" colspan="2" class="description"><p>
Creates a new instance with the specified name and value.
</p></td>
</tr>
</table>
</div>
<div id="doEndTag">
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="main">
<tr>
<td valign="top" class="NAME">doEndTag()</td>
<td valign="top" class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"> </td>
</tr>
<tr>
<td valign="top" colspan="2" class="usage"><span class="LITERAL">public int doEndTag() throws JspException</span></td>
</tr>
<tr>
<td valign="top" colspan="2" class="description"><p>
Returns <span class="LITERAL">EVAL_PAGE</span>.
</p></td>
</tr>
</table>
</div>
<div id="doStartTag">
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="main">
<tr>
<td valign="top" class="NAME">doStartTag()</td>
<td valign="top" class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"> </td>
</tr>
<tr>
<td valign="top" colspan="2" class="usage"><span class="LITERAL">public int doStartTag() throws JspException</span></td>
</tr>
<tr>
<td valign="top" colspan="2" class="description"><p>
Returns <span class="LITERAL">SKIP_BODY</span>.
</p></td>
</tr>
</table>
</div>
<div id="findAncestorWithClass">
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="main">
<tr>
<td valign="top" class="NAME">findAncestorWithClass()</td>
<td valign="top" class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"> </td>
</tr>
<tr>
<td valign="top" colspan="2" class="usage"><span class="LITERAL">public static final Tag findAncestorWithClass(Tag from, Class class)</span></td>
</tr>
<tr>
<td valign="top" colspan="2" class="description"><p>
Returns the instance of the specified class, found by testing for a match of each parent in a tag handler nesting structure (corresponding to nested action elements) starting with the specified <span class="LITERAL">Tag</span> instance, or <span class="LITERAL">null</span> if not found.
</p></td>
</tr>
</table>
</div>
<div id="getId">
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="main">
<tr>
<td valign="top" class="NAME">getId()</td>
<td valign="top" class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"> </td>
</tr>
<tr>
<td valign="top" colspan="2" class="usage"><span class="LITERAL">public String getId()</span></td>
</tr>
<tr>
<td valign="top" colspan="2" class="description"><p>
Returns the <span class="LITERAL">id</span> attribute value, or <span class="LITERAL">null</span> if not set.
</p></td>
</tr>
</table>
</div>
<div id="getParent">
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="main">
<tr>
<td valign="top" class="NAME">getParent()</td>
<td valign="top" class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"> </td>
</tr>
<tr>
<td valign="top" colspan="2" class="usage"><span class="LITERAL">public Tag getParent()</span></td>
</tr>
<tr>
<td valign="top" colspan="2" class="description"><p>
Returns the parent of this <span class="LITERAL">Tag</span> instance (representing the action element that contains the action element corresponding to this <span class="LITERAL">Tag</span> instance), or <span class="LITERAL">null</span> if the instance has no parent (i.e., is at the top level in the JSP page).
</p></td>
</tr>
</table>
</div>
<div id="getValue">
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="main">
<tr>
<td valign="top" class="NAME">getValue()</td>
<td valign="top" class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"> </td>
</tr>
<tr>
<td valign="top" colspan="2" class="usage"><span class="LITERAL">public Object getValue(String k)</span></td>
</tr>
<tr>
<td valign="top" colspan="2" class="description"><p>
Returns the value for the specified attribute that has been set with the <span class="LITERAL">setValue()</span> method, or <span class="LITERAL">null</span> if not found.
</p></td>
</tr>
</table>
</div>
<div id="getValues">
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="main">
<tr>
<td valign="top" class="NAME">getValues()</td>
<td valign="top" class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"> </td>
</tr>
<tr>
<td valign="top" colspan="2" class="usage"><span class="LITERAL">public java.util.Enumeration getValues()</span></td>
</tr>
<tr>
<td valign="top" colspan="2" class="description"><p>
Returns an <span class="LITERAL">Enumeration</span> of all attribute names for values set with the <span class="LITERAL">setValue()</span> method.
</p></td>
</tr>
</table>
</div>
<div id="release">
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="main">
<tr>
<td valign="top" class="NAME">release()</td>
<td valign="top" class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"> </td>
</tr>
<tr>
<td valign="top" colspan="2" class="usage"><span class="LITERAL">public void release()</span></td>
</tr>
<tr>
<td valign="top" colspan="2" class="description"><p>
Removes the references to all objects held by this instance.
</p></td>
</tr>
</table>
</div>
<div id="removeValue">
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="main">
<tr>
<td valign="top" class="NAME">removeValue()</td>
<td valign="top" class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"> </td>
</tr>
<tr>
<td valign="top" colspan="2" class="usage"><span class="LITERAL">public void removeValue(String k)</span></td>
</tr>
<tr>
<td valign="top" colspan="2" class="description"><p>
Removes a value set with the <span class="LITERAL">setValue()</span> method.
</p></td>
</tr>
</table>
</div>
<div id="setPageContext">
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="main">
<tr>
<td valign="top" class="NAME">setPageContext()</td>
<td valign="top" class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"> </td>
</tr>
<tr>
<td valign="top" colspan="2" class="usage"><span class="LITERAL">public void setPageContext(PageContext pageContext)</span></td>
</tr>
<tr>
<td valign="top" colspan="2" class="description"><p>
Saves a reference to the current <span class="LITERAL">PageContext</span>.
</p></td>
</tr>
</table>
</div>
<div id="setId">
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="main">
<tr>
<td valign="top" class="NAME">setId()</td>
<td valign="top" class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"> </td>
</tr>
<tr>
<td valign="top" colspan="2" class="usage"><span class="LITERAL">public void setId(String id)</span></td>
</tr>
<tr>
<td valign="top" colspan="2" class="description"><p>
Sets the <span class="LITERAL">id</span> attribute value.
</p></td>
</tr>
</table>
</div>
<div id="setParent">
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="main">
<tr>
<td valign="top" class="NAME">setParent()</td>
<td valign="top" class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"> </td>
</tr>
<tr>
<td valign="top" colspan="2" class="usage"><span class="LITERAL">public void setParent(Tag t)</span></td>
</tr>
<tr>
<td valign="top" colspan="2" class="description"><p>
Saves a reference to the parent for this instance.
</p></td>
</tr>
</table>
</div>
<div id="setValue">
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="main">
<tr>
<td valign="top" class="NAME">setValue()</td>
<td valign="top" class="COMPATIBILITY">&nbsp;</td>
</tr>
<tr>
<td colspan="2" class="divider"><img src="dwres:18084" width="100%" height="1"> </td>
</tr>
<tr>
<td valign="top" colspan="2" class="usage"><span class="LITERAL">public void setValue(String k, Object o)</span></td>
</tr>
<tr>
<td valign="top" colspan="2" class="description"><p>
Saves the specified attribute with the specified value. Subclasses can use this method to save attribute values as an alternative to instance variables.
</p></td>
</tr>
</table>
</div>
</body>
</html>
