| /* |
| * Copyright 2004 The Apache Software Foundation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package javax.servlet.jsp.tagext; |
| |
| import java.io.Serializable; |
| import java.util.Enumeration; |
| import java.util.Hashtable; |
| |
| import javax.servlet.jsp.JspException; |
| import javax.servlet.jsp.PageContext; |
| |
| /** |
| * A base class for defining new tag handlers implementing Tag. |
| * |
| * <p> The TagSupport class is a utility class intended to be used as |
| * the base class for new tag handlers. The TagSupport class |
| * implements the Tag and IterationTag interfaces and adds additional |
| * convenience methods including getter methods for the properties in |
| * Tag. TagSupport has one static method that is included to |
| * facilitate coordination among cooperating tags. |
| * |
| * <p> Many tag handlers will extend TagSupport and only redefine a |
| * few methods. |
| */ |
| |
| public class TagSupport implements IterationTag, Serializable { |
| |
| /** |
| * Find the instance of a given class type that is closest to a given |
| * instance. |
| * This method uses the getParent method from the Tag |
| * interface. |
| * This method is used for coordination among cooperating tags. |
| * |
| * <p> |
| * The current version of the specification only provides one formal |
| * way of indicating the observable type of a tag handler: its |
| * tag handler implementation class, described in the tag-class |
| * subelement of the tag element. This is extended in an |
| * informal manner by allowing the tag library author to |
| * indicate in the description subelement an observable type. |
| * The type should be a subtype of the tag handler implementation |
| * class or void. |
| * This addititional constraint can be exploited by a |
| * specialized container that knows about that specific tag library, |
| * as in the case of the JSP standard tag library. |
| * |
| * <p> |
| * When a tag library author provides information on the |
| * observable type of a tag handler, client programmatic code |
| * should adhere to that constraint. Specifically, the Class |
| * passed to findAncestorWithClass should be a subtype of the |
| * observable type. |
| * |
| * |
| * @param from The instance from where to start looking. |
| * @param klass The subclass of Tag or interface to be matched |
| * @return the nearest ancestor that implements the interface |
| * or is an instance of the class specified |
| */ |
| |
| public static final Tag findAncestorWithClass(Tag from, Class klass) { |
| boolean isInterface = false; |
| |
| if (from == null || |
| klass == null || |
| (!Tag.class.isAssignableFrom(klass) && |
| !(isInterface = klass.isInterface()))) { |
| return null; |
| } |
| |
| for (;;) { |
| Tag tag = from.getParent(); |
| |
| if (tag == null) { |
| return null; |
| } |
| |
| if ((isInterface && klass.isInstance(tag)) || |
| klass.isAssignableFrom(tag.getClass())) |
| return tag; |
| else |
| from = tag; |
| } |
| } |
| |
| /** |
| * Default constructor, all subclasses are required to define only |
| * a public constructor with the same signature, and to call the |
| * superclass constructor. |
| * |
| * This constructor is called by the code generated by the JSP |
| * translator. |
| */ |
| |
| public TagSupport() { } |
| |
| /** |
| * Default processing of the start tag, returning SKIP_BODY. |
| * |
| * @return SKIP_BODY |
| * @throws JspException if an error occurs while processing this tag |
| * |
| * @see Tag#doStartTag() |
| */ |
| |
| public int doStartTag() throws JspException { |
| return SKIP_BODY; |
| } |
| |
| /** |
| * Default processing of the end tag returning EVAL_PAGE. |
| * |
| * @return EVAL_PAGE |
| * @throws JspException if an error occurs while processing this tag |
| * |
| * @see Tag#doEndTag() |
| */ |
| |
| public int doEndTag() throws JspException { |
| return EVAL_PAGE; |
| } |
| |
| |
| /** |
| * Default processing for a body. |
| * |
| * @return SKIP_BODY |
| * @throws JspException if an error occurs while processing this tag |
| * |
| * @see IterationTag#doAfterBody() |
| */ |
| |
| public int doAfterBody() throws JspException { |
| return SKIP_BODY; |
| } |
| |
| // Actions related to body evaluation |
| |
| |
| /** |
| * Release state. |
| * |
| * @see Tag#release() |
| */ |
| |
| public void release() { |
| parent = null; |
| id = null; |
| if( values != null ) { |
| values.clear(); |
| } |
| values = null; |
| } |
| |
| /** |
| * Set the nesting tag of this tag. |
| * |
| * @param t The parent Tag. |
| * @see Tag#setParent(Tag) |
| */ |
| |
| public void setParent(Tag t) { |
| parent = t; |
| } |
| |
| /** |
| * The Tag instance most closely enclosing this tag instance. |
| * @see Tag#getParent() |
| * |
| * @return the parent tag instance or null |
| */ |
| |
| public Tag getParent() { |
| return parent; |
| } |
| |
| /** |
| * Set the id attribute for this tag. |
| * |
| * @param id The String for the id. |
| */ |
| |
| public void setId(String id) { |
| this.id = id; |
| } |
| |
| /** |
| * The value of the id attribute of this tag; or null. |
| * |
| * @return the value of the id attribute, or null |
| */ |
| |
| public String getId() { |
| return id; |
| } |
| |
| /** |
| * Set the page context. |
| * |
| * @param pageContext The PageContext. |
| * @see Tag#setPageContext |
| */ |
| |
| public void setPageContext(PageContext pageContext) { |
| this.pageContext = pageContext; |
| } |
| |
| /** |
| * Associate a value with a String key. |
| * |
| * @param k The key String. |
| * @param o The value to associate. |
| */ |
| |
| public void setValue(String k, Object o) { |
| if (values == null) { |
| values = new Hashtable(); |
| } |
| values.put(k, o); |
| } |
| |
| /** |
| * Get a the value associated with a key. |
| * |
| * @param k The string key. |
| * @return The value associated with the key, or null. |
| */ |
| |
| public Object getValue(String k) { |
| if (values == null) { |
| return null; |
| } else { |
| return values.get(k); |
| } |
| } |
| |
| /** |
| * Remove a value associated with a key. |
| * |
| * @param k The string key. |
| */ |
| |
| public void removeValue(String k) { |
| if (values != null) { |
| values.remove(k); |
| } |
| } |
| |
| /** |
| * Enumerate the keys for the values kept by this tag handler. |
| * |
| * @return An enumeration of all the keys for the values set, |
| * or null or an empty Enumeration if no values have been set. |
| */ |
| |
| public Enumeration getValues() { |
| if (values == null) { |
| return null; |
| } |
| return values.keys(); |
| } |
| |
| // private fields |
| |
| private Tag parent; |
| private Hashtable values; |
| /** |
| * The value of the id attribute of this tag; or null. |
| */ |
| protected String id; |
| |
| // protected fields |
| |
| /** |
| * The PageContext. |
| */ |
| protected PageContext pageContext; |
| } |
| |