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

/**
 * The BodyTag interface extends IterationTag by defining additional
 * methods that let a tag handler manipulate the content of evaluating its body.
 *
 * <p>
 * It is the responsibility of the tag handler to manipulate the body
 * content.  For example the tag handler may take the body content,
 * convert it into a String using the bodyContent.getString
 * method and then use it.  Or the tag handler may take the body
 * content and write it out into its enclosing JspWriter using
 * the bodyContent.writeOut method.
 *
 * <p> A tag handler that implements BodyTag is treated as one that
 * implements IterationTag, except that the doStartTag method can
 * return SKIP_BODY, EVAL_BODY_INCLUDE or EVAL_BODY_BUFFERED.
 *
 * <p>
 * If EVAL_BODY_INCLUDE is returned, then evaluation happens
 * as in IterationTag.
 *
 * <p>
 * If EVAL_BODY_BUFFERED is returned, then a BodyContent object will be
 * created (by code generated by the JSP compiler) to capture the body
 * evaluation.
 * The code generated by the JSP compiler obtains the BodyContent object by
 * calling the pushBody method of the current pageContext, which
 * additionally has the effect of saving the previous out value.
 * The page compiler returns this object by calling the popBody
 * method of the PageContext class;
 * the call also restores the value of out.
 *
 * <p>
 * The interface provides one new property with a setter method and one
 * new action method.
 *
 * <p><B>Properties</B>
 * <p> There is a new property: bodyContent, to contain the BodyContent
 * object, where the JSP Page implementation object will place the
 * evaluation (and reevaluation, if appropriate) of the body.  The setter
 * method (setBodyContent) will only be invoked if doStartTag() returns
 * EVAL_BODY_BUFFERED and the corresponding action element does not have
 * an empty body.
 *
 * <p><B>Methods</B>
 * <p> In addition to the setter method for the bodyContent property, there
 * is a new action method: doInitBody(), which is invoked right after
 * setBodyContent() and before the body evaluation.  This method is only
 * invoked if doStartTag() returns EVAL_BODY_BUFFERED.
 *
 * <p><B>Lifecycle</B>
 * <p> Lifecycle details are described by the transition diagram below.
 * Exceptions that are thrown during the computation of doStartTag(),
 * setBodyContent(), doInitBody(), BODY, doAfterBody() interrupt the
 * execution sequence and are propagated up the stack, unless the
 * tag handler implements the TryCatchFinally interface; see that
 * interface for details.
 * <p>
 * <IMG src="doc-files/BodyTagProtocol.gif"
 *      alt="Lifecycle Details Transition Diagram for BodyTag"/>
 *
 * <p><B>Empty and Non-Empty Action</B>
 * <p> If the TagLibraryDescriptor file indicates that the action must
 * always have an empty element body, by an &lt;body-content&gt; entry 
 * of "empty", then the doStartTag() method must return SKIP_BODY.
 * Otherwise, the doStartTag() method may return SKIP_BODY,
 * EVAL_BODY_INCLUDE, or EVAL_BODY_BUFFERED.
 *
 * <p>Note that which methods are invoked after the doStartTag() depends on 
 * both the return value and on if the custom action element is empty
 * or not in the JSP page, not how it's declared in the TLD.
 *
 * <p>
 * If SKIP_BODY is returned the body is not evaluated, and doEndTag() is
 * invoked.
 *
 * <p>
 * If EVAL_BODY_INCLUDE is returned, and the custom action element is not
 * empty, setBodyContent() is not invoked,
 * doInitBody() is not invoked, the body is evaluated and
 * "passed through" to the current out, doAfterBody() is invoked
 * and then, after zero or more iterations, doEndTag() is invoked.
 * If the custom action element is empty, only doStart() and 
 * doEndTag() are invoked.
 *
 * <p>
 * If EVAL_BODY_BUFFERED is returned, and the custom action element is not
 * empty, setBodyContent() is invoked,
 * doInitBody() is invoked, the body is evaluated, doAfterBody() is
 * invoked, and then, after zero or more iterations, doEndTag() is invoked.
 * If the custom action element is empty, only doStart() and doEndTag() 
 * are invoked.
 */

public interface BodyTag extends IterationTag {

    /**
     * Deprecated constant that has the same value as EVAL_BODY_BUFFERED
     * and EVAL_BODY_AGAIN.  This name has been marked as deprecated
     * to encourage the use of the two different terms, which are much
     * more descriptive.
     *
     * @deprecated	As of Java JSP API 1.2, use BodyTag.EVAL_BODY_BUFFERED
     * or IterationTag.EVAL_BODY_AGAIN.
     */
 
    public final static int EVAL_BODY_TAG = 2;

    /**
     * Request the creation of new buffer, a BodyContent on which to
     * evaluate the body of this tag.
     *
     * Returned from doStartTag when it implements BodyTag.
     * This is an illegal return value for doStartTag when the class
     * does not implement BodyTag.
     */

    public final static int EVAL_BODY_BUFFERED = 2;


    /**
     * Set the bodyContent property.
     * This method is invoked by the JSP page implementation object at
     * most once per action invocation.
     * This method will be invoked before doInitBody.
     * This method will not be invoked for empty tags or for non-empty
     * tags whose doStartTag() method returns SKIP_BODY or EVAL_BODY_INCLUDE.
     *
     * <p>
     * When setBodyContent is invoked, the value of the implicit object out
     * has already been changed in the pageContext object.  The BodyContent
     * object passed will have not data on it but may have been reused
     * (and cleared) from some previous invocation.
     *
     * <p>
     * The BodyContent object is available and with the appropriate content
     * until after the invocation of the doEndTag method, at which case it
     * may be reused.
     *
     * @param b the BodyContent
     * @see #doInitBody
     * @see #doAfterBody
     */

    void setBodyContent(BodyContent b);


    /**
     * Prepare for evaluation of the body.
     * This method is invoked by the JSP page implementation object
     * after setBodyContent and before the first time
     * the body is to be evaluated.
     * This method will not be invoked for empty tags or for non-empty
     * tags whose doStartTag() method returns SKIP_BODY or EVAL_BODY_INCLUDE.
     *
     * <p>
     * The JSP container will resynchronize the values of any AT_BEGIN and
     * NESTED variables (defined by the associated TagExtraInfo or TLD) after
     * the invocation of doInitBody().
     *
     * @throws JspException if an error occurred while processing this tag
     * @see #doAfterBody
     */

    void doInitBody() throws JspException;

}
