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