/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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;
}

