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.model; 017 018import java.lang.annotation.Annotation; 019import java.util.Map; 020import java.util.Map.Entry; 021 022import org.apache.commons.lang.StringUtils; 023import org.kuali.rice.krad.uif.component.ClientSideState; 024import org.kuali.rice.krad.uif.component.Component; 025import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle; 026import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleTaskBase; 027import org.kuali.rice.krad.uif.util.CopyUtils; 028import org.kuali.rice.krad.uif.util.ObjectPropertyUtils; 029import org.kuali.rice.krad.uif.view.View; 030import org.kuali.rice.krad.uif.view.ViewModel; 031 032/** 033 * Synchronize client side state for the component. 034 * 035 * @author Kuali Rice Team (rice.collab@kuali.org) 036 */ 037public class SyncClientSideStateTask extends ViewLifecycleTaskBase<Component> { 038 039 /** 040 * Default constructor. 041 */ 042 public SyncClientSideStateTask() { 043 super(Component.class); 044 } 045 046 /** 047 * Updates the properties of the given component instance with the value found from the 048 * corresponding map of client state (if found) 049 * 050 * {@inheritDoc} 051 */ 052 @Override 053 protected void performLifecycleTask() { 054 Component component = (Component) getElementState().getElement(); 055 ViewModel model = (ViewModel) ViewLifecycle.getModel(); 056 057 // find the map of state that was sent for component (if any) 058 Map<String, Object> clientSideState = model.getClientStateForSyncing(); 059 if (!(component instanceof View) && clientSideState.containsKey(component.getId())) { 060 @SuppressWarnings("unchecked") 061 Map<String, Object> componentState = 062 (Map<String, Object>) clientSideState.get(component.getId()); 063 clientSideState = componentState; 064 } 065 066 // if state was sent, match with fields on the component that are annotated to have client state 067 if ((clientSideState != null) && (!clientSideState.isEmpty())) { 068 Map<String, Annotation> annotatedFields = CopyUtils.getFieldsWithAnnotation(component.getClass(), 069 ClientSideState.class); 070 071 for (Entry<String, Annotation> annotatedField : annotatedFields.entrySet()) { 072 ClientSideState clientSideStateAnnot = (ClientSideState) annotatedField.getValue(); 073 074 String variableName = clientSideStateAnnot.variableName(); 075 if (StringUtils.isBlank(variableName)) { 076 variableName = annotatedField.getKey(); 077 } 078 079 if (clientSideState.containsKey(variableName)) { 080 Object value = clientSideState.get(variableName); 081 ObjectPropertyUtils.setPropertyValue(component, annotatedField.getKey(), value); 082 } 083 } 084 } 085 } 086 087}