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