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
015package org.apache.tapestry;
016
017import java.util.Locale;
018
019import org.apache.hivemind.ApplicationRuntimeException;
020import org.apache.tapestry.event.ChangeObserver;
021import org.apache.tapestry.event.PageAttachListener;
022import org.apache.tapestry.event.PageBeginRenderListener;
023import org.apache.tapestry.event.PageDetachListener;
024import org.apache.tapestry.event.PageEndRenderListener;
025import org.apache.tapestry.event.PageRenderListener;
026import org.apache.tapestry.event.PageValidateListener;
027import 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
040public 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}