/*
* 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 {

    private static final long serialVersionUID = 1L;

    /**
     * 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 additional 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,
            // TCK signature test fails with generics
            @SuppressWarnings("rawtypes")
            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)) ||
                    ((Class<?>)klass).isAssignableFrom(tag.getClass())) {
                return tag;
            }
            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() {
        // NOOP by default
    }

    /**
     * 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()
     */
    @Override
    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()
     */
    @Override
    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()
     */
    @Override
    public int doAfterBody() throws JspException {
        return SKIP_BODY;
    }

    // Actions related to body evaluation


    /**
     * Release state.
     *
     * @see Tag#release()
     */
    @Override
    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)
     */
    @Override
    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
     */
    @Override
    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
     */
    @Override
    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<String, Object>();
        }
        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;
        }
        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<String> getValues() {
        if (values == null) {
            return null;
        }
        return values.keys();
    }

    // private fields

    private   Tag         parent;
    private   Hashtable<String, Object>   values;
    /**
     * The value of the id attribute of this tag; or null.
     */
    protected String      id;

    // protected fields

    /**
     * The PageContext.
     */
    protected transient PageContext pageContext;
}

