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.model;
014
015import org.apache.tapestry5.EventConstants;
016import org.apache.tapestry5.annotations.*;
017import org.apache.tapestry5.ioc.Resource;
018import org.apache.tapestry5.services.ComponentClassResolver;
019import org.apache.tapestry5.services.LibraryMapping;
020import org.slf4j.Logger;
021
022import java.util.List;
023import java.util.Set;
024
025/**
026 * Defines a component in terms of its capabilities, parameters, sub-components, etc. During <em>runtime</em>, the
027 * component model is immutable. During <em>construction</em> time, when the class is being transformed and loaded, the
028 * model is mutable.
029 *
030 * @see org.apache.tapestry5.model.MutableComponentModel
031 */
032public interface ComponentModel
033{
034    /**
035     * Returns the name of the library that defines this component; this may be the empty string for
036     * an application page or component, or will be a name of a library (possibly including "core" for built-in
037     * components).
038     * Library names are defined by the {@link LibraryMapping} contributions
039     * to the {@link ComponentClassResolver} service.
040     *
041     * @return library name containing the component, or empty string for application components
042     * @since 5.4
043     */
044    String getLibraryName();
045
046    /**
047     * Is this a model of a page (rather than a component, mixin, or base-class)?
048     *
049     * @return true if a page
050     * @since 5.3
051     */
052    boolean isPage();
053
054    /**
055     * Returns the resource corresponding to the class file for this component. This is used to find related resources,
056     * such as the component's template and message catalog.
057     */
058    Resource getBaseResource();
059
060    /**
061     * The fully qualified class name of the component.
062     */
063    String getComponentClassName();
064
065    /**
066     * Returns the ids of all embedded components defined within the component class (via the {@link
067     * Component} annotation), including those defined by any super-class.
068     */
069    List<String> getEmbeddedComponentIds();
070
071    /**
072     * Returns an embedded component defined by this component or by a super-class.
073     *
074     * @param componentId
075     *         the id of the embedded component
076     * @return the embedded component model, or null if no component exists with that id
077     */
078    EmbeddedComponentModel getEmbeddedComponentModel(String componentId);
079
080    /**
081     * Returns the persistent strategy associated with the field.
082     *
083     * @param fieldName
084     * @return the corresponding strategy, or the empty string
085     * @throws IllegalArgumentException
086     *         if the named field is not marked as persistent
087     */
088    String getFieldPersistenceStrategy(String fieldName);
089
090    /**
091     * Returns object that will be used to log warnings and errors related to this component.
092     *
093     * @see org.apache.tapestry5.annotations.Log
094     */
095    Logger getLogger();
096
097    /**
098     * Returns a list of the class names of mixins that are part of the component's implementation.
099     */
100    List<String> getMixinClassNames();
101
102    /**
103     * Return a single parameter model by parameter name, or null if the parameter is not defined (is not
104     * a formal parameter). This may be a parameter defined by this component, or from a base class.
105     *
106     * @param parameterName
107     *         the name of the parameter (case is ignored)
108     * @return the parameter model if found in this model or a parent model, or null if not found
109     */
110    ParameterModel getParameterModel(String parameterName);
111
112    /**
113     * Returns true if the named parameter is formally defined (there's a ParameterModel).
114     *
115     * @param parameterName
116     *         name of the parameter (case is ignored)
117     * @since 5.2.0
118     */
119    boolean isFormalParameter(String parameterName);
120
121    /**
122     * Returns an alphabetically sorted list of the names of all formal parameters. This includes parameters defined by
123     * a base class.
124     */
125
126    List<String> getParameterNames();
127
128    /**
129     * Returns an alphabetically sorted list of the names of all formal parameters defined by this specific class
130     * (parameters inherited from base classes are not identified).
131     */
132    List<String> getDeclaredParameterNames();
133
134    /**
135     * Returns a list of the names of all persistent fields (within this class, or any super-class). The names are
136     * sorted alphabetically.
137     *
138     * @see Persist
139     */
140    List<String> getPersistentFieldNames();
141
142    /**
143     * Returns true if the modeled component is a root class, a component class whose parent class is not a component
144     * class.  We may in the future require that components only extend from Object.
145     *
146     * @return true if a root class, false if a subclass
147     */
148    boolean isRootClass();
149
150    /**
151     * Returns true if the model indicates that informal parameters, additional parameters beyond the formal parameter
152     * defined for the component, are supported. This is false in most cases, but may be set to true for specific
153     * classes (when the {@link SupportsInformalParameters} annotation is present, or inherited from a super-class).
154     *
155     * @return true if this component model supports informal parameters
156     */
157    boolean getSupportsInformalParameters();
158
159    /**
160     * Returns the component model for this component's super-class, if it exists. Remember that only classes in the
161     * correct packages, are considered component classes.
162     *
163     * @return the parent class model, or null if this component's super class is not itself a component class
164     */
165    ComponentModel getParentModel();
166
167    /**
168     * Relevant for component mixins only. Indicates that the mixin behavior should occur <em>after</em> (not before)
169     * the component. Normally, this flag is set by the presence of the {@link MixinAfter} annotation.
170     *
171     * @return true if the mixin should operate after, not before, the component
172     */
173    boolean isMixinAfter();
174
175    /**
176     * Gets a meta value identified by the given key. If the current model does not provide a value for the key, then
177     * the parent component model (if any) is searched.
178     *
179     * @param key
180     *         identifies the value to be accessed
181     * @return the value for the key (possibly inherited from a parent model), or null
182     */
183    String getMeta(String key);
184
185    /**
186     * Returns a set of all the render phases that this model (including parent models) that are handled. Render phases
187     * are represented by the corresponding annotation ({@link BeginRender}, {@link AfterRender}, etc.).
188     *
189     * @return set of classes
190     * @since 5.0.19, 5.1.0.0
191     */
192    Set<Class> getHandledRenderPhases();
193
194    /**
195     * Determines if the component has an event handler for the indicated event name (case insensitive). This includes
196     * handlers in the component class itself, or its super-classes, but does not include event handlers supplied by
197     * implementation or instance mixins.
198     *
199     * @param eventType
200     *         name of event to check (case insensitive)
201     * @return true if event handler present
202     */
203    boolean handlesEvent(String eventType);
204
205    /**
206     * @param mixinClassName
207     *         class name of the mixin for which the ordering is desired
208     * @return the ordering constraint(s) for the mixin, potentially null.
209     * @since 5.2.0
210     */
211    String[] getOrderForMixin(String mixinClassName);
212
213    /**
214     * Relevant for pages only, indicates that the component handle the {@link EventConstants#ACTIVATE}
215     * events with a catch all rules
216     *
217     * @return true if the page implements catch all rules for the activate event context, or false otherwise
218     * @see MutableComponentModel#doHandleActivationEventContext()
219     * @since 5.4
220     */
221    boolean handleActivationEventContext();
222}