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