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 java.util.Collection;
018    import java.util.Map;
019    
020    import org.apache.hivemind.LocationHolder;
021    import org.apache.hivemind.Messages;
022    import org.apache.tapestry.engine.IPageLoader;
023    import org.apache.tapestry.listener.ListenerMap;
024    import org.apache.tapestry.spec.IComponentSpecification;
025    import org.apache.tapestry.spec.IContainedComponent;
026    
027    /**
028     * Defines an object which may be used to provide dynamic content on a Tapestry web page.
029     * <p>
030     * Components are created dynamically from thier class names (part of the
031     * {@link IComponentSpecification}).
032     * 
033     * @author Howard Leiws Ship
034     */
035    
036    public interface IComponent extends IRender, LocationHolder
037    {
038    
039        /**
040         * Adds an asset to the component. This is invoked from the page loader.
041         */
042    
043        public void addAsset(String name, IAsset asset);
044    
045        /**
046         * Adds a component to a container. Should only be called during the page loading process, which
047         * is responsible for any checking.
048         * 
049         * @see IPageLoader
050         */
051    
052        public void addComponent(IComponent component);
053    
054        /**
055         * Adds a new renderable element to the receiver's body. The element may be either another
056         * component, or static HTML. Such elements come from inside the receiver's tag within its
057         * container's template, and represent static text and other components.
058         * <p>
059         * The method {@link #renderBody(IMarkupWriter, IRequestCycle)}is used to render these
060         * elements.
061         * 
062         * @since 2.2
063         */
064    
065        public void addBody(IRender element);
066    
067        /**
068         * Returns the asset map for the component, which may be empty but will not be null.
069         * <p>
070         * The return value is unmodifiable.
071         */
072    
073        public Map getAssets();
074    
075        /**
076         * Returns the named asset, or null if not found.
077         */
078    
079        public IAsset getAsset(String name);
080    
081        /**
082         * Returns the binding with the given name or null if not found.
083         * <p>
084         * Bindings are added to a component using {@link #setBinding(String,IBinding)}.
085         */
086    
087        public IBinding getBinding(String name);
088    
089        /**
090         * Returns a {@link Collection}of the names of all bindings (which includes bindings for both
091         * formal and informal parameters).
092         * <p>
093         * The return value is unmodifiable. It will be null for a {@link IPage page}, or may simply be
094         * empty for a component with no bindings.
095         */
096    
097        public Collection getBindingNames();
098    
099        /**
100         * Returns a {@link Map}of the {@link IBinding bindings}for this component; this includes
101         * informal parameters as well as formal bindings.
102         * 
103         * @since 1.0.5
104         */
105    
106        public Map getBindings();
107    
108        /**
109         * Retrieves an contained component by its id. Contained components have unique ids within their
110         * container.
111         * 
112         * @exception ApplicationRuntimeException
113         *                runtime exception thrown if the named component does not exist.
114         */
115    
116        public IComponent getComponent(String id);
117    
118        /**
119         * Returns the component which embeds the receiver. All components are contained within other
120         * components, with the exception of the root page component.
121         * <p>
122         * A page returns null.
123         */
124    
125        public IComponent getContainer();
126    
127        /**
128         * Sets the container of the component. This is write-once, an attempt to change it later will
129         * throw an {@link ApplicationRuntimeException}.
130         */
131    
132        public void setContainer(IComponent value);
133    
134        /**
135         * Returns a string identifying the name of the page and the id path of the reciever within the
136         * page (seperated by a slash). Note that this extended id is indetned primarily for identifying
137         * the component to the user (since slashes are legal characters within page names). Pages
138         * simply return their name.
139         * 
140         * @see #getIdPath()
141         */
142    
143        public String getExtendedId();
144    
145        /**
146         * Returns the simple id of the component, as defined in its specification.
147         * <p>
148         * An id will be unique within the component which contains this component.
149         * <p>
150         * A {@link IPage page}will always return null.
151         */
152    
153        public String getId();
154    
155        /**
156         * Sets the id of the component. This is write-once, an attempt to change it later will throw an
157         * {@link ApplicationRuntimeException}.
158         */
159    
160        public void setId(String value);
161    
162        /**
163         * Returns the qualified id of the component. This represents a path from the {@link IPage page}
164         * to this component, showing how components contain each other.
165         * <p>
166         * A {@link IPage page}will always return null. A component contained on a page returns its
167         * simple id. Other components return their container's id path followed by a period and their
168         * own name.
169         * 
170         * @see #getId()
171         */
172    
173        public String getIdPath();
174    
175        /**
176         * Returns the page which ultimately contains the receiver. A page will return itself.
177         */
178    
179        public IPage getPage();
180    
181        /**
182         * Sets the page which ultimiately contains the component. This is write-once, an attempt to
183         * change it later will throw an {@link ApplicationRuntimeException}.
184         */
185    
186        public void setPage(IPage value);
187    
188        /**
189         * Returns the specification which defines the component.
190         */
191    
192        public IComponentSpecification getSpecification();
193    
194        /**
195         * Invoked to make the receiver render its body (the elements and components its tag wraps
196         * around, on its container's template). This method is public so that the
197         * {@link org.apache.tapestry.components.RenderBody}component may operate.
198         * 
199         * @since 2.2
200         */
201    
202        public void renderBody(IMarkupWriter writer, IRequestCycle cycle);
203    
204        /**
205         * Adds a binding to a container. Should only be called during the page loading process (which
206         * is responsible for eror checking).
207         * 
208         * @see IPageLoader
209         */
210    
211        public void setBinding(String name, IBinding binding);
212    
213        /**
214         * Returns the contained components as an unmodifiable {@link Map}. This allows peer components
215         * to work together without directly involving their container ... the classic example is to
216         * have an {@link org.apache.tapestry.components.Insert}work with an enclosing
217         * {@link org.apache.tapestry.components.Foreach}.
218         * <p>
219         * This is late addition to Tapestry, because it also opens the door to abuse, since it is quite
220         * possible to break the "black box" aspect of a component by interacting directly with
221         * components it embeds. This creates ugly interelationships between components that should be
222         * seperated.
223         * 
224         * @return A Map of components keyed on component id. May return an empty map, but won't return
225         *         null.
226         */
227    
228        public Map getComponents();
229    
230        /**
231         * Allows a component to finish any setup after it has been constructed.
232         * <p>
233         * The exact timing is not specified, but any components contained by the receiving component
234         * will also have been constructed before this method is invoked.
235         * <p>
236         * As of release 1.0.6, this method is invoked <em>before</em> bindings are set. This should
237         * not affect anything, as bindings should only be used during renderring.
238         * <p>
239         * Release 2.2 added the cycle parameter which is, regretfully, not backwards compatible.
240         * 
241         * @since 0.2.12
242         */
243    
244        public void finishLoad(IRequestCycle cycle, IPageLoader loader,
245                IComponentSpecification specification);
246    
247        /**
248         * Returns component strings for the component. Starting in release 4.0, this method is
249         * unimplemented (and is automatically injected into each component implementation).
250         * 
251         * @since 3.0
252         */
253    
254        public Messages getMessages();
255    
256        /**
257         * Returns the {@link INamespace}in which the component was defined (as an alias).
258         * 
259         * @since 2.2
260         */
261    
262        public INamespace getNamespace();
263    
264        /**
265         * Sets the {@link INamespace}for the component. The namespace should only be set once.
266         * 
267         * @since 2.2
268         */
269    
270        public void setNamespace(INamespace namespace);
271    
272        /**
273         * Sets a property of a component.
274         * 
275         * @param propertyName
276         *            the property name
277         * @param value
278         *            the provided value
279         * @deprecated To be removed in 4.1. Use
280         *             {@link org.apache.hivemind.util.PropertyUtils#read(java.lang.Object, java.lang.String) instead.
281         */
282        public void setProperty(String propertyName, Object value);
283    
284        /**
285         * Gets a property of a component.
286         * 
287         * @param propertyName
288         *            the property name
289         * @return Object the value of property
290         * @deprecated To be removed in 4.1. Use
291         *             {@link org.apache.hivemind.util.PropertyUtils#read(java.lang.Object, java.lang.String)}
292         *             instead
293         */
294        public Object getProperty(String propertyName);
295    
296        /**
297         * Returns true if the component is currently rendering.
298         * 
299         * @since 4.0
300         */
301    
302        public boolean isRendering();
303    
304        /**
305         * Invoked after {@link #finishLoad(IRequestCycle, IPageLoader, IComponentSpecification)}to
306         * switch the component from its initial construction state into its active state. The
307         * difference concerns parameters, whose defaults values may be set from inside
308         * {@link #finishLoad(IRequestCycle, IPageLoader, IComponentSpecification)}.
309         * 
310         * @since 4.0
311         */
312    
313        public void enterActiveState();
314    
315        /**
316         * Returns a {@link IBeanProvider} from which managed beans can be obtained.
317         * 
318         * @since 4.0
319         */
320    
321        public IBeanProvider getBeans();
322    
323        /**
324         * Returns a {@link ListenerMap} for the component. The map contains a number of synthetic
325         * read-only properties that implement the {@link IActionListener} interface, but in fact, cause
326         * public instance methods to be invoked (via reflection).
327         * 
328         * @since 4.0
329         */
330    
331        public ListenerMap getListeners();
332    
333        /**
334         * Returns a localized string message. Each component has an optional set of localized message
335         * strings that are read from properties files.
336         * 
337         * @param key
338         *            the key used to locate the message
339         * @return the localized message for the key, or a placeholder if no message is defined for the
340         *         key.
341         * @since 3.0
342         * @deprecated To be removed in release 4.1. Use {@link #getMessages()} instead.
343         */
344    
345        public String getMessage(String key);
346    
347        /**
348         * Returns the {@link org.apache.tapestry.spec.IContainedComponent}. This will be null for
349         * pages. This property is set when a component is constructed, and links the component instance
350         * to the reference in the containing page or component's template or specification. This is
351         * useful to allow a component to know its type or the meta-data associated with the component.
352         * 
353         * @return the contained component, or null for a page.
354         * @since 4.0
355         */
356    
357        public IContainedComponent getContainedComponent();
358    
359        /**
360         * Sets the {@link #getContainedComponent()} property; this may only be done once.
361         * 
362         * @param containedComponent
363         *            may not be null
364         * @since 4.0
365         */
366        public void setContainedComponent(IContainedComponent containedComponent);
367    }