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