001    // Copyright 2004, 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry;
016    
017    import java.util.Locale;
018    
019    import org.apache.tapestry.event.ChangeObserver;
020    import org.apache.tapestry.event.PageAttachListener;
021    import org.apache.tapestry.event.PageBeginRenderListener;
022    import org.apache.tapestry.event.PageDetachListener;
023    import org.apache.tapestry.event.PageEndRenderListener;
024    import org.apache.tapestry.event.PageRenderListener;
025    import org.apache.tapestry.event.PageValidateListener;
026    import org.apache.tapestry.util.ContentType;
027    
028    /**
029     * A root level component responsible for generating an entire a page within the application.
030     * <p>
031     * Pages are created dynamically from thier class names (part of the
032     * {@link org.apache.tapestry.spec.IComponentSpecification}).
033     * 
034     * @see org.apache.tapestry.engine.IPageSource
035     * @see org.apache.tapestry.engine.IPageLoader
036     * @author Howard Lewis Ship
037     */
038    
039    public interface IPage extends IComponent
040    {
041        /**
042         * Invoked on a page when it is no longer needed by the engine, just before is is returned to
043         * the pool. The page is expected to null the engine, visit and changeObserver properties.
044         * <p>
045         * Classes should also reset any properties to default values (as if the instance was freshly
046         * instantiated).
047         * 
048         * @see org.apache.tapestry.engine.IPageSource#releasePage(IPage)
049         */
050    
051        public void detach();
052    
053        /**
054         * Returns the {@link IEngine}that the page is currently attached to.
055         */
056    
057        public IEngine getEngine();
058    
059        /**
060         * Returns the object (effectively, an {@link org.apache.tapestry.engine.IPageRecorder}) that
061         * is notified of any changes to persistant properties of the page.
062         */
063    
064        public ChangeObserver getChangeObserver();
065    
066        /**
067         * Returns the <code>Locale</code> of the page. The locale may be used to determine what
068         * template is used by the page and the components contained by the page.
069         */
070    
071        public Locale getLocale();
072    
073        /**
074         * Updates the page's locale. This is write-once, a subsequent attempt will throw an
075         * {@link ApplicationRuntimeException}.
076         */
077    
078        public void setLocale(Locale value);
079    
080        /**
081         * Returns the fully qualified name of the page, including its namespace prefix, if any.
082         * 
083         * @since 2.3
084         */
085    
086        public String getPageName();
087    
088        /**
089         * Sets the name of the page.
090         * 
091         * @param pageName
092         *            fully qualified page name (including namespace prefix, if any)
093         * @since 3.0
094         */
095    
096        public void setPageName(String pageName);
097    
098        /**
099         * Returns a particular component from within the page. The path is a dotted name sequence
100         * identifying the component. It may be null in which case the page returns itself.
101         * 
102         * @exception ApplicationRuntimeException
103         *                runtime exception thrown if the path does not identify a component.
104         */
105    
106        public IComponent getNestedComponent(String path);
107    
108        /**
109         * Attaches the page to the {@link IEngine engine}. This method is used when a pooled page is
110         * claimed for use with a particular engine; it will stay attached to the engine until the end
111         * of the current request cycle, then be returned to the pool.
112         * <p>
113         * This method will notify any {@link PageAttachListener}s.
114         * <p>
115         * This method is rarely overriden; to initialize page properties before a render, implement the
116         * {@link PageBeginRenderListener}interface.
117         */
118    
119        public void attach(IEngine engine, IRequestCycle cycle);
120    
121        /**
122         * Invoked to render the entire page. This should only be invoked by
123         * {@link IRequestCycle#renderPage(IMarkupWriter writer)}.
124         * <p>
125         * The page performs a render using the following steps:
126         * <ul>
127         * <li>Invokes
128         * {@link PageBeginRenderListener#pageBeginRender(org.apache.tapestry.event.PageEvent)}
129         * <li>Invokes {@link #beginResponse(IMarkupWriter, IRequestCycle)}
130         * <li>Invokes {@link IRequestCycle#commitPageChanges()}(if not rewinding)
131         * <li>Invokes {@link #render(IMarkupWriter, IRequestCycle)}
132         * <li>Invokes {@link PageEndRenderListener#pageEndRender(org.apache.tapestry.event.PageEvent)}
133         * (this occurs even if a previous step throws an exception).
134         * </ul>
135         */
136    
137        public void renderPage(IMarkupWriter writer, IRequestCycle cycle);
138    
139        /**
140         * Invoked before a partial render of the page occurs (this happens when rewinding a
141         * {@link org.apache.tapestry.form.Form}within the page). The page is expected to fire
142         * appopriate events.
143         * 
144         * @since 2.2
145         */
146    
147        public void beginPageRender();
148    
149        /**
150         * Invoked after a partial render of the page occurs (this happens when rewinding a
151         * {@link org.apache.tapestry.form.Form}within the page). The page is expected to fire
152         * appropriate events.
153         * 
154         * @since 2.2
155         */
156    
157        public void endPageRender();
158    
159        public void setChangeObserver(ChangeObserver value);
160    
161        /**
162         * Method invoked by the page, action and direct services to validate that the user is allowed
163         * to visit the page.
164         * <p>
165         * Most web applications have a concept of 'logging in' and pages that an anonymous (not logged
166         * in) user should not be able to visit directly. This method acts as the first line of defense
167         * against a malicous user hacking URLs.
168         * <p>
169         * Pages that should be protected will typically throw a {@linkPageRedirectException}, to
170         * redirect the user to an appropriate part of the system (such as, a login page).
171         * <p>
172         * Since 3.0, it is easiest to not override this method, but to implement the
173         * {@link PageValidateListener}interface instead.
174         */
175    
176        public void validate(IRequestCycle cycle);
177    
178        /**
179         * Invoked to obtain the content type to be used for the response. The implementation of this
180         * method is the primary difference between an HTML page and an XML/WML/etc. page.
181         */
182    
183        public ContentType getResponseContentType();
184    
185        /**
186         * Invoked just before rendering of the page is initiated. This gives the page a chance to
187         * perform any additional setup. One possible behavior is to set HTTP headers and cookies before
188         * any output is generated.
189         * <p>
190         * The timing of this explicitly <em>before</em>
191         * {@link org.apache.tapestry.engine.IPageRecorder page recorder}changes are committed.
192         * Rendering occurs <em>after</em> the recorders are committed, when it is too late to make
193         * changes to dynamic page properties.
194         */
195    
196        public void beginResponse(IMarkupWriter writer, IRequestCycle cycle);
197    
198        /**
199         * Returns the current {@link IRequestCycle}. This is set when the page is loaded (or obtained
200         * from the pool) and attached to the {@link IEngine engine}.
201         */
202    
203        public IRequestCycle getRequestCycle();
204    
205        /**
206         * Returns the visit object for the application; the visit object contains application-specific
207         * information.
208         * 
209         * @deprecated To be removed in 4.1. Inject an application state object instead. <strong>Do not
210         *             attempt to inject property visit</strong>.
211         */
212    
213        public Object getVisit();
214    
215        /**
216         * Returns the globally shared application object. The global object is stored in the servlet
217         * context.
218         * <p>
219         * Returns the global object, if it exists, or null if not defined.
220         * 
221         * @since 2.3
222         * @deprecated To be removed in 4.1. Inject an application state object instead. <strong>Do not
223         *             attempt to inject property global.</strong>
224         */
225    
226        public Object getGlobal();
227    
228        /**
229         * @since 1.0.5
230         * @deprecated To be removed in 4.1 Use
231         *             {@link #addPageBeginRenderListener(PageBeginRenderListener)}or
232         *             {@link #addPageEndRenderListener(PageEndRenderListener)}.
233         */
234    
235        public void addPageRenderListener(PageRenderListener listener);
236    
237        /**
238         * @since 2.1
239         * @deprecated To be removed in 4.1. Use
240         *             {@link #removePageBeginRenderListener(PageBeginRenderListener)}or
241         *             {@link #removePageEndRenderListener(PageEndRenderListener)}.
242         */
243    
244        public void removePageRenderListener(PageRenderListener listener);
245    
246        /** @since 4.0 */
247        public void addPageBeginRenderListener(PageBeginRenderListener listener);
248    
249        /** @since 4.0 */
250        public void removePageBeginRenderListener(PageBeginRenderListener listener);
251    
252        /** @since 4.0 */
253    
254        public void addPageEndRenderListener(PageEndRenderListener listener);
255    
256        /** @since 4.0 */
257    
258        public void removePageEndRenderListener(PageEndRenderListener listener);
259    
260        /**
261         * @since 1.0.5
262         */
263    
264        public void addPageDetachListener(PageDetachListener listener);
265    
266        /**
267         * @since 2.1
268         */
269    
270        public void removePageDetachListener(PageDetachListener listener);
271    
272        /**
273         * @since 3.0
274         */
275    
276        public void addPageValidateListener(PageValidateListener listener);
277    
278        /**
279         * @since 3.0
280         */
281    
282        public void removePageValidateListener(PageValidateListener listener);
283    
284        /** @since 4.0 */
285    
286        public void addPageAttachListener(PageAttachListener listener);
287    
288        /** @since 4.0 */
289    
290        public void removePageAttachListener(PageAttachListener listener);
291    }