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
015package org.apache.tapestry;
016
017import java.util.Collection;
018import java.util.Map;
019
020import org.apache.hivemind.LocationHolder;
021import org.apache.hivemind.Messages;
022import org.apache.tapestry.engine.IPageLoader;
023import org.apache.tapestry.listener.ListenerMap;
024import org.apache.tapestry.spec.IComponentSpecification;
025import 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
036public 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}