001// Licensed under the Apache License, Version 2.0 (the "License");
002// you may not use this file except in compliance with the License.
003// You may obtain a copy of the License at
004//
005// http://www.apache.org/licenses/LICENSE-2.0
006//
007// Unless required by applicable law or agreed to in writing, software
008// distributed under the License is distributed on an "AS IS" BASIS,
009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
010// See the License for the specific language governing permissions and
011// limitations under the License.
012
013package org.apache.tapestry5;
014
015import org.apache.tapestry5.commons.AnnotationProvider;
016import org.apache.tapestry5.commons.Messages;
017import org.apache.tapestry5.commons.Resource;
018import org.apache.tapestry5.model.ComponentModel;
019import org.apache.tapestry5.runtime.Component;
020import org.apache.tapestry5.runtime.PageLifecycleCallbackHub;
021import org.apache.tapestry5.runtime.PageLifecycleListener;
022
023import java.lang.annotation.Annotation;
024import java.lang.reflect.Type;
025import java.util.List;
026
027/**
028 * Provides a component instance with the resources provided by the framework. In many circumstances, the resources
029 * object can be considered the component itself; in others, it is the {@linkplain #getComponent() component property},
030 * an instance of a class provided by the application developer (though transformed in many ways while being loaded)
031 * that is the true component. In reality, it is the combination of the resources object with the user class instance
032 * that forms the components; neither is useful without the other.
033 */
034public interface ComponentResources extends ComponentResourcesCommon
035{
036    /**
037     * Returns the base resource for the component, which will represent the class's location within the classpath (this
038     * is used to resolve relative assets).
039     */
040    Resource getBaseResource();
041
042    /**
043     * Returns the component model object that defines the behavior of the component.
044     */
045    ComponentModel getComponentModel();
046
047    /**
048     * Returns the component this object provides resources for.
049     */
050    Component getComponent();
051
052    /**
053     * Returns the component which contains this component, or null for the root component. For mixins, this returns the
054     * component to which the mixin is attached.
055     */
056    Component getContainer();
057
058    /**
059     * Returns the {@link ComponentResources} for the container, or null if the this is the root component (that has no
060     * container). As a special case, for a mixin, this returns the core component's resources.
061     */
062    ComponentResources getContainerResources();
063
064    /**
065     * Returns the {@link Messages} from the container, or null if this is the root component (with no container). As a
066     * special case, for a mixin, this return the core component's messages.
067     */
068    Messages getContainerMessages();
069
070    /**
071     * Returns the page that contains this component. Technically, the page itself is an internal object in Tapestry and
072     * this returns the root component of the actual page, but from an application developer point of view, this is the
073     * page.
074     */
075    Component getPage();
076
077    /**
078     * Returns an embedded component, given the component's id.
079     *
080     * @param embeddedId
081     *         selects the embedded component (case is ignored)
082     * @throws org.apache.tapestry5.commons.util.UnknownValueException
083     *         if this component does not contain a component with the given id
084     */
085
086    Component getEmbeddedComponent(String embeddedId);
087
088    /**
089     * Returns true if the named parameter is bound, false if not.
090     */
091    boolean isBound(String parameterName);
092
093    /**
094     * Obtains an annotation provided by a parameter.
095     *
096     * @param parameterName
097     *         name of parameter to search for the annotation
098     * @param annotationType
099     *         the type of annotation
100     * @return the annotation if found or null otherwise
101     */
102    <T extends Annotation> T getParameterAnnotation(String parameterName, Class<T> annotationType);
103
104    /**
105     * Indentifies all parameters that are not formal parameters and writes each as a attribute/value pair into the
106     * current element of the markup writer.
107     *
108     * @param writer
109     *         to which {@link MarkupWriter#attributes(Object[]) attributes} will be written
110     */
111    void renderInformalParameters(MarkupWriter writer);
112
113    /**
114     * Returns the message catalog for this component.
115     */
116    Messages getMessages();
117
118    /**
119     * Returns the actual type of the bound parameter, or null if the parameter is not bound. This is primarily used
120     * with property bindings, and is used to determine the actual type of the property, rather than the type of
121     * parameter (remember that type coercion automatically occurs, which can mask significant differences between the
122     * parameter type and the bound property type).
123     *
124     * @param parameterName
125     *         used to select the parameter (case is ignored)
126     * @return the type of the bound parameter, or null if the parameter is not bound
127     * @see Binding#getBindingType()
128     */
129    Class getBoundType(String parameterName);
130    
131    
132    /**
133     * Returns the generic type of the bound parameter, or null if the parameter is not bound. This is useful
134     * for when the parameter is bound to a generic property (eg java.util.List) to determine the element type.
135     * 
136     * @param parameterName
137     *        used to select the parameter (case is ignored)
138     * @return the generic type of the bound parameter, or null if the parameter is not bound
139     * @see Binding#getBindingType()
140     */
141    Type getBoundGenericType(String parameterName);
142
143    /**
144     * Returns an annotation provider, used to obtain annotations related to the parameter.
145     *
146     * @param parameterName
147     *         used to select the parameter (case is ignored)
148     * @return the annotation provider, or null if the parameter is not bound
149     */
150    AnnotationProvider getAnnotationProvider(String parameterName);
151
152    /**
153     * Used to access an informal parameter that's a Block.
154     *
155     * @param parameterName
156     *         the name of the informal parameter (case is ignored)
157     * @return the informal Block parameter, or null if not bound
158     */
159    Block getBlockParameter(String parameterName);
160
161    /**
162     * Returns a previously stored render variable.
163     *
164     * @param name
165     *         of the variable (case will be ignored)
166     * @return the variable's value
167     * @throws IllegalArgumentException
168     *         if the name doesn't correspond to a stored value
169     */
170    Object getRenderVariable(String name);
171
172    /**
173     * Stores a render variable, accessible with the provided name.
174     *
175     * @param name
176     *         of value to store
177     * @param value
178     *         value to store (may not be null)
179     * @throws IllegalStateException
180     *         if the component is not currently rendering
181     */
182    void storeRenderVariable(String name, Object value);
183
184    /**
185     * Adds a listener object that will be notified about page lifecycle events.
186     *
187     * @deprecated In 5.3.4, use {@link #getPageLifecycleCallbackHub()} instead
188     */
189    void addPageLifecycleListener(PageLifecycleListener listener);
190
191    /**
192     * Provides access to an object that can be used to register callbacks for page lifecycle events.
193     *
194     * @return the hub
195     * @since 5.3.4
196     */
197    PageLifecycleCallbackHub getPageLifecycleCallbackHub();
198
199    /**
200     * Removes a previously added listener.
201     *
202     * @since 5.2.0
203     * @deprecated in 5.3.4, not necessary with {@link PageLifecycleCallbackHub#addPageLoadedCallback(Runnable)}.
204     */
205    void removePageLifecycleListener(PageLifecycleListener listener);
206
207    /**
208     * Discards all persistent field changes for the page containing the component. Changes are eliminated from
209     * persistent storage (such as the {@link org.apache.tapestry5.http.services.Session}) which will take effect in the
210     * <em>next</em> request (the attached page instance is not affected).
211     */
212    void discardPersistentFieldChanges();
213
214    /**
215     * Returns the name of element that represents the component in its template, or null if not known.
216     *
217     * @return the element name or null
218     */
219    String getElementName();
220
221    /**
222     * Returns a list of the names of any informal parameters bound to this component.
223     *
224     * @return the name sorted alphabetically
225     * @see org.apache.tapestry5.annotations.SupportsInformalParameters
226     */
227    List<String> getInformalParameterNames();
228
229    /**
230     * Reads an informal parameter and {@linkplain org.apache.tapestry5.commons.services.TypeCoercer coerces} the bound
231     * value to the indicated type.
232     *
233     * @param name
234     *         name of informal parameter
235     * @param type
236     *         output value type
237     * @return instance of type
238     */
239    <T> T getInformalParameter(String name, Class<T> type);
240
241    /**
242     * Returns true if these resources represent a mixin to another component. The component is the
243     * {@linkplain #getContainerResources() container} of this resources.
244     *
245     * @since 5.2.0
246     */
247    boolean isMixin();
248}