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 }