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 org.apache.tapestry.engine.IEngineService;
018import org.apache.tapestry.engine.IMonitor;
019import org.apache.tapestry.request.RequestContext;
020import org.apache.tapestry.services.Infrastructure;
021
022/**
023 * Controller object that manages a single request cycle. A request cycle is one 'hit' on the web
024 * server. In the case of a Tapestry application, this will involve:
025 * <ul>
026 * <li>Responding to the URL by finding an {@link IEngineService}object
027 * <li>Determining the result page
028 * <li>Renderring the result page
029 * <li>Releasing any resources
030 * </ul>
031 * <p>
032 * Mixed in with this is:
033 * <ul>
034 * <li>Exception handling
035 * <li>Loading of pages and templates from resources
036 * <li>Tracking changes to page properties, and restoring pages to prior states
037 * <li>Pooling of page objects
038 * </ul>
039 * <p>
040 * A request cycle is broken up into two phases. The <em>rewind</em> phase is optional, as it tied
041 * to {@link org.apache.tapestry.link.ActionLink}or {@link org.apache.tapestry.form.Form}
042 * components. In the rewind phase, a previous page render is redone (discarding output) until a
043 * specific component of the page is reached. This rewinding ensures that the page is restored to
044 * the exact state it had when the URL for the request cycle was generated, taking into account the
045 * dynamic nature of the page ({@link org.apache.tapestry.components.Foreach},
046 * {@link org.apache.tapestry.components.Conditional}, etc.). Once this component is reached, it
047 * can notify its {@link IActionListener}. The listener has the ability to update the state of any
048 * pages and select a new result page.
049 * <p>
050 * Following the rewind phase is the <em>render</em> phase. During the render phase, a page is
051 * actually rendered and output sent to the client web browser.
052 * 
053 * @author Howard Lewis Ship
054 */
055
056public interface IRequestCycle
057{
058    /**
059     * Invoked after the request cycle is no longer needed, to release any resources it may have.
060     * This includes releasing any loaded pages back to the page source.
061     */
062
063    public void cleanup();
064
065    /**
066     * Passes the String through
067     * {@link javax.servlet.http.HttpServletResponse#encodeURL(java.lang.String)}, which ensures
068     * that the session id is encoded in the URL (if necessary).
069     */
070
071    public String encodeURL(String URL);
072
073    /**
074     * Returns the engine which is processing this request cycle.
075     */
076
077    public IEngine getEngine();
078
079    /**
080     * Retrieves a previously stored attribute, returning null if not found. Attributes allow
081     * components to locate each other; primarily they allow a wrapped component to locate a
082     * component which wraps it. Attributes are cleared at the end of the render (or rewind).
083     */
084
085    public Object getAttribute(String name);
086
087    public IMonitor getMonitor();
088
089    /**
090     * Returns the next action id. ActionLink ids are used to identify different actions on a page
091     * (URLs that are related to dynamic page state).
092     * 
093     * @deprecated To be removed in release 4.1 with no replacement.
094     * @see #getUniqueId(String)
095     */
096
097    public String getNextActionId();
098
099    /**
100     * Identifies the active page, the page which will ultimately render the response.
101     */
102
103    public IPage getPage();
104
105    /**
106     * Returns the page with the given name. If the page has been previously loaded in the current
107     * request cycle, that page is returned. Otherwise, the engine's page loader is used to load the
108     * page.
109     * 
110     * @throws PageNotFoundException
111     *             if the page does not exist.
112     * @see org.apache.tapestry.engine.IPageSource#getPage(IRequestCycle, String, IMonitor)
113     */
114
115    public IPage getPage(String name);
116
117    /**
118     * Returns true if the context is being used to rewind a prior state of the page. This is only
119     * true when there is a target action id.
120     */
121
122    public boolean isRewinding();
123
124    /**
125     * Checks to see if the current action id matches the target action id. Returns true only if
126     * they match. Returns false if there is no target action id (that is, during page rendering).
127     * <p>
128     * If theres a match on action id, then the component is compared against the target component.
129     * If there's a mismatch then a {@link StaleLinkException}is thrown.
130     */
131
132    public boolean isRewound(IComponent component) throws StaleLinkException;
133
134    /**
135     * Removes a previously stored attribute, if one with the given name exists.
136     */
137
138    public void removeAttribute(String name);
139
140    /**
141     * Renders the given page. Applications should always use this method to render the page, rather
142     * than directly invoking {@link IPage#render(IMarkupWriter, IRequestCycle)}since the request
143     * cycle must perform some setup before rendering.
144     */
145
146    public void renderPage(IMarkupWriter writer);
147
148    /**
149     * Rewinds a page and executes some form of action when the component with the specified action
150     * id is reached.
151     * 
152     * @see IAction
153     * @see org.apache.tapestry.link.ActionLink
154     * @deprecated To be removed in 4.1 with no replacement.
155     */
156
157    public void rewindPage(String targetActionId, IComponent targetComponent);
158
159    /**
160     * Allows a temporary object to be stored in the request cycle, which allows otherwise unrelated
161     * objects to communicate. This is similar to <code>HttpServletRequest.setAttribute()</code>,
162     * except that values can be changed and removed as well.
163     * <p>
164     * This is used by components to locate each other. A component, such as
165     * {@link org.apache.tapestry.html.Body}, will write itself under a well-known name into the
166     * request cycle, and components it wraps can locate it by that name.
167     * <p>
168     * Attributes are cleared at the end of each render or rewind phase.
169     */
170
171    public void setAttribute(String name, Object value);
172
173    /**
174     * Invoked just before rendering the response page to get all
175     * {@link org.apache.tapestry.engine.IPageRecorder page recorders}touched in this request cycle
176     * to commit their changes (save them to persistant storage).
177     * 
178     * @see org.apache.tapestry.engine.IPageRecorder#commit()
179     */
180
181    public void commitPageChanges();
182
183    /**
184     * Returns the service which initiated this request cycle.
185     * 
186     * @since 1.0.1
187     */
188
189    public IEngineService getService();
190
191    /**
192     * Used by {@link IForm forms}to perform a <em>partial</em> rewind so as to respond to the
193     * form submission (using the direct service).
194     * <p>
195     * Note: the targetActionId parameter was removed in release 4.0.
196     * 
197     * @since 1.0.2
198     */
199
200    public void rewindForm(IForm form);
201
202    /**
203     * Much like {@link #forgetPage(String)}, but the page stays active and can even record
204     * changes, until the end of the request cycle, at which point it is discarded (and any recorded
205     * changes are lost). This is used in certain rare cases where a page has persistent state but
206     * is being renderred "for the last time".
207     * 
208     * @since 2.0.2
209     * @deprecated To be removed in 4.1. Use {@link #forgetPage(String)}.
210     */
211
212    public void discardPage(String name);
213
214    /**
215     * Invoked by a {@link IEngineService service}&nbsp;to store an array of application-specific
216     * parameters. These can later be retrieved (typically, by an application-specific listener
217     * method) by invoking {@link #getServiceParameters()}.
218     * <p>
219     * Through release 2.1, parameters was of type String[]. This is an incompatible change in 2.2.
220     * 
221     * @see org.apache.tapestry.engine.DirectService
222     * @since 2.0.3
223     * @deprecated To be removed in 4.1. Use {@link #setListenerParameters(Object[])}instead.
224     */
225
226    public void setServiceParameters(Object[] parameters);
227
228    /**
229     * Invoked by a {@link IEngineService service}&nbsp;to store an array of application-specific
230     * parameters. These can later be retrieved (typically, by an application-specific listener
231     * method) by invoking {@link #getListenerParameters()}.
232     * 
233     * @see org.apache.tapestry.engine.DirectService
234     * @since 4.0
235     */
236    public void setListenerParameters(Object[] parameters);
237
238    /**
239     * Returns parameters previously stored by {@link #setServiceParameters(Object[])}.
240     * <p>
241     * Through release 2.1, the return type was String[]. This is an incompatible change in 2.2.
242     * 
243     * @since 2.0.3
244     * @deprecated To be removed in 4.1. Use {@link #getListenerParameters()}instead.
245     */
246
247    public Object[] getServiceParameters();
248
249    /**
250     * Returns parameters previously stored by {@link #setListenerParameters(Object[])}.
251     * 
252     * @since 4.0
253     */
254
255    public Object[] getListenerParameters();
256
257    /**
258     * A convienience for invoking {@link #activate(IPage)}. Invokes {@link #getPage(String)}to
259     * get an instance of the named page.
260     * 
261     * @since 3.0
262     */
263
264    public void activate(String name);
265
266    /**
267     * Sets the active page for the request. The active page is the page which will ultimately
268     * render the response. The activate page is typically set by the {@link IEngineService service}.
269     * Frequently, the active page is changed (from a listener method) to choose an alternate page
270     * to render the response).
271     * <p>
272     * {@link IPage#validate(IRequestCycle)}is invoked on the page to be activated.
273     * {@link PageRedirectException}is caught and the page specified in the exception will be the
274     * active page instead (that is, a page may "pass the baton" to another page using the
275     * exception). The new page is also validated. This continues until a page does not throw
276     * {@link PageRedirectException}.
277     * <p>
278     * Validation loops can occur, where page A redirects to page B and then page B redirects back
279     * to page A (possibly with intermediate steps). This is detected and results in an
280     * {@link ApplicationRuntimeException}.
281     * 
282     * @since 3.0
283     */
284    public void activate(IPage page);
285
286    /**
287     * Returns a query parameter value, or null if not provided in the request. If multiple values
288     * are provided, returns the first value.
289     * 
290     * @since 4.0
291     */
292    public String getParameter(String name);
293
294    /**
295     * Returns all query parameter values for the given name. Returns null if no values were
296     * provided.
297     * 
298     * @since 4.0
299     */
300    public String[] getParameters(String name);
301
302    /**
303     * Converts a partial URL into an absolute URL. Prefixes the provided URL with servlet context
304     * path (if any), then expands it to a full URL by prepending with the scheme, server and port
305     * (determined from the current {@link org.apache.tapestry.web.WebRequest request}.
306     * 
307     * @since 4.0
308     */
309
310    public String getAbsoluteURL(String partialURL);
311
312    /**
313     * Forgets any stored changes to the specified page. If the page has already been loaded (and
314     * rolled back) then the loaded page instance is not affected; if the page is only loaded
315     * subsequently, the page instance will not see any persisted property changes.
316     * 
317     * @since 4.0
318     */
319
320    public void forgetPage(String name);
321
322    /**
323     * Returns the central {@link org.apache.tapestry.services.Infrastructure}&nbsp;object used to
324     * manage the processing of the request.
325     * 
326     * @since 4.0
327     */
328
329    public Infrastructure getInfrastructure();
330
331    /**
332     * Returns the {@link RequestContext}. This is provided to ease the upgrade from Tapestry 3.0.
333     * 
334     * @deprecated To be removed in 4.1.
335     */
336
337    public RequestContext getRequestContext();
338
339    /**
340     * Returns the provided string, possibly modified (with an appended suffix) to make it unique.
341     * 
342     * @param baseId
343     *            the base id from which to generate the unique string.
344     * @return baseId, or baseId with a suffix appended (if the method has been previously invoked
345     *         with the same baseId).
346     */
347
348    public String getUniqueId(String baseId);
349
350    /**
351     * Sends a redirect to the client web browser. This is currently a convinience for constructing
352     * and throwing a {@link RedirectException}, but may change in a later release.
353     * 
354     * @since 4.0
355     * @throws RedirectException
356     */
357
358    public void sendRedirect(String URL);
359}