/*
* 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 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;
	}
    }    
}
