001    /*
002    * Licensed to the Apache Software Foundation (ASF) under one or more
003    * contributor license agreements.  See the NOTICE file distributed with
004    * this work for additional information regarding copyright ownership.
005    * The ASF licenses this file to You under the Apache License, Version 2.0
006    * (the "License"); you may not use this file except in compliance with
007    * the License.  You may obtain a copy of the License at
008    *
009    *     http://www.apache.org/licenses/LICENSE-2.0
010    *
011    * Unless required by applicable law or agreed to in writing, software
012    * distributed under the License is distributed on an "AS IS" BASIS,
013    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014    * See the License for the specific language governing permissions and
015    * limitations under the License.
016    */
017    package javax.servlet.jsp.tagext;
018    
019    import javax.servlet.jsp.*;
020    
021    /**
022     * The BodyTag interface extends IterationTag by defining additional
023     * methods that let a tag handler manipulate the content of evaluating its body.
024     *
025     * <p>
026     * It is the responsibility of the tag handler to manipulate the body
027     * content.  For example the tag handler may take the body content,
028     * convert it into a String using the bodyContent.getString
029     * method and then use it.  Or the tag handler may take the body
030     * content and write it out into its enclosing JspWriter using
031     * the bodyContent.writeOut method.
032     *
033     * <p> A tag handler that implements BodyTag is treated as one that
034     * implements IterationTag, except that the doStartTag method can
035     * return SKIP_BODY, EVAL_BODY_INCLUDE or EVAL_BODY_BUFFERED.
036     *
037     * <p>
038     * If EVAL_BODY_INCLUDE is returned, then evaluation happens
039     * as in IterationTag.
040     *
041     * <p>
042     * If EVAL_BODY_BUFFERED is returned, then a BodyContent object will be
043     * created (by code generated by the JSP compiler) to capture the body
044     * evaluation.
045     * The code generated by the JSP compiler obtains the BodyContent object by
046     * calling the pushBody method of the current pageContext, which
047     * additionally has the effect of saving the previous out value.
048     * The page compiler returns this object by calling the popBody
049     * method of the PageContext class;
050     * the call also restores the value of out.
051     *
052     * <p>
053     * The interface provides one new property with a setter method and one
054     * new action method.
055     *
056     * <p><B>Properties</B>
057     * <p> There is a new property: bodyContent, to contain the BodyContent
058     * object, where the JSP Page implementation object will place the
059     * evaluation (and reevaluation, if appropriate) of the body.  The setter
060     * method (setBodyContent) will only be invoked if doStartTag() returns
061     * EVAL_BODY_BUFFERED and the corresponding action element does not have
062     * an empty body.
063     *
064     * <p><B>Methods</B>
065     * <p> In addition to the setter method for the bodyContent property, there
066     * is a new action method: doInitBody(), which is invoked right after
067     * setBodyContent() and before the body evaluation.  This method is only
068     * invoked if doStartTag() returns EVAL_BODY_BUFFERED.
069     *
070     * <p><B>Lifecycle</B>
071     * <p> Lifecycle details are described by the transition diagram below.
072     * Exceptions that are thrown during the computation of doStartTag(),
073     * setBodyContent(), doInitBody(), BODY, doAfterBody() interrupt the
074     * execution sequence and are propagated up the stack, unless the
075     * tag handler implements the TryCatchFinally interface; see that
076     * interface for details.
077     * <p>
078     * <IMG src="doc-files/BodyTagProtocol.gif"
079     *      alt="Lifecycle Details Transition Diagram for BodyTag"/>
080     *
081     * <p><B>Empty and Non-Empty Action</B>
082     * <p> If the TagLibraryDescriptor file indicates that the action must
083     * always have an empty element body, by an &lt;body-content&gt; entry 
084     * of "empty", then the doStartTag() method must return SKIP_BODY.
085     * Otherwise, the doStartTag() method may return SKIP_BODY,
086     * EVAL_BODY_INCLUDE, or EVAL_BODY_BUFFERED.
087     *
088     * <p>Note that which methods are invoked after the doStartTag() depends on 
089     * both the return value and on if the custom action element is empty
090     * or not in the JSP page, not how it's declared in the TLD.
091     *
092     * <p>
093     * If SKIP_BODY is returned the body is not evaluated, and doEndTag() is
094     * invoked.
095     *
096     * <p>
097     * If EVAL_BODY_INCLUDE is returned, and the custom action element is not
098     * empty, setBodyContent() is not invoked,
099     * doInitBody() is not invoked, the body is evaluated and
100     * "passed through" to the current out, doAfterBody() is invoked
101     * and then, after zero or more iterations, doEndTag() is invoked.
102     * If the custom action element is empty, only doStart() and 
103     * doEndTag() are invoked.
104     *
105     * <p>
106     * If EVAL_BODY_BUFFERED is returned, and the custom action element is not
107     * empty, setBodyContent() is invoked,
108     * doInitBody() is invoked, the body is evaluated, doAfterBody() is
109     * invoked, and then, after zero or more iterations, doEndTag() is invoked.
110     * If the custom action element is empty, only doStart() and doEndTag() 
111     * are invoked.
112     */
113    
114    public interface BodyTag extends IterationTag {
115    
116        /**
117         * Deprecated constant that has the same value as EVAL_BODY_BUFFERED
118         * and EVAL_BODY_AGAIN.  This name has been marked as deprecated
119         * to encourage the use of the two different terms, which are much
120         * more descriptive.
121         *
122         * @deprecated      As of Java JSP API 1.2, use BodyTag.EVAL_BODY_BUFFERED
123         * or IterationTag.EVAL_BODY_AGAIN.
124         */
125     
126        public final static int EVAL_BODY_TAG = 2;
127    
128        /**
129         * Request the creation of new buffer, a BodyContent on which to
130         * evaluate the body of this tag.
131         *
132         * Returned from doStartTag when it implements BodyTag.
133         * This is an illegal return value for doStartTag when the class
134         * does not implement BodyTag.
135         */
136    
137        public final static int EVAL_BODY_BUFFERED = 2;
138    
139    
140        /**
141         * Set the bodyContent property.
142         * This method is invoked by the JSP page implementation object at
143         * most once per action invocation.
144         * This method will be invoked before doInitBody.
145         * This method will not be invoked for empty tags or for non-empty
146         * tags whose doStartTag() method returns SKIP_BODY or EVAL_BODY_INCLUDE.
147         *
148         * <p>
149         * When setBodyContent is invoked, the value of the implicit object out
150         * has already been changed in the pageContext object.  The BodyContent
151         * object passed will have not data on it but may have been reused
152         * (and cleared) from some previous invocation.
153         *
154         * <p>
155         * The BodyContent object is available and with the appropriate content
156         * until after the invocation of the doEndTag method, at which case it
157         * may be reused.
158         *
159         * @param b the BodyContent
160         * @see #doInitBody
161         * @see #doAfterBody
162         */
163    
164        void setBodyContent(BodyContent b);
165    
166    
167        /**
168         * Prepare for evaluation of the body.
169         * This method is invoked by the JSP page implementation object
170         * after setBodyContent and before the first time
171         * the body is to be evaluated.
172         * This method will not be invoked for empty tags or for non-empty
173         * tags whose doStartTag() method returns SKIP_BODY or EVAL_BODY_INCLUDE.
174         *
175         * <p>
176         * The JSP container will resynchronize the values of any AT_BEGIN and
177         * NESTED variables (defined by the associated TagExtraInfo or TLD) after
178         * the invocation of doInitBody().
179         *
180         * @throws JspException if an error occurred while processing this tag
181         * @see #doAfterBody
182         */
183    
184        void doInitBody() throws JspException;
185    
186    }