1 /**
2 * Copyright 2005-2014 The Kuali Foundation
3 *
4 * Licensed under the Educational Community License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/ecl2.php
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.kuali.rice.krad.uif.util;
17
18 import java.io.Serializable;
19 import java.util.Map;
20 import java.util.Queue;
21
22 import org.kuali.rice.krad.datadictionary.Copyable;
23 import org.kuali.rice.krad.uif.component.Component;
24 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
25 import org.kuali.rice.krad.uif.lifecycle.ViewLifecyclePhase;
26 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleTask;
27
28 /**
29 * Interface to be implemented by objects that participates in the view lifecycle.
30 *
31 * @author Kuali Rice Team (rice.collab@kuali.org)
32 */
33 public interface LifecycleElement extends Serializable, Copyable {
34
35 /**
36 * The unique id (within a given tree) for the element.
37 *
38 * <p>The id is used to identify an element instance within the tree, and
39 * will be used by renderers to set the HTML element id. This gives a way to find various elements
40 * for scripting. If the id is not given, a default will be generated by the framework.
41 * </p>
42 *
43 * @return A unique ID for this lifecycle element.
44 */
45 String getId();
46
47 /**
48 * Setter for the unique id (within a given tree) for the component
49 *
50 * @param id - string to set as the component id
51 */
52 void setId(String id);
53
54 /**
55 * A string suffix that should get applied to the id for all child components of the given element.
56 *
57 * <p>This is mainly used within the framework to keep ids unique. For instance, for components generated
58 * for collection lines, all the components within those should get a line suffix. The framework will set
59 * this property to be '_line0', '_line1', etc. Then when the apply model phase is run on the child components
60 * their ids will be updated with this suffix.</p>
61 *
62 * @return String id suffix for child components
63 * @see org.kuali.rice.krad.uif.lifecycle.model.SuffixIdFromContainerTask
64 */
65 String getContainerIdSuffix();
66
67 /**
68 * @see LifecycleElement#getContainerIdSuffix()
69 */
70 void setContainerIdSuffix(String containerIdSuffix);
71
72 /**
73 * Gets a property for referring to this component from the view, relative to the view, as
74 * assigned by the current or most recent lifecycle.
75 *
76 * @return property path
77 */
78 String getViewPath();
79
80 /**
81 * Setter for {@link #getViewPath()}.
82 *
83 * @param viewPath The property path.
84 */
85 void setViewPath(String viewPath);
86
87 /**
88 * Map of paths for this component that will be used to process a refresh (if necessary).
89 *
90 * @return map of refresh paths, key represents the lifecycle phase and the value is the path for
91 * the component at that phase
92 */
93 Map<String, String> getPhasePathMapping();
94
95 /**
96 * @see LifecycleElement#getPhasePathMapping()
97 */
98 void setPhasePathMapping(Map<String, String> phasePathMapping);
99
100 /**
101 * Determine if this lifecycle element is mutable.
102 *
103 * <p>
104 * Most lifecycle element are immutable, and all are immutable expect during initialization and
105 * the during the view lifecycle. Those that have been copied within the view lifecycle,
106 * however, may be modified during the same lifecycle.
107 * </p>
108 * @param legalBeforeConfiguration true if the current operation may be called before the
109 * lifecycle element has been cached, for example while being initialized as part of a
110 * Spring context.
111 *
112 * @return True if the component is mutable.
113 */
114 boolean isMutable(boolean legalBeforeConfiguration);
115
116 /**
117 * Check for mutability on the element before modifying state.
118 *
119 * @param legalDuringInitialization True if the operation is legal during view initialization,
120 * false if the operation is only allowed during the component lifecycle.
121 * @throws IllegalStateException If the component is not mutable and the lifecycle is operating
122 * in strict mode.
123 * @see ViewLifecycle#isStrict()
124 */
125 void checkMutable(boolean legalDuringInitialization);
126
127 /**
128 * Get the view lifecycle processing status for this component.
129 *
130 * @return The view lifecycle processing status for this component.
131 * @see org.kuali.rice.krad.uif.UifConstants.ViewStatus
132 */
133 String getViewStatus();
134
135 /**
136 * Sets the view status.
137 *
138 * @param viewStatus view status
139 * @see #getViewStatus()
140 */
141 void setViewStatus(String viewStatus);
142
143 /**
144 * Indicates whether the component should be rendered in the UI
145 *
146 * <p>
147 * If set to false, the corresponding component template will not be invoked
148 * (therefore nothing will be rendered to the UI).
149 * </p>
150 *
151 * @return boolean true if the component should be rendered, false if it
152 * should not be
153 */
154 boolean isRender();
155
156 /**
157 * Setter for the components render indicator
158 *
159 * @param render
160 */
161 void setRender(boolean render);
162
163 /**
164 * Indicates whether the component has been initialized.
165 *
166 * @return True if the component has been initialized, false if not.
167 */
168 boolean isInitialized();
169
170 /**
171 * Indicates whether the component has been updated from the model.
172 *
173 * @return True if the component has been updated, false if not.
174 */
175 boolean isModelApplied();
176
177 /**
178 * Indicates whether the component has been updated from the model and final
179 * updates made.
180 *
181 * @return True if the component has been updated, false if not.
182 */
183 boolean isFinal();
184
185 /**
186 * Receive notification that a lifecycle phase, and all successor phases, have been completed on
187 * this component.
188 * @param phase The completed view lifecycle phase
189 */
190 void notifyCompleted(ViewLifecyclePhase phase);
191
192 /**
193 * Context map for the lifecycle element.
194 *
195 * <p>Any el statements configured for the components properties (e.g. title="@{foo.property}") are evaluated
196 * using the el context map. This map will get populated with default objects like the model, view, and request
197 * from the {@code ViewHelperService}. Other components can push further objects into the context so that
198 * they are available for use with that component. For example, field instances that are part of a collection
199 * line as receive the current line instance</p>
200 *
201 * <p>Context map also provides objects to methods that are invoked for {@code GeneratedField} instances</p>
202 *
203 * <p>The Map key gives the name of the variable that can be used within expressions, and the Map value gives
204 * the object instance for which expressions containing the variable should evaluate against</p>
205 *
206 * <p>NOTE: Calling getContext().putAll() will skip updating any configured property replacers for the
207 * component. Instead you should call #pushAllToContextDeep</p>
208 *
209 * @return Map<String, Object> context
210 */
211 Map<String, Object> getContext();
212
213 /**
214 * @see LifecycleElement#getContext()
215 */
216 void setContext(Map<String, Object> context);
217
218 /**
219 * Places the given object into the context Map for the component with the given name
220 *
221 * <p>
222 * Note this also will push context to property replacers configured on the component. To place
223 * multiple objects in the context, you should use #pushAllToContextDeep since that will call this
224 * method for each and update property replacers. Using {@link Component#getContext()}{@link
225 * Map#putAll(Map) .putAll()} will bypass property replacers.
226 * </p>
227 *
228 * @param objectName - name the object should be exposed under in the context map
229 * @param object - object instance to place into context
230 */
231 void pushObjectToContext(String objectName, Object object);
232
233 /**
234 * Places each entry of the given Map into the context for the component
235 *
236 * <p>
237 * Note this will call #pushObjectToContextDeep for each entry which will update any configured property
238 * replacers as well. This should be used in place of getContext().putAll()
239 * </p>
240 *
241 * @param objects - Map<String, Object> objects to add to context, where the entry key will be the context key
242 * and the entry value will be the context value
243 */
244 void pushAllToContext(Map<String, Object> objects);
245
246 /**
247 * Initializes the component
248 *
249 * <p>
250 * Where components can set defaults and setup other necessary state. The initialize method
251 * should only be called once per component lifecycle and is invoked within the initialize phase
252 * of the view lifecylce.
253 * </p>
254 *
255 * @param model - object instance containing the view data
256 * @see org.kuali.rice.krad.uif.lifecycle.initialize.ComponentDefaultInitializeTask
257 * @deprecated Special processing within this method should be replaced by
258 * {@link ViewLifecycleTask} and initialized by
259 * {@link #initializePendingTasks(ViewLifecyclePhase, Queue)}.
260 */
261 @Deprecated
262 void performInitialization(Object model);
263
264 /**
265 * Called after the initialize phase to perform conditional logic based on the model data
266 *
267 * <p>
268 * Where components can perform conditional logic such as dynamically generating new fields or setting field state
269 * based on the given data
270 * </p>
271 *
272 * @param model - Top level object containing the data (could be the form or a
273 * top level business object, dto)
274 * @param parent parent lifecycle element
275 * @deprecated Special processing within this method should be replaced by
276 * {@link ViewLifecycleTask} and initialized by
277 * {@link #initializePendingTasks(ViewLifecyclePhase, Queue)}.
278 */
279 @Deprecated
280 void performApplyModel(Object model, LifecycleElement parent);
281
282 /**
283 * The last phase before the view is rendered
284 *
285 * <p>
286 * Here final preparations can be made based on the updated view state.
287 * </p>
288 *
289 * @param model - top level object containing the data
290 * @param parent - parent component
291 * @deprecated Special processing within this method should be replaced by
292 * {@link ViewLifecycleTask} and initialized by
293 * {@link #initializePendingTasks(ViewLifecyclePhase, Queue)}.
294 */
295 @Deprecated
296 void performFinalize(Object model, LifecycleElement parent);
297
298 /**
299 * Return true if the lifecycle should be skipped for this component.
300 *
301 * <p>Skipping the lifecycle means do not invoke the performInitialize, performApplyModel, and
302 * performFinalize methods of this component and its children. This means that content built
303 * by those lifecycle tasks will not be processed or applied.
304 * Skipping the lifecycle on a component helps initial load/setup performance by only performing
305 * the full lifecycle when the component is requested on subsequent requests (ajax retrievals).</p>
306 *
307 * @return true if lifecycle should be skipped for this component
308 */
309 boolean skipLifecycle();
310
311 }