View Javadoc
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.lifecycle.model;
17  
18  import java.lang.annotation.Annotation;
19  import java.util.Map;
20  import java.util.Map.Entry;
21  
22  import org.apache.commons.lang.StringUtils;
23  import org.kuali.rice.krad.uif.component.ClientSideState;
24  import org.kuali.rice.krad.uif.component.Component;
25  import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
26  import org.kuali.rice.krad.uif.lifecycle.ViewLifecyclePhase;
27  import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleTaskBase;
28  import org.kuali.rice.krad.uif.util.CloneUtils;
29  import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
30  import org.kuali.rice.krad.uif.view.View;
31  import org.kuali.rice.krad.uif.view.ViewModel;
32  
33  /**
34   * Synchronize client side state for the component.
35   * 
36   * @author Kuali Rice Team (rice.collab@kuali.org)
37   */
38  public class SyncClientSideStateTask extends ViewLifecycleTaskBase<Component> {
39  
40      /**
41       * Constructor.
42       * 
43       * @param phase The apply model phase for the component.
44       */
45      public SyncClientSideStateTask(ViewLifecyclePhase phase) {
46          super(phase, Component.class);
47      }
48  
49      /**
50       * Updates the properties of the given component instance with the value found from the
51       * corresponding map of client state (if found)
52       * 
53       * {@inheritDoc}
54       */
55      @Override
56      protected void performLifecycleTask() {
57          Component component = (Component) getElementState().getElement();
58          ViewModel model = (ViewModel) ViewLifecycle.getModel();
59  
60          // find the map of state that was sent for component (if any)
61          Map<String, Object> clientSideState = model.getClientStateForSyncing();
62          if (!(component instanceof View) && clientSideState.containsKey(component.getId())) {
63              @SuppressWarnings("unchecked")
64              Map<String, Object> componentState =
65                      (Map<String, Object>) clientSideState.get(component.getId());
66              clientSideState = componentState;
67          }
68  
69          // if state was sent, match with fields on the component that are annotated to have client state
70          if ((clientSideState != null) && (!clientSideState.isEmpty())) {
71              Map<String, Annotation> annotatedFields = CloneUtils.getFieldsWithAnnotation(component.getClass(),
72                      ClientSideState.class);
73  
74              for (Entry<String, Annotation> annotatedField : annotatedFields.entrySet()) {
75                  ClientSideState clientSideStateAnnot = (ClientSideState) annotatedField.getValue();
76  
77                  String variableName = clientSideStateAnnot.variableName();
78                  if (StringUtils.isBlank(variableName)) {
79                      variableName = annotatedField.getKey();
80                  }
81  
82                  if (clientSideState.containsKey(variableName)) {
83                      Object value = clientSideState.get(variableName);
84                      ObjectPropertyUtils.setPropertyValue(component, annotatedField.getKey(), value);
85                  }
86              }
87          }
88      }
89  
90  }