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 }