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 }