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     
018    package javax.servlet.jsp;
019    
020    import java.io.IOException;
021    
022    import javax.servlet.Servlet;
023    import javax.servlet.ServletConfig;
024    import javax.servlet.ServletContext;
025    import javax.servlet.ServletException;
026    import javax.servlet.ServletRequest;
027    import javax.servlet.ServletResponse;
028    
029    import javax.servlet.http.HttpSession;
030    
031    import javax.servlet.jsp.tagext.BodyContent;
032    
033    /**
034     * <p>
035     * PageContext extends JspContext to provide useful context information for
036     * when JSP technology is used in a Servlet environment.
037     * <p>
038     * A PageContext instance provides access to all the namespaces associated
039     * with a JSP page, provides access to several page attributes, as well as
040     * a layer above the implementation details.  Implicit objects are added
041     * to the pageContext automatically.
042     *
043     * <p> The <code> PageContext </code> class is an abstract class, designed to be
044     * extended to provide implementation dependent implementations thereof, by
045     * conformant JSP engine runtime environments. A PageContext instance is 
046     * obtained by a JSP implementation class by calling the
047     * JspFactory.getPageContext() method, and is released by calling
048     * JspFactory.releasePageContext().
049     *
050     * <p> An example of how PageContext, JspFactory, and other classes can be
051     * used  within a JSP Page Implementation object is given elsewhere.
052     *
053     * <p>
054     * The PageContext provides a number of facilities to the page/component 
055     * author and page implementor, including:
056     * <ul>
057     * <li>a single API to manage the various scoped namespaces
058     * <li>a number of convenience API's to access various public objects
059     * <li>a mechanism to obtain the JspWriter for output
060     * <li>a mechanism to manage session usage by the page
061     * <li>a mechanism to expose page directive attributes to the scripting 
062     *     environment
063     * <li>mechanisms to forward or include the current request to other active 
064     *     components in the application
065     * <li>a mechanism to handle errorpage exception processing
066     * </ul>
067     *
068     * <p><B>Methods Intended for Container Generated Code</B>
069     * <p>Some methods are intended to be used by the code generated by the
070     * container, not by code written by JSP page authors, or JSP tag library 
071     * authors.
072     * <p>The methods supporting <B>lifecycle</B> are <code>initialize()</code>
073     * and <code>release()</code>
074     *
075     * <p>
076     * The following methods enable the <B>management of nested</B> JspWriter 
077     * streams to implement Tag Extensions: <code>pushBody()</code>
078     *
079     * <p><B>Methods Intended for JSP authors</B>
080     * <p>
081     * The following methods provide <B>convenient access</B> to implicit objects:
082     * <code>getException()</code>,  <code>getPage()</code>
083     * <code>getRequest()</code>,  <code>getResponse()</code>,
084     * <code>getSession()</code>,  <code>getServletConfig()</code>
085     * and <code>getServletContext()</code>.
086     *
087     * <p>
088     * The following methods provide support for <B>forwarding, inclusion
089     * and error handling</B>:
090     * <code>forward()</code>,  <code>include()</code>,
091     * and  <code>handlePageException()</code>.
092     */
093    
094    abstract public class PageContext 
095        extends JspContext
096    {
097        
098        /**
099         * Sole constructor. (For invocation by subclass constructors, 
100         * typically implicit.)
101         */
102        public PageContext() {
103        }
104        
105        /**
106         * Page scope: (this is the default) the named reference remains available
107         * in this PageContext until the return from the current Servlet.service()
108         * invocation.
109         */
110    
111        public static final int PAGE_SCOPE          = 1;
112    
113        /**
114         * Request scope: the named reference remains available from the 
115         * ServletRequest associated with the Servlet until the current request 
116         * is completed.
117         */
118    
119        public static final int REQUEST_SCOPE       = 2;
120    
121        /**
122         * Session scope (only valid if this page participates in a session):
123         * the named reference remains available from the HttpSession (if any)
124         * associated with the Servlet until the HttpSession is invalidated.
125         */
126    
127        public static final int SESSION_SCOPE       = 3;
128    
129        /**
130         * Application scope: named reference remains available in the 
131         * ServletContext until it is reclaimed.
132         */
133    
134        public static final int APPLICATION_SCOPE   = 4;
135    
136        /**
137         * Name used to store the Servlet in this PageContext's nametables.
138         */
139    
140        public static final String PAGE = "javax.servlet.jsp.jspPage";
141    
142        /**
143         * Name used to store this PageContext in it's own name table.
144         */
145    
146        public static final String PAGECONTEXT = "javax.servlet.jsp.jspPageContext";
147    
148        /**
149         * Name used to store ServletRequest in PageContext name table.
150         */
151    
152        public static final String REQUEST = "javax.servlet.jsp.jspRequest";
153    
154        /**
155         * Name used to store ServletResponse in PageContext name table.
156         */
157    
158        public static final String RESPONSE = "javax.servlet.jsp.jspResponse";
159    
160        /**
161         * Name used to store ServletConfig in PageContext name table.
162         */
163    
164        public static final String CONFIG = "javax.servlet.jsp.jspConfig";
165    
166        /**
167         * Name used to store HttpSession in PageContext name table.
168         */
169    
170        public static final String SESSION = "javax.servlet.jsp.jspSession";
171        /**
172         * Name used to store current JspWriter in PageContext name table.
173         */
174    
175        public static final String OUT = "javax.servlet.jsp.jspOut";
176    
177        /**
178         * Name used to store ServletContext in PageContext name table.
179         */
180    
181        public static final String APPLICATION = "javax.servlet.jsp.jspApplication";
182    
183        /**
184         * Name used to store uncaught exception in ServletRequest attribute 
185         * list and PageContext name table.
186         */
187    
188        public static final String EXCEPTION = "javax.servlet.jsp.jspException";
189    
190        /**
191         * <p>
192         * The initialize method is called to initialize an uninitialized PageContext
193         * so that it may be used by a JSP Implementation class to service an
194         * incoming request and response within it's _jspService() method.
195         *
196         * <p>
197         * This method is typically called from JspFactory.getPageContext() in
198         * order to initialize state.
199         *
200         * <p>
201         * This method is required to create an initial JspWriter, and associate
202         * the "out" name in page scope with this newly created object.
203         *
204         * <p>
205         * This method should not be used by page  or tag library authors.
206         *
207         * @param servlet The Servlet that is associated with this PageContext
208         * @param request The currently pending request for this Servlet
209         * @param response The currently pending response for this Servlet
210         * @param errorPageURL The value of the errorpage attribute from the page 
211         *     directive or null
212         * @param needsSession The value of the session attribute from the 
213         *     page directive
214         * @param bufferSize The value of the buffer attribute from the page 
215         *     directive
216         * @param autoFlush The value of the autoflush attribute from the page 
217         *     directive
218         *
219         * @throws IOException during creation of JspWriter
220         * @throws IllegalStateException if out not correctly initialized
221         * @throws IllegalArgumentException If one of the given parameters
222         *     is invalid
223         */
224     
225        abstract public void initialize(Servlet servlet, ServletRequest request, 
226            ServletResponse response, String errorPageURL, boolean needsSession, 
227            int bufferSize, boolean autoFlush)  
228            throws IOException, IllegalStateException, IllegalArgumentException;
229    
230        /**
231         * <p>
232         * This method shall "reset" the internal state of a PageContext, releasing
233         * all internal references, and preparing the PageContext for potential
234         * reuse by a later invocation of initialize(). This method is typically
235         * called from JspFactory.releasePageContext().
236         *
237         * <p>
238         * Subclasses shall envelope this method.
239         *
240         * <p>
241         * This method should not be used by page  or tag library authors.
242         *
243         */
244    
245        abstract public void release();
246    
247        /**
248         * The current value of the session object (an HttpSession).
249         *
250         * @return the HttpSession for this PageContext or null
251         */
252    
253        abstract public HttpSession getSession();
254    
255        /**
256         * The current value of the page object (In a Servlet environment, 
257         * this is an instance of javax.servlet.Servlet).
258         *
259         * @return the Page implementation class instance associated 
260         *     with this PageContext
261         */
262    
263        abstract public Object getPage();
264    
265    
266        /**
267         * The current value of the request object (a ServletRequest).
268         *
269         * @return The ServletRequest for this PageContext
270         */
271    
272        abstract public ServletRequest getRequest();
273    
274        /**
275         * The current value of the response object (a ServletResponse).
276         *
277         * @return the ServletResponse for this PageContext
278         */
279    
280        abstract public ServletResponse getResponse();
281    
282        /**
283         * The current value of the exception object (an Exception).
284         *
285         * @return any exception passed to this as an errorpage
286         */
287    
288        abstract public Exception getException();
289    
290        /**
291         * The ServletConfig instance.
292         *
293         * @return the ServletConfig for this PageContext
294         */
295    
296        abstract public ServletConfig getServletConfig();
297    
298        /**
299         * The ServletContext instance.
300         * 
301         * @return the ServletContext for this PageContext
302         */
303    
304        abstract public ServletContext getServletContext();
305    
306        /**
307         * <p>
308         * This method is used to re-direct, or "forward" the current 
309         * ServletRequest and ServletResponse to another active component in 
310         * the application.
311         * </p>
312         * <p>
313         * If the <I> relativeUrlPath </I> begins with a "/" then the URL specified
314         * is calculated relative to the DOCROOT of the <code> ServletContext </code>
315         * for this JSP. If the path does not begin with a "/" then the URL 
316         * specified is calculated relative to the URL of the request that was
317         * mapped to the calling JSP.
318         * </p>
319         * <p>
320         * It is only valid to call this method from a <code> Thread </code>
321         * executing within a <code> _jspService(...) </code> method of a JSP.
322         * </p>
323         * <p>
324         * Once this method has been called successfully, it is illegal for the
325         * calling <code> Thread </code> to attempt to modify the <code>
326         * ServletResponse </code> object.  Any such attempt to do so, shall result
327         * in undefined behavior. Typically, callers immediately return from 
328         * <code> _jspService(...) </code> after calling this method.
329         * </p>
330         *
331         * @param relativeUrlPath specifies the relative URL path to the target 
332         *     resource as described above
333         *
334         * @throws IllegalStateException if <code> ServletResponse </code> is not 
335         *     in a state where a forward can be performed
336         * @throws ServletException if the page that was forwarded to throws
337         *     a ServletException
338         * @throws IOException if an I/O error occurred while forwarding
339         */
340    
341        abstract public void forward(String relativeUrlPath) 
342            throws ServletException, IOException;
343    
344        /**
345         * <p>
346         * Causes the resource specified to be processed as part of the current
347         * ServletRequest and ServletResponse being processed by the calling Thread.
348         * The output of the target resources processing of the request is written
349         * directly to the ServletResponse output stream.
350         * </p>
351         * <p>
352         * The current JspWriter "out" for this JSP is flushed as a side-effect
353         * of this call, prior to processing the include.
354         * </p>
355         * <p>
356         * If the <I> relativeUrlPath </I> begins with a "/" then the URL specified
357         * is calculated relative to the DOCROOT of the <code>ServletContext</code>
358         * for this JSP. If the path does not begin with a "/" then the URL 
359         * specified is calculated relative to the URL of the request that was
360         * mapped to the calling JSP.
361         * </p>
362         * <p>
363         * It is only valid to call this method from a <code> Thread </code>
364         * executing within a <code> _jspService(...) </code> method of a JSP.
365         * </p>
366         *
367         * @param relativeUrlPath specifies the relative URL path to the target 
368         *     resource to be included
369         *
370         * @throws ServletException if the page that was forwarded to throws
371         *     a ServletException
372         * @throws IOException if an I/O error occurred while forwarding
373         */
374        abstract public void include(String relativeUrlPath) 
375            throws ServletException, IOException;
376    
377        /**
378         * <p>
379         * Causes the resource specified to be processed as part of the current
380         * ServletRequest and ServletResponse being processed by the calling Thread.
381         * The output of the target resources processing of the request is written
382         * directly to the current JspWriter returned by a call to getOut().
383         * </p>
384         * <p>
385         * If flush is true, The current JspWriter "out" for this JSP 
386         * is flushed as a side-effect of this call, prior to processing 
387         * the include.  Otherwise, the JspWriter "out" is not flushed.
388         * </p>
389         * <p>
390         * If the <i>relativeUrlPath</i> begins with a "/" then the URL specified
391         * is calculated relative to the DOCROOT of the <code>ServletContext</code>
392         * for this JSP. If the path does not begin with a "/" then the URL 
393         * specified is calculated relative to the URL of the request that was
394         * mapped to the calling JSP.
395         * </p>
396         * <p>
397         * It is only valid to call this method from a <code> Thread </code>
398         * executing within a <code> _jspService(...) </code> method of a JSP.
399         * </p>
400         *
401         * @param relativeUrlPath specifies the relative URL path to the 
402         *     target resource to be included
403         * @param flush True if the JspWriter is to be flushed before the include,
404         *     or false if not.
405         *
406         * @throws ServletException if the page that was forwarded to throws
407         *     a ServletException
408         * @throws IOException if an I/O error occurred while forwarding
409         * @since 2.0
410         */
411        abstract public void include(String relativeUrlPath, boolean flush) 
412            throws ServletException, IOException;
413    
414        /**
415         * <p>
416         * This method is intended to process an unhandled 'page' level
417         * exception by forwarding the exception to the specified
418         * error page for this JSP.  If forwarding is not possible (for
419         * example because the response has already been committed), an
420         * implementation dependent mechanism should be used to invoke
421         * the error page (e.g. "including" the error page instead).
422         *
423         * <p>
424         * If no error page is defined in the page, the exception should
425         * be rethrown so that the standard servlet error handling
426         * takes over.
427         *
428         * <p>
429         * A JSP implementation class shall typically clean up any local state
430         * prior to invoking this and will return immediately thereafter. It is
431         * illegal to generate any output to the client, or to modify any 
432         * ServletResponse state after invoking this call.
433         *
434         * <p>
435         * This method is kept for backwards compatiblity reasons.  Newly
436         * generated code should use PageContext.handlePageException(Throwable).
437         *
438         * @param e the exception to be handled
439         *
440         * @throws ServletException if an error occurs while invoking the error page
441         * @throws IOException if an I/O error occurred while invoking the error
442         *     page
443         * @throws NullPointerException if the exception is null
444         *
445         * @see #handlePageException(Throwable)
446         */
447    
448        abstract public void handlePageException(Exception e) 
449            throws ServletException, IOException;
450    
451        /**
452         * <p>
453         * This method is intended to process an unhandled 'page' level
454         * exception by forwarding the exception to the specified
455         * error page for this JSP.  If forwarding is not possible (for
456         * example because the response has already been committed), an
457         * implementation dependent mechanism should be used to invoke
458         * the error page (e.g. "including" the error page instead).
459         *
460         * <p>
461         * If no error page is defined in the page, the exception should
462         * be rethrown so that the standard servlet error handling
463         * takes over.
464         *
465         * <p>
466         * This method is intended to process an unhandled "page" level exception
467         * by redirecting the exception to either the specified error page for this
468         * JSP, or if none was specified, to perform some implementation dependent
469         * action.
470         *
471         * <p>
472         * A JSP implementation class shall typically clean up any local state
473         * prior to invoking this and will return immediately thereafter. It is
474         * illegal to generate any output to the client, or to modify any 
475         * ServletResponse state after invoking this call.
476         *
477         * @param t the throwable to be handled
478         *
479         * @throws ServletException if an error occurs while invoking the error page
480         * @throws IOException if an I/O error occurred while invoking the error
481         *     page
482         * @throws NullPointerException if the exception is null
483         *
484         * @see #handlePageException(Exception)
485         */
486    
487        abstract public void handlePageException(Throwable t) 
488            throws ServletException, IOException;
489    
490        /**
491         * Return a new BodyContent object, save the current "out" JspWriter,
492         * and update the value of the "out" attribute in the page scope
493         * attribute namespace of the PageContext.
494         *
495         * @return the new BodyContent
496         */
497    
498        public BodyContent pushBody() {
499            return null; // XXX to implement
500        }
501             
502    
503        /**
504         * Provides convenient access to error information.
505         *
506         * @return an ErrorData instance containing information about the 
507         * error, as obtained from the request attributes, as per the 
508         * Servlet specification.  If this is not an error page (that is,
509         * if the isErrorPage attribute of the page directive is not set
510         * to "true"), the information is meaningless.
511         *
512         * @since 2.0
513         */
514        public ErrorData getErrorData() {
515            return new ErrorData( 
516                (Throwable)getRequest().getAttribute( "javax.servlet.error.exception" ),
517                ((Integer)getRequest().getAttribute( 
518                    "javax.servlet.error.status_code" )).intValue(),
519                (String)getRequest().getAttribute( "javax.servlet.error.request_uri" ),
520                (String)getRequest().getAttribute( "javax.servlet.error.servlet_name" ) );
521        }
522        
523    }