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 }