001/** 002 * Copyright 2005-2015 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.krad.uif.util; 017 018import java.io.Serializable; 019import java.util.Map; 020import java.util.Queue; 021 022import org.kuali.rice.krad.datadictionary.Copyable; 023import org.kuali.rice.krad.uif.component.Component; 024import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle; 025import org.kuali.rice.krad.uif.lifecycle.ViewLifecyclePhase; 026import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleTask; 027 028/** 029 * Interface to be implemented by objects that participates in the view lifecycle. 030 * 031 * @author Kuali Rice Team (rice.collab@kuali.org) 032 */ 033public interface LifecycleElement extends Serializable, Copyable { 034 035 /** 036 * The unique id (within a given tree) for the element. 037 * 038 * <p>The id is used to identify an element instance within the tree, and 039 * will be used by renderers to set the HTML element id. This gives a way to find various elements 040 * for scripting. If the id is not given, a default will be generated by the framework. 041 * </p> 042 * 043 * @return A unique ID for this lifecycle element. 044 */ 045 String getId(); 046 047 /** 048 * Setter for the unique id (within a given tree) for the component 049 * 050 * @param id - string to set as the component id 051 */ 052 void setId(String id); 053 054 /** 055 * A string suffix that should get applied to the id for all child components of the given element. 056 * 057 * <p>This is mainly used within the framework to keep ids unique. For instance, for components generated 058 * for collection lines, all the components within those should get a line suffix. The framework will set 059 * this property to be '_line0', '_line1', etc. Then when the apply model phase is run on the child components 060 * their ids will be updated with this suffix.</p> 061 * 062 * @return String id suffix for child components 063 * @see org.kuali.rice.krad.uif.lifecycle.model.SuffixIdFromContainerTask 064 */ 065 String getContainerIdSuffix(); 066 067 /** 068 * @see LifecycleElement#getContainerIdSuffix() 069 */ 070 void setContainerIdSuffix(String containerIdSuffix); 071 072 /** 073 * Gets a property for referring to this component from the view, relative to the view, as 074 * assigned by the current or most recent lifecycle. 075 * 076 * @return property path 077 */ 078 String getViewPath(); 079 080 /** 081 * Setter for {@link #getViewPath()}. 082 * 083 * @param viewPath The property path. 084 */ 085 void setViewPath(String viewPath); 086 087 /** 088 * Map of paths for this component that will be used to process a refresh (if necessary). 089 * 090 * @return map of refresh paths, key represents the lifecycle phase and the value is the path for 091 * the component at that phase 092 */ 093 Map<String, String> getPhasePathMapping(); 094 095 /** 096 * @see LifecycleElement#getPhasePathMapping() 097 */ 098 void setPhasePathMapping(Map<String, String> phasePathMapping); 099 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}