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.tapestry.engine.IEngineService; 018 import org.apache.tapestry.engine.IMonitor; 019 import org.apache.tapestry.request.RequestContext; 020 import 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 056 public 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 094 public String getNextActionId(); 095 096 /** 097 * Identifies the active page, the page which will ultimately render the response. 098 */ 099 100 public IPage getPage(); 101 102 /** 103 * Returns the page with the given name. If the page has been previously loaded in the current 104 * request cycle, that page is returned. Otherwise, the engine's page loader is used to load the 105 * page. 106 * 107 * @throws PageNotFoundException 108 * if the page does not exist. 109 * @see org.apache.tapestry.engine.IPageSource#getPage(IRequestCycle, String, IMonitor) 110 */ 111 112 public IPage getPage(String name); 113 114 /** 115 * Returns true if the context is being used to rewind a prior state of the page. This is only 116 * true when there is a target action id. 117 */ 118 119 public boolean isRewinding(); 120 121 /** 122 * Checks to see if the current action id matches the target action id. Returns true only if 123 * they match. Returns false if there is no target action id (that is, during page rendering). 124 * <p> 125 * If theres a match on action id, then the component is compared against the target component. 126 * If there's a mismatch then a {@link StaleLinkException}is thrown. 127 */ 128 129 public boolean isRewound(IComponent component) throws StaleLinkException; 130 131 /** 132 * Removes a previously stored attribute, if one with the given name exists. 133 */ 134 135 public void removeAttribute(String name); 136 137 /** 138 * Renders the given page. Applications should always use this method to render the page, rather 139 * than directly invoking {@link IPage#render(IMarkupWriter, IRequestCycle)}since the request 140 * cycle must perform some setup before rendering. 141 */ 142 143 public void renderPage(IMarkupWriter writer); 144 145 /** 146 * Rewinds a page and executes some form of action when the component with the specified action 147 * id is reached. 148 * 149 * @see IAction 150 * @see org.apache.tapestry.link.ActionLink 151 */ 152 153 public void rewindPage(String targetActionId, IComponent targetComponent); 154 155 /** 156 * Allows a temporary object to be stored in the request cycle, which allows otherwise unrelated 157 * objects to communicate. This is similar to <code>HttpServletRequest.setAttribute()</code>, 158 * except that values can be changed and removed as well. 159 * <p> 160 * This is used by components to locate each other. A component, such as 161 * {@link org.apache.tapestry.html.Body}, will write itself under a well-known name into the 162 * request cycle, and components it wraps can locate it by that name. 163 * <p> 164 * Attributes are cleared at the end of each render or rewind phase. 165 */ 166 167 public void setAttribute(String name, Object value); 168 169 /** 170 * Invoked just before rendering the response page to get all 171 * {@link org.apache.tapestry.engine.IPageRecorder page recorders}touched in this request cycle 172 * to commit their changes (save them to persistant storage). 173 * 174 * @see org.apache.tapestry.engine.IPageRecorder#commit() 175 */ 176 177 public void commitPageChanges(); 178 179 /** 180 * Returns the service which initiated this request cycle. 181 * 182 * @since 1.0.1 183 */ 184 185 public IEngineService getService(); 186 187 /** 188 * Used by {@link IForm forms}to perform a <em>partial</em> rewind so as to respond to the 189 * form submission (using the direct service). 190 * <p> 191 * Note: the targetActionId parameter was removed in release 4.0. 192 * 193 * @since 1.0.2 194 */ 195 196 public void rewindForm(IForm form); 197 198 /** 199 * Much like {@link #forgetPage(String)}, but the page stays active and can even record 200 * changes, until the end of the request cycle, at which point it is discarded (and any recorded 201 * changes are lost). This is used in certain rare cases where a page has persistent state but 202 * is being renderred "for the last time". 203 * 204 * @since 2.0.2 205 * @deprecated To be removed in 4.1. Use {@link #forgetPage(String)}. 206 */ 207 208 public void discardPage(String name); 209 210 /** 211 * Invoked by a {@link IEngineService service} to store an array of application-specific 212 * parameters. These can later be retrieved (typically, by an application-specific listener 213 * method) by invoking {@link #getServiceParameters()}. 214 * <p> 215 * Through release 2.1, parameters was of type String[]. This is an incompatible change in 2.2. 216 * 217 * @see org.apache.tapestry.engine.DirectService 218 * @since 2.0.3 219 * @deprecated To be removed in 4.1. Use {@link #setListenerParameters(Object[])}instead. 220 */ 221 222 public void setServiceParameters(Object[] parameters); 223 224 /** 225 * Invoked by a {@link IEngineService service} to store an array of application-specific 226 * parameters. These can later be retrieved (typically, by an application-specific listener 227 * method) by invoking {@link #getListenerParameters()}. 228 * 229 * @see org.apache.tapestry.engine.DirectService 230 * @since 4.0 231 */ 232 public void setListenerParameters(Object[] parameters); 233 234 /** 235 * Returns parameters previously stored by {@link #setServiceParameters(Object[])}. 236 * <p> 237 * Through release 2.1, the return type was String[]. This is an incompatible change in 2.2. 238 * 239 * @since 2.0.3 240 * @deprecated To be removed in 4.1. Use {@link #getListenerParameters()}instead. 241 */ 242 243 public Object[] getServiceParameters(); 244 245 /** 246 * Returns parameters previously stored by {@link #setListenerParameters(Object[])}. 247 * 248 * @since 4.0 249 */ 250 251 public Object[] getListenerParameters(); 252 253 /** 254 * A convienience for invoking {@link #activate(IPage)}. Invokes {@link #getPage(String)}to 255 * get an instance of the named page. 256 * 257 * @since 3.0 258 */ 259 260 public void activate(String name); 261 262 /** 263 * Sets the active page for the request. The active page is the page which will ultimately 264 * render the response. The activate page is typically set by the {@link IEngineService service}. 265 * Frequently, the active page is changed (from a listener method) to choose an alternate page 266 * to render the response). 267 * <p> 268 * {@link IPage#validate(IRequestCycle)}is invoked on the page to be activated. 269 * {@link PageRedirectException}is caught and the page specified in the exception will be the 270 * active page instead (that is, a page may "pass the baton" to another page using the 271 * exception). The new page is also validated. This continues until a page does not throw 272 * {@link PageRedirectException}. 273 * <p> 274 * Validation loops can occur, where page A redirects to page B and then page B redirects back 275 * to page A (possibly with intermediate steps). This is detected and results in an 276 * {@link ApplicationRuntimeException}. 277 * 278 * @since 3.0 279 */ 280 public void activate(IPage page); 281 282 /** 283 * Returns a query parameter value, or null if not provided in the request. If multiple values 284 * are provided, returns the first value. 285 * 286 * @since 4.0 287 */ 288 public String getParameter(String name); 289 290 /** 291 * Returns all query parameter values for the given name. Returns null if no values were 292 * provided. 293 * 294 * @since 4.0 295 */ 296 public String[] getParameters(String name); 297 298 /** 299 * Converts a partial URL into an absolute URL. Prefixes the provided URL with servlet context 300 * path (if any), then expands it to a full URL by prepending with the scheme, server and port 301 * (determined from the current {@link org.apache.tapestry.web.WebRequest request}. 302 * 303 * @since 4.0 304 */ 305 306 public String getAbsoluteURL(String partialURL); 307 308 /** 309 * Forgets any stored changes to the specified page. If the page has already been loaded (and 310 * rolled back) then the loaded page instance is not affected; if the page is only loaded 311 * subsequently, the page instance will not see any persisted property changes. 312 * 313 * @since 4.0 314 */ 315 316 public void forgetPage(String name); 317 318 /** 319 * Returns the central {@link org.apache.tapestry.services.Infrastructure} object used to 320 * manage the processing of the request. 321 * 322 * @since 4.0 323 */ 324 325 public Infrastructure getInfrastructure(); 326 327 /** 328 * Returns the {@link RequestContext}. This is provided to ease the upgrade from Tapestry 3.0. 329 * 330 * @deprecated To be removed in 4.1. 331 */ 332 333 public RequestContext getRequestContext(); 334 335 /** 336 * Returns the provided string, possibly modified (with an appended suffix) to make it unique. 337 * 338 * @param baseId 339 * the base id from which to generate the unique string. 340 * @return baseId, or baseId with a suffix appended (if the method has been previously invoked 341 * with the same baseId). 342 */ 343 344 public String getUniqueId(String baseId); 345 346 /** 347 * Sends a redirect to the client web browser. This is currently a convinience for constructing 348 * and throwing a {@link RedirectException}, but may change in a later release. 349 * 350 * @since 4.0 351 * @throws RedirectException 352 */ 353 354 public void sendRedirect(String URL); 355 }