View Javadoc

    1   /**
    2    *
    3    * Copyright 2003-2004 The Apache Software Foundation
    4    *
    5    *  Licensed under the Apache License, Version 2.0 (the "License");
    6    *  you may not use this file except in compliance with the License.
    7    *  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   *  Unless required by applicable law or agreed to in writing, software
    12   *  distributed under the License is distributed on an "AS IS" BASIS,
    13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   *  See the License for the specific language governing permissions and
    15   *  limitations under the License.
    16   */
    17
    18  //
    19  // This source code implements specifications defined by the Java
    20  // Community Process. In order to remain compliant with the specification
    21  // DO NOT add / change / or delete method signatures!
    22  //
    23
    24  package javax.servlet.jsp.tagext;
    25
    26  import java.io.Serializable;
    27  import java.util.Enumeration;
    28  import java.util.Hashtable;
    29
    30  import javax.servlet.jsp.JspException;
    31  import javax.servlet.jsp.PageContext;
    32
    33  /**
    34   * A base class for defining new tag handlers implementing Tag.
    35   *
    36   * <p> The TagSupport class is a utility class intended to be used as
    37   * the base class for new tag handlers.  The TagSupport class
    38   * implements the Tag and IterationTag interfaces and adds additional
    39   * convenience methods including getter methods for the properties in
    40   * Tag.  TagSupport has one static method that is included to
    41   * facilitate coordination among cooperating tags.
    42   *
    43   * <p> Many tag handlers will extend TagSupport and only redefine a
    44   * few methods.
    45   */
    46
    47  public class TagSupport implements IterationTag, Serializable {
    48
    49      /**
    50       * Find the instance of a given class type that is closest to a given
    51       * instance.
    52       * This method uses the getParent method from the Tag
    53       * interface.
    54       * This method is used for coordination among cooperating tags.
    55       *
    56       * <p>
    57       * The current version of the specification only provides one formal
    58       * way of indicating the observable type of a tag handler: its
    59       * tag handler implementation class, described in the tag-class
    60       * subelement of the tag element.  This is extended in an
    61       * informal manner by allowing the tag library author to
    62       * indicate in the description subelement an observable type.
    63       * The type should be a subtype of the tag handler implementation
    64       * class or void.
    65       * This addititional constraint can be exploited by a
    66       * specialized container that knows about that specific tag library,
    67       * as in the case of the JSP standard tag library.
    68       *
    69       * <p>
    70       * When a tag library author provides information on the
    71       * observable type of a tag handler, client programmatic code
    72       * should adhere to that constraint.  Specifically, the Class
    73       * passed to findAncestorWithClass should be a subtype of the
    74       * observable type.
    75       *
    76       *
    77       * @param from The instance from where to start looking.
    78       * @param klass The subclass of Tag or interface to be matched
    79       * @return the nearest ancestor that implements the interface
    80       * or is an instance of the class specified
    81       */
    82
    83      public static final Tag findAncestorWithClass(Tag from, Class klass) {
    84  	boolean isInterface = false;
    85
    86  	if (from == null ||
    87  	    klass == null ||
    88  	    (!Tag.class.isAssignableFrom(klass) &&
    89  	     !(isInterface = klass.isInterface()))) {
    90  	    return null;
    91  	}
    92
    93  	for (;;) {
    94  	    Tag tag = from.getParent();
    95
    96  	    if (tag == null) {
    97  		return null;
    98  	    }
    99
    100 	    if ((isInterface && klass.isInstance(tag)) ||
    101 	        klass.isAssignableFrom(tag.getClass()))
    102 		return tag;
    103 	    else
    104 		from = tag;
    105 	}
    106     }
    107
    108     /**
    109      * Default constructor, all subclasses are required to define only
    110      * a public constructor with the same signature, and to call the
    111      * superclass constructor.
    112      *
    113      * This constructor is called by the code generated by the JSP
    114      * translator.
    115      */
    116
    117     public TagSupport() { }
    118
    119     /**
    120      * Default processing of the start tag, returning SKIP_BODY.
    121      *
    122      * @return SKIP_BODY
    123      * @throws JspException if an error occurs while processing this tag
    124      *
    125      * @see Tag#doStartTag()
    126      */
    127
    128     public int doStartTag() throws JspException {
    129         return SKIP_BODY;
    130     }
    131
    132     /**
    133      * Default processing of the end tag returning EVAL_PAGE.
    134      *
    135      * @return EVAL_PAGE
    136      * @throws JspException if an error occurs while processing this tag
    137      *
    138      * @see Tag#doEndTag()
    139      */
    140
    141     public int doEndTag() throws JspException {
    142 	return EVAL_PAGE;
    143     }
    144
    145
    146     /**
    147      * Default processing for a body.
    148      *
    149      * @return SKIP_BODY
    150      * @throws JspException if an error occurs while processing this tag
    151      *
    152      * @see IterationTag#doAfterBody()
    153      */
    154
    155     public int doAfterBody() throws JspException {
    156 	return SKIP_BODY;
    157     }
    158
    159     // Actions related to body evaluation
    160
    161
    162     /**
    163      * Release state.
    164      *
    165      * @see Tag#release()
    166      */
    167
    168     public void release() {
    169 	parent = null;
    170 	id = null;
    171 	if( values != null ) {
    172 	    values.clear();
    173 	}
    174 	values = null;
    175     }
    176
    177     /**
    178      * Set the nesting tag of this tag.
    179      *
    180      * @param t The parent Tag.
    181      * @see Tag#setParent(Tag)
    182      */
    183
    184     public void setParent(Tag t) {
    185 	parent = t;
    186     }
    187
    188     /**
    189      * The Tag instance most closely enclosing this tag instance.
    190      * @see Tag#getParent()
    191      *
    192      * @return the parent tag instance or null
    193      */
    194
    195     public Tag getParent() {
    196 	return parent;
    197     }
    198
    199     /**
    200      * Set the id attribute for this tag.
    201      *
    202      * @param id The String for the id.
    203      */
    204
    205     public void setId(String id) {
    206 	this.id = id;
    207     }
    208
    209     /**
    210      * The value of the id attribute of this tag; or null.
    211      *
    212      * @return the value of the id attribute, or null
    213      */
    214
    215     public String getId() {
    216 	return id;
    217     }
    218
    219     /**
    220      * Set the page context.
    221      *
    222      * @param pageContext The PageContext.
    223      * @see Tag#setPageContext
    224      */
    225
    226     public void setPageContext(PageContext pageContext) {
    227 	this.pageContext = pageContext;
    228     }
    229
    230     /**
    231      * Associate a value with a String key.
    232      *
    233      * @param k The key String.
    234      * @param o The value to associate.
    235      */
    236
    237     public void setValue(String k, Object o) {
    238 	if (values == null) {
    239 	    values = new Hashtable();
    240 	}
    241 	values.put(k, o);
    242     }
    243
    244     /**
    245      * Get a the value associated with a key.
    246      *
    247      * @param k The string key.
    248      * @return The value associated with the key, or null.
    249      */
    250
    251     public Object getValue(String k) {
    252 	if (values == null) {
    253 	    return null;
    254 	} else {
    255 	    return values.get(k);
    256 	}
    257     }
    258
    259     /**
    260      * Remove a value associated with a key.
    261      *
    262      * @param k The string key.
    263      */
    264
    265     public void removeValue(String k) {
    266 	if (values != null) {
    267 	    values.remove(k);
    268 	}
    269     }
    270
    271     /**
    272      * Enumerate the keys for the values kept by this tag handler.
    273      *
    274      * @return An enumeration of all the keys for the values set,
    275      *     or null or an empty Enumeration if no values have been set.
    276      */
    277
    278     public Enumeration getValues() {
    279 	if (values == null) {
    280 	    return null;
    281 	}
    282 	return values.keys();
    283     }
    284
    285     // private fields
    286
    287     private   Tag         parent;
    288     private   Hashtable   values;
    289     /**
    290      * The value of the id attribute of this tag; or null.
    291      */
    292     protected String	  id;
    293
    294     // protected fields
    295
    296     /**
    297      * The PageContext.
    298      */
    299     protected PageContext pageContext;
    300 }
    301