/*
* 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 javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import java.io.IOException;

/**
 * A base class for defining tag handlers implementing SimpleTag.
 * <p>
 * The SimpleTagSupport class is a utility class intended to be used
 * as the base class for new simple tag handlers.  The SimpleTagSupport
 * class implements the SimpleTag interface and adds additional
 * convenience methods including getter methods for the properties in
 * SimpleTag.
 *
 * @since 2.0
 */
public class SimpleTagSupport 
    implements SimpleTag
{
    /** Reference to the enclosing tag. */
    private JspTag parentTag;
    
    /** The JSP context for the upcoming tag invocation. */
    private JspContext jspContext;
    
    /** The body of the tag. */
    private JspFragment jspBody;
    
    /**
     * Sole constructor. (For invocation by subclass constructors, 
     * typically implicit.)
     */
    public SimpleTagSupport() {
    }
    
    /** 
     * Default processing of the tag does nothing.
     *
     * @throws JspException Subclasses can throw JspException to indicate
     *     an error occurred while processing this tag.
     * @throws javax.servlet.jsp.SkipPageException If the page that
     *     (either directly or indirectly) invoked this tag is to
     *     cease evaluation.  A Simple Tag Handler generated from a 
     *     tag file must throw this exception if an invoked Classic 
     *     Tag Handler returned SKIP_PAGE or if an invoked Simple
     *     Tag Handler threw SkipPageException or if an invoked Jsp Fragment
     *     threw a SkipPageException.
     * @throws IOException Subclasses can throw IOException if there was
     *     an error writing to the output stream
     * @see SimpleTag#doTag()
     */ 
    public void doTag() 
        throws JspException, IOException
    {
    }
    
    /**
     * Sets the parent of this tag, for collaboration purposes.
     * <p>
     * The container invokes this method only if this tag invocation is
     * nested within another tag invocation.
     *
     * @param parent the tag that encloses this tag
     */
    public void setParent( JspTag parent ) {
        this.parentTag = parent;
    }
    
    /**
     * Returns the parent of this tag, for collaboration purposes.
     *
     * @return the parent of this tag
     */ 
    public JspTag getParent() {
        return this.parentTag;
    }
    
    /**
     * Stores the provided JSP context in the private jspContext field.
     * Subclasses can access the <code>JspContext</code> via 
     * <code>getJspContext()</code>.
     * 
     * @param pc the page context for this invocation
     * @see SimpleTag#setJspContext
     */
    public void setJspContext( JspContext pc ) {
        this.jspContext = pc;
    }
    
    /**
     * Returns the page context passed in by the container via 
     * setJspContext.
     *
     * @return the page context for this invocation
     */
    protected JspContext getJspContext() {
        return this.jspContext;
    }
                
    /** 
     * Stores the provided JspFragment.
     *
     * @param jspBody The fragment encapsulating the body of this tag.
     *     If the action element is empty in the page, this method is 
     *     not called at all.
     * @see SimpleTag#setJspBody
     */ 
    public void setJspBody( JspFragment jspBody ) {
        this.jspBody = jspBody;
    }
    
    /**
     * Returns the body passed in by the container via setJspBody.
     *
     * @return the fragment encapsulating the body of this tag, or
     *    null if the action element is empty in the page.
     */
    protected JspFragment getJspBody() {
        return this.jspBody;
    }

    /**
     * Find the instance of a given class type that is closest to a given
     * instance.
     * This method uses the getParent method from the Tag and/or SimpleTag
     * interfaces.  This method is used for coordination among 
     * cooperating tags.
     *
     * <p> For every instance of TagAdapter
     * encountered while traversing the ancestors, the tag handler returned by
     * <tt>TagAdapter.getAdaptee()</tt> - instead of the TagAdpater itself -
     * is compared to <tt>klass</tt>. If the tag handler matches, it - and
     * not its TagAdapter - is returned.
     *
     * <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 JspTag or interface to be matched
     * @return the nearest ancestor that implements the interface
     * or is an instance of the class specified
     */
    public static final JspTag findAncestorWithClass(
	JspTag from, Class klass) 
    {
	boolean isInterface = false;

	if (from == null || klass == null
	        || (!JspTag.class.isAssignableFrom(klass)
		    && !(isInterface = klass.isInterface()))) {
	    return null;
	}

	for (;;) {
	    JspTag parent = null;
	    if( from instanceof SimpleTag ) {
		parent = ((SimpleTag)from).getParent();
	    }
	    else if( from instanceof Tag ) {
		parent = ((Tag)from).getParent();
	    }
	    if (parent == null) {
		return null;
	    }

	    if (parent instanceof TagAdapter) {
		parent = ((TagAdapter) parent).getAdaptee();
	    }

	    if ((isInterface && klass.isInstance(parent))
		    || klass.isAssignableFrom(parent.getClass())) {
		return parent;
	    }

	    from = parent;
	}
    }    
}
