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 * Initialize the lifecycle task queue for custom tasks specific to this component on the given
129 * lifecycle phase.
130 *
131 * <p>
132 * Any tasks added to the queue by this method will be performed after the default lifecycle
133 * phase processing method {@link #performInitialization(Object)},
134 * {@link #performApplyModel(Object, LifecycleElement)}, or
135 * {@link #performFinalize(Object, LifecycleElement)} has been called.
136 * </p>
137 *
138 * @param phase The lifecycle phase to queue pending tasks for.
139 * @param pendingTasks The pending task queue.
140 */
141 void initializePendingTasks(ViewLifecyclePhase phase, Queue<ViewLifecycleTask<?>> pendingTasks);
142
143 /**
144 * Get the view lifecycle processing status for this component.
145 *
146 * @return The view lifecycle processing status for this component.
147 * @see org.kuali.rice.krad.uif.UifConstants.ViewStatus
148 */
149 String getViewStatus();
150
151 /**
152 * Sets the view status.
153 *
154 * @param viewStatus view status
155 * @see #getViewStatus()
156 */
157 void setViewStatus(String viewStatus);
158
159 /**
160 * Indicates whether the component should be rendered in the UI
161 *
162 * <p>
163 * If set to false, the corresponding component template will not be invoked
164 * (therefore nothing will be rendered to the UI).
165 * </p>
166 *
167 * @return boolean true if the component should be rendered, false if it
168 * should not be
169 */
170 boolean isRender();
171
172 /**
173 * Setter for the components render indicator
174 *
175 * @param render
176 */
177 void setRender(boolean render);
178
179 /**
180 * Indicates whether the component has been initialized.
181 *
182 * @return True if the component has been initialized, false if not.
183 */
184 boolean isInitialized();
185
186 /**
187 * Indicates whether the component has been updated from the model.
188 *
189 * @return True if the component has been updated, false if not.
190 */
191 boolean isModelApplied();
192
193 /**
194 * Indicates whether the component has been updated from the model and final
195 * updates made.
196 *
197 * @return True if the component has been updated, false if not.
198 */
199 boolean isFinal();
200
201 /**
202 * Receive notification that a lifecycle phase, and all successor phases, have been completed on
203 * this component.
204 * @param phase The completed view lifecycle phase
205 */
206 void notifyCompleted(ViewLifecyclePhase phase);
207
208 /**
209 * Context map for the lifecycle element.
210 *
211 * <p>Any el statements configured for the components properties (e.g. title="@{foo.property}") are evaluated
212 * using the el context map. This map will get populated with default objects like the model, view, and request
213 * from the {@code ViewHelperService}. Other components can push further objects into the context so that
214 * they are available for use with that component. For example, field instances that are part of a collection
215 * line as receive the current line instance</p>
216 *
217 * <p>Context map also provides objects to methods that are invoked for {@code GeneratedField} instances</p>
218 *
219 * <p>The Map key gives the name of the variable that can be used within expressions, and the Map value gives
220 * the object instance for which expressions containing the variable should evaluate against</p>
221 *
222 * <p>NOTE: Calling getContext().putAll() will skip updating any configured property replacers for the
223 * component. Instead you should call #pushAllToContext</p>
224 *
225 * @return Map<String, Object> context
226 */
227 Map<String, Object> getContext();
228
229 /**
230 * @see LifecycleElement#getContext()
231 */
232 void setContext(Map<String, Object> context);
233
234 /**
235 * Places the given object into the context Map for the component with the given name
236 *
237 * <p>
238 * Note this also will push context to property replacers configured on the component. To place
239 * multiple objects in the context, you should use #pushAllToContext since that will call this
240 * method for each and update property replacers. Using {@link Component#getContext()}{@link
241 * Map#putAll(Map) .putAll()} will bypass property replacers.
242 * </p>
243 *
244 * @param objectName - name the object should be exposed under in the context map
245 * @param object - object instance to place into context
246 */
247 void pushObjectToContext(String objectName, Object object);
248
249 /**
250 * Places each entry of the given Map into the context for the component
251 *
252 * <p>
253 * Note this will call #pushObjectToContext for each entry which will update any configured property
254 * replacers as well. This should be used in place of getContext().putAll()
255 * </p>
256 *
257 * @param objects - Map<String, Object> objects to add to context, where the entry key will be the context key
258 * and the entry value will be the context value
259 */
260 void pushAllToContext(Map<String, Object> objects);
261
262 /**
263 * Initializes the component
264 *
265 * <p>
266 * Where components can set defaults and setup other necessary state. The initialize method
267 * should only be called once per component lifecycle and is invoked within the initialize phase
268 * of the view lifecylce.
269 * </p>
270 *
271 * @param model - object instance containing the view data
272 * @see org.kuali.rice.krad.uif.lifecycle.initialize.ComponentDefaultInitializeTask
273 * @deprecated Special processing within this method should be replaced by
274 * {@link ViewLifecycleTask} and initialized by
275 * {@link #initializePendingTasks(ViewLifecyclePhase, Queue)}.
276 */
277 @Deprecated
278 void performInitialization(Object model);
279
280 /**
281 * Called after the initialize phase to perform conditional logic based on the model data
282 *
283 * <p>
284 * Where components can perform conditional logic such as dynamically generating new fields or setting field state
285 * based on the given data
286 * </p>
287 *
288 * @param model - Top level object containing the data (could be the form or a
289 * top level business object, dto)
290 * @param parent parent lifecycle element
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 performApplyModel(Object model, LifecycleElement parent);
297
298 /**
299 * The last phase before the view is rendered
300 *
301 * <p>
302 * Here final preparations can be made based on the updated view state.
303 * </p>
304 *
305 * @param model - top level object containing the data
306 * @param parent - parent component
307 * @deprecated Special processing within this method should be replaced by
308 * {@link ViewLifecycleTask} and initialized by
309 * {@link #initializePendingTasks(ViewLifecyclePhase, Queue)}.
310 */
311 @Deprecated
312 void performFinalize(Object model, LifecycleElement parent);
313
314 /**
315 * Return true if the lifecycle should be skipped for this component
316 *
317 * @return true if lifecycle should be skipped for this component
318 */
319 boolean skipLifecycle();
320
321 }