001/** 002 * Copyright 2005-2018 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.lifecycle; 017 018import java.util.List; 019import java.util.Map; 020 021import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 022import org.kuali.rice.krad.uif.UifConstants; 023import org.kuali.rice.krad.uif.container.PageGroup; 024import org.kuali.rice.krad.uif.service.ViewHelperService; 025import org.kuali.rice.krad.uif.util.BooleanMap; 026import org.kuali.rice.krad.uif.util.ProcessLogger; 027import org.kuali.rice.krad.uif.view.View; 028import org.kuali.rice.krad.uif.view.ViewModel; 029import org.kuali.rice.krad.web.form.UifFormBase; 030import org.slf4j.Logger; 031import org.slf4j.LoggerFactory; 032 033/** 034 * Perform the lifecycle process for the view or a component. 035 * 036 * @author Kuali Rice Team (rice.collab@kuali.org) 037 */ 038public class ViewLifecycleBuild implements Runnable { 039 private static final Logger LOG = LoggerFactory.getLogger(ViewLifecycleBuild.class); 040 041 private final Map<String, String> parameters; 042 private final Map<String, List<String>> refreshPathMappings; 043 044 /** 045 * Constructor. 046 * 047 * @param parameters Map of key values pairs that provide configuration for the view, this is generally comes from 048 * the request and can be the request parameter Map itself. Any parameters not valid for the View will be 049 * filtered out 050 * @param refreshPathMappings 051 */ 052 public ViewLifecycleBuild(Map<String, String> parameters, Map<String, List<String>> refreshPathMappings) { 053 this.parameters = parameters; 054 this.refreshPathMappings = refreshPathMappings; 055 } 056 057 /** 058 * Runs the three lifecycle phases and performs post finalize processing. 059 */ 060 @Override 061 public void run() { 062 View view = ViewLifecycle.getView(); 063 064 ProcessLogger.trace("begin-view-lifecycle:" + view.getId()); 065 066 populateViewRequestParameters(); 067 068 runInitializePhase(); 069 070 runApplyModelPhase(); 071 072 runFinalizePhase(); 073 074 // remove view so default values are only applied once 075 ((ViewModel) ViewLifecycle.getModel()).setApplyDefaultValues(false); 076 077 // build script for generating growl messages 078 String growlScript = ViewLifecycle.getHelper().buildGrowlScript(); 079 ((ViewModel) ViewLifecycle.getModel()).setGrowlScript(growlScript); 080 081 // on component refreshes regenerate server message content for page 082 if (ViewLifecycle.isRefreshLifecycle()) { 083 PageGroup page = view.getCurrentPage(); 084 page.getValidationMessages().generateMessages(view, ViewLifecycle.getModel(), page); 085 } 086 087 LifecycleRefreshPathBuilder.processLifecycleElements(); 088 089 ViewLifecycle.getViewPostMetadata().cleanAfterLifecycle(); 090 091 ProcessLogger.trace("finalize:" + view.getId()); 092 } 093 094 /** 095 * Invokes the view helper to populate view attributes from request parameters, then makes a back up of the 096 * view request parameters on the form. 097 */ 098 protected void populateViewRequestParameters() { 099 View view = ViewLifecycle.getView(); 100 ViewHelperService helper = ViewLifecycle.getHelper(); 101 UifFormBase model = (UifFormBase) ViewLifecycle.getModel(); 102 103 // populate view from request parameters. In case of refresh, the parameters will be stored on the 104 // form from the initial build 105 Map<String, String> parametersToPopulate = parameters; 106 if (ViewLifecycle.isRefreshLifecycle()) { 107 parametersToPopulate = model.getViewRequestParameters(); 108 } 109 110 helper.populateViewFromRequestParameters(parametersToPopulate); 111 112 // backup view request parameters on form for refreshes 113 model.setViewRequestParameters(view.getViewRequestParameters()); 114 } 115 116 /** 117 * Runs the initialize lifecycle phase. 118 * 119 * <p>First the view helper is invoked to perform any custom processing, then the processor is invoked 120 * to perform any tasks for this phase.</p> 121 */ 122 protected void runInitializePhase() { 123 ViewLifecycleProcessor processor = ViewLifecycle.getProcessor(); 124 125 List<String> refreshPaths = null; 126 if (refreshPathMappings != null) { 127 refreshPaths = refreshPathMappings.get(UifConstants.ViewPhases.INITIALIZE); 128 } 129 130 ViewLifecyclePhase phase = KRADServiceLocatorWeb.getViewLifecyclePhaseBuilder().buildPhase( 131 ViewLifecycle.getView(), UifConstants.ViewPhases.INITIALIZE, refreshPaths); 132 133 View view = ViewLifecycle.getView(); 134 ViewHelperService helper = ViewLifecycle.getHelper(); 135 UifFormBase model = (UifFormBase) ViewLifecycle.getModel(); 136 137 ViewLifecycle.getExpressionEvaluator().initializeEvaluationContext(model); 138 139 if (LOG.isInfoEnabled()) { 140 LOG.info("performing initialize phase for view: " + view.getId()); 141 } 142 143 helper.performCustomViewInitialization(model); 144 145 processor.performPhase(phase); 146 147 ProcessLogger.trace("initialize:" + view.getId()); 148 } 149 150 /** 151 * Runs the apply model lifecycle phase. 152 * 153 * <p>Default values are applied and context is setup for expression evaluation. Then the processor is invoked 154 * to perform any tasks for this phase. </p> 155 */ 156 protected void runApplyModelPhase() { 157 ViewLifecycleProcessor processor = ViewLifecycle.getProcessor(); 158 159 List<String> refreshPaths = null; 160 if (refreshPathMappings != null) { 161 refreshPaths = refreshPathMappings.get(UifConstants.ViewPhases.APPLY_MODEL); 162 } 163 164 ViewLifecyclePhase phase = KRADServiceLocatorWeb.getViewLifecyclePhaseBuilder().buildPhase( 165 ViewLifecycle.getView(), UifConstants.ViewPhases.APPLY_MODEL, refreshPaths); 166 167 View view = ViewLifecycle.getView(); 168 ViewHelperService helper = ViewLifecycle.getHelper(); 169 UifFormBase model = (UifFormBase) ViewLifecycle.getModel(); 170 171 if (LOG.isInfoEnabled()) { 172 LOG.info("performing apply model phase for view: " + view.getId()); 173 } 174 175 // apply default values if view in list 176 177 if(model.isApplyDefaultValues()) { 178 helper.applyDefaultValues(view); 179 180 //ensure default values are only set once 181 model.setApplyDefaultValues(false); 182 } 183 184 // get action flag and edit modes from authorizer/presentation controller, or set from the form backup 185 if (model.isEvaluateFlagsAndModes()) { 186 helper.retrieveEditModesAndActionFlags(); 187 188 // backup maps 189 model.setActionFlags(view.getActionFlags()); 190 model.setEditModes(view.getEditModes()); 191 192 model.setEvaluateFlagsAndModes(false); 193 } else { 194 view.setActionFlags(model.getActionFlags()); 195 view.setEditModes(model.getEditModes()); 196 } 197 198 // set view context for conditional expressions 199 helper.setViewContext(); 200 201 processor.performPhase(phase); 202 203 ProcessLogger.trace("apply-model:" + view.getId()); 204 } 205 206 /** 207 * Runs the finalize lifecycle phase. 208 * 209 * <p>Processor is invoked to perform any tasks for this phase.</p> 210 */ 211 protected void runFinalizePhase() { 212 ViewLifecycleProcessor processor = ViewLifecycle.getProcessor(); 213 214 List<String> refreshPaths = null; 215 if (refreshPathMappings != null) { 216 refreshPaths = refreshPathMappings.get(UifConstants.ViewPhases.FINALIZE); 217 } 218 219 ViewLifecyclePhase phase = KRADServiceLocatorWeb.getViewLifecyclePhaseBuilder().buildPhase( 220 ViewLifecycle.getView(), UifConstants.ViewPhases.FINALIZE, refreshPaths); 221 222 View view = ViewLifecycle.getView(); 223 if (LOG.isInfoEnabled()) { 224 LOG.info("performing finalize phase for view: " + view.getId()); 225 } 226 227 processor.performPhase(phase); 228 } 229 230}