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.hivemind.LocationHolder; 019 import org.apache.hivemind.Messages; 020 import org.apache.tapestry.engine.IPageLoader; 021 import org.apache.tapestry.form.IFormComponent; 022 import org.apache.tapestry.internal.event.IComponentEventInvoker; 023 import org.apache.tapestry.listener.ListenerMap; 024 import org.apache.tapestry.spec.IComponentSpecification; 025 import org.apache.tapestry.spec.IContainedComponent; 026 027 import java.util.Collection; 028 import java.util.Map; 029 030 /** 031 * Defines an object which may be used to provide dynamic content on a Tapestry web page. 032 * <p> 033 * Components are created dynamically from thier class names (part of the 034 * {@link IComponentSpecification}). 035 * 036 * @author Howard Lewis Ship 037 */ 038 039 public interface IComponent extends IRender, LocationHolder 040 { 041 042 /** 043 * Adds an asset to the component. This is invoked from the page loader. 044 * 045 * @param name 046 * The lookup name the asset will be bound to and referenacable as. 047 * @param asset 048 * The asset to add. 049 */ 050 051 void addAsset(String name, IAsset asset); 052 053 /** 054 * Adds a component to a container. Should only be called during the page loading process, which 055 * is responsible for doing all the necessary work of managing component state. 056 * 057 * @param component 058 * The component to add. 059 * @see IPageLoader 060 */ 061 062 void addComponent(IComponent component); 063 064 /** 065 * Adds a new renderable element to the receiver's body. The element may be either another 066 * component, or static HTML. Such elements come from inside the receiver's tag within its 067 * container's template, and represent static text and other components. 068 * <p> 069 * The method {@link #renderBody(IMarkupWriter, IRequestCycle)}is used to render these 070 * elements. 071 * 072 * @since 2.2 073 */ 074 075 void addBody(IRender element); 076 077 /** 078 * Returns the asset map for the component, which may be empty but will not be null. 079 * <p> 080 * The return value is unmodifiable. 081 */ 082 083 Map getAssets(); 084 085 /** 086 * Returns the named asset, or null if not found. 087 */ 088 089 IAsset getAsset(String name); 090 091 /** 092 * Returns the binding with the given name or null if not found. 093 * <p> 094 * Bindings are added to a component using {@link #setBinding(String,IBinding)}. 095 */ 096 097 IBinding getBinding(String name); 098 099 /** 100 * Returns a {@link Collection}of the names of all bindings (which includes bindings for both 101 * formal and informal parameters). 102 * <p> 103 * The return value is unmodifiable. It will be null for a {@link IPage page}, or may simply be 104 * empty for a component with no bindings. 105 */ 106 107 Collection getBindingNames(); 108 109 /** 110 * Returns a {@link Map}of the {@link IBinding bindings}for this component; this includes 111 * informal parameters as well as formal bindings. 112 * 113 * @since 1.0.5 114 */ 115 116 Map getBindings(); 117 118 /** 119 * Retrieves an contained component by its id. Contained components have unique ids within their 120 * container. 121 * 122 * @exception ApplicationRuntimeException 123 * runtime exception thrown if the named component does not exist. 124 */ 125 126 IComponent getComponent(String id); 127 128 /** 129 * Returns the component which embeds the receiver. All components are contained within other 130 * components, with the exception of the root page component. 131 * <p> 132 * A page returns null. 133 */ 134 135 IComponent getContainer(); 136 137 /** 138 * Sets the container of the component. This is write-once, an attempt to change it later will 139 * throw an {@link ApplicationRuntimeException}. 140 */ 141 142 void setContainer(IComponent value); 143 144 /** 145 * Returns a string identifying the name of the page and the id path of the reciever within the 146 * page (seperated by a slash). Note that this extended id is indetned primarily for identifying 147 * the component to the user (since slashes are legal characters within page names). Pages 148 * simply return their name. 149 * 150 * @see #getIdPath() 151 */ 152 153 String getExtendedId(); 154 155 /** 156 * Returns the simple id of the component, as defined in its specification. 157 * <p> 158 * An id will be unique within the component which contains this component. 159 * <p> 160 * A {@link IPage page}will always return null. 161 */ 162 163 String getId(); 164 165 /** 166 * Sets the id of the component. This is write-once, an attempt to change it later will throw an 167 * {@link ApplicationRuntimeException}. 168 */ 169 170 void setId(String value); 171 172 /** 173 * Returns either the normal {@link #getId()} value OR the value of any binding 174 * named <code>id</code> - if one exists. Higher precedence is given to bound id values. 175 * 176 * @return The bound or normal component id, or null if neither exists. 177 */ 178 179 String getSpecifiedId(); 180 181 /** 182 * Returns the qualified id of the component. This represents a path from the {@link IPage page} 183 * to this component, showing how components contain each other. 184 * <p> 185 * A {@link IPage page}will always return null. A component contained on a page returns its 186 * simple id. Other components return their container's id path followed by a period and their 187 * own name. 188 * 189 * @see #getId() 190 */ 191 192 String getIdPath(); 193 194 /** 195 * Returns the component's client-side element id. This has traditionally been an 196 * {@link IFormComponent} only binding but now applies to all components. The method 197 * should check to see if any id parameter/property has been set already and use that 198 * above all others, falling back to {@link #getId()} if nothing else is found. 199 * 200 * @return the id, or null if the component doesn't support a client id. 201 * @since 4.1 202 */ 203 String getClientId(); 204 205 /** 206 * Sets the client ID. It is <strong>strongly</strong> discouraged for you to try 207 * setting this unless you understand the ramifications of how the rest of the system 208 * relies on this functioning. 209 * 210 * @param id The client id to set. 211 */ 212 void setClientId(String id); 213 214 /** 215 * Used internally to "peek" at what the next generated client id will be for this 216 * component when it renders. Similar to the logic found in {@link IRequestCycle#peekUniqueId(String)}. 217 * 218 * @return The next possible client ID for this component. 219 */ 220 String peekClientId(); 221 222 /** 223 * Though most component implementations ignore the specific html tag used 224 * to reference a component, this value may be used for those components that 225 * do wish to use the same tag that was provided when rendering a component. 226 * 227 * <p>Example:<br/> 228 * <pre> 229 * <fieldset jwcid="@If" condition="true" > 230 * <input type="text" /> 231 * </fieldset> 232 * </pre> 233 * </p> 234 * 235 * <p> 236 * In the example above, the value of the template tag would be "fieldset" for 237 * the If component. 238 * </p> 239 * 240 * @return The html element tag name originally specified when referencing 241 * the component. 242 * @since 4.1 243 */ 244 String getTemplateTagName(); 245 246 /** 247 * Sets the template tag name used to reference this component. 248 * 249 * <p> 250 * Set by the component template loader automatically, people shouldn't 251 * normally have any reason to try setting this. 252 * </p> 253 * 254 * @param tag The tag name to set. 255 */ 256 void setTemplateTagName(String tag); 257 258 /** 259 * Returns the page which ultimately contains the receiver. A page will return itself. 260 */ 261 262 IPage getPage(); 263 264 /** 265 * Sets the page which ultimiately contains the component. This is write-once, an attempt to 266 * change it later will throw an {@link ApplicationRuntimeException}. 267 */ 268 269 void setPage(IPage value); 270 271 /** 272 * Returns the specification which defines the component. 273 */ 274 275 IComponentSpecification getSpecification(); 276 277 /** 278 * Invoked to make the receiver render its body (the elements and components its tag wraps 279 * around, on its container's template). This method is public so that the 280 * {@link org.apache.tapestry.components.RenderBody}component may operate. 281 * 282 * @since 2.2 283 */ 284 285 void renderBody(IMarkupWriter writer, IRequestCycle cycle); 286 287 /** 288 * Adds a binding to a container. Should only be called during the page loading process (which 289 * is responsible for eror checking). 290 * 291 * @see IPageLoader 292 */ 293 294 void setBinding(String name, IBinding binding); 295 296 /** 297 * Returns the contained components as an unmodifiable {@link Map}. This allows peer components 298 * to work together without directly involving their container ... the classic example is to 299 * have an {@link org.apache.tapestry.components.Insert}work with an enclosing 300 * {@link org.apache.tapestry.components.ForBean}. 301 * <p> 302 * This is late addition to Tapestry, because it also opens the door to abuse, since it is quite 303 * possible to break the "black box" aspect of a component by interacting directly with 304 * components it embeds. This creates ugly interelationships between components that should be 305 * seperated. 306 * 307 * @return A Map of components keyed on component id. May return an empty map, but won't return 308 * null. 309 */ 310 311 Map getComponents(); 312 313 /** 314 * Allows a component to finish any setup after it has been constructed. 315 * <p> 316 * The exact timing is not specified, but any components contained by the receiving component 317 * will also have been constructed before this method is invoked. 318 * 319 * @since 0.2.12 320 */ 321 322 void finishLoad(IRequestCycle cycle, IPageLoader loader, IComponentSpecification specification); 323 324 /** 325 * Returns component strings for the component. Starting in release 4.0, this method is 326 * unimplemented (and is automatically injected into each component implementation). 327 * 328 * @since 3.0 329 */ 330 331 Messages getMessages(); 332 333 /** 334 * Returns the {@link INamespace}in which the component was defined (as an alias). 335 * 336 * @since 2.2 337 */ 338 339 INamespace getNamespace(); 340 341 /** 342 * Sets the {@link INamespace}for the component. The namespace should only be set once. 343 * 344 * @since 2.2 345 */ 346 347 void setNamespace(INamespace namespace); 348 349 /** 350 * Returns true if the component is currently rendering. 351 * 352 * @since 4.0 353 */ 354 355 boolean isRendering(); 356 357 /** 358 * Invoked after {@link #finishLoad(IRequestCycle, IPageLoader, IComponentSpecification)}to 359 * switch the component from its initial construction state into its active state. The 360 * difference concerns parameters, whose defaults values may be set from inside 361 * {@link #finishLoad(IRequestCycle, IPageLoader, IComponentSpecification)}. 362 * 363 * @since 4.0 364 */ 365 366 void enterActiveState(); 367 368 /** 369 * Returns a {@link IBeanProvider} from which managed beans can be obtained. 370 * 371 * @since 4.0 372 */ 373 374 IBeanProvider getBeans(); 375 376 /** 377 * Returns a {@link ListenerMap} for the component. The map contains a number of synthetic 378 * read-only properties that implement the {@link IActionListener} interface, but in fact, cause 379 * public instance methods to be invoked (via reflection). 380 * 381 * @since 4.0 382 */ 383 384 ListenerMap getListeners(); 385 386 /** 387 * Returns the {@link org.apache.tapestry.spec.IContainedComponent}. This will be null for 388 * pages. This property is set when a component is constructed, and links the component instance 389 * to the reference in the containing page or component's template or specification. This is 390 * useful to allow a component to know its type or the meta-data associated with the component. 391 * 392 * @return the contained component, or null for a page. 393 * @since 4.0 394 */ 395 396 IContainedComponent getContainedComponent(); 397 398 /** 399 * Sets the {@link #getContainedComponent()} property; this may only be done once. 400 * 401 * @param containedComponent 402 * may not be null 403 * @since 4.0 404 */ 405 void setContainedComponent(IContainedComponent containedComponent); 406 407 /** 408 * Returns the event connection manager services that handles creating/accepting 409 * browser events associated with various properties of components. 410 * 411 * @return eventInvoker, may not be null 412 * @since 4.1 413 */ 414 IComponentEventInvoker getEventInvoker(); 415 }