View Javadoc
1   /**
2    * Copyright 2005-2016 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.web.bind;
17  
18  import org.springframework.beans.BeanWrapperImpl;
19  import org.springframework.beans.BeansException;
20  import org.springframework.beans.InvalidPropertyException;
21  import org.springframework.beans.NullValueInNestedPathException;
22  import org.springframework.beans.PropertyValue;
23  
24  /**
25   * Bean wrapper that will auto grow paths for setting the value but not grow paths for getting
26   * a value.
27   *
28   * @author Kuali Rice Team (rice.collab@kuali.org)
29   */
30  public class UifBeanWrapper extends BeanWrapperImpl {
31  
32      private BeanWrapperImpl rootBeanWrapper;
33  
34      public UifBeanWrapper(Object object) {
35          super(object);
36      }
37  
38      public UifBeanWrapper(Object object, String nestedPath, UifBeanWrapper superBw) {
39          super(object, nestedPath, superBw);
40  
41          setRootBeanWrapper(superBw.getRootBeanWrapper());
42      }
43  
44      /**
45       * Overridden to set auto grow nested paths to false for getting the value.
46       *
47       * {@inheritDoc}
48       */
49      @Override
50      public Object getPropertyValue(String propertyName) throws BeansException {
51          return getPropertyValue(propertyName, false);
52      }
53  
54      /**
55       * Returns the value for the given property growing nested paths depending on the parameter.
56       *
57       * @param propertyName name of the property to get value for
58       * @param autoGrowNestedPaths whether nested paths should be grown (initialized if null)
59       * @return value for property
60       */
61      protected Object getPropertyValue(String propertyName, boolean autoGrowNestedPaths) {
62          setAutoGrowNestedPaths(autoGrowNestedPaths);
63  
64          Object value = null;
65          try {
66              value = super.getPropertyValue(propertyName);
67          } catch (NullValueInNestedPathException e) {
68              // swallow null values in path and return null as the value
69          } catch (InvalidPropertyException e1) {
70              if (!(e1.getRootCause() instanceof NullValueInNestedPathException)) {
71                  throw e1;
72              }
73          }
74  
75          return value;
76      }
77  
78      /**
79       * Override to set auto grow to true for setting property values.
80       *
81       * {@inheritDoc}
82       */
83      @Override
84      public void setPropertyValue(PropertyValue pv) throws BeansException {
85          setAutoGrowNestedPaths(true);
86  
87          super.setPropertyValue(pv);
88      }
89  
90      /**
91       * Override to set auto grow to true for setting property values.
92       *
93       * {@inheritDoc}
94       */
95      @Override
96      public void setPropertyValue(String propertyName, Object value) throws BeansException {
97          setAutoGrowNestedPaths(true);
98  
99          super.setPropertyValue(propertyName, value);
100     }
101 
102     /**
103      * Override to instantiate a UIF bean wrapper for nested bean wrappers.
104      *
105      * {@inheritDoc}
106      */
107     @Override
108     protected BeanWrapperImpl newNestedBeanWrapper(Object object, String nestedPath) {
109         return new UifBeanWrapper(object, nestedPath, this);
110     }
111 
112     /**
113      * Override to set auto grown on the nested bean wrapper to the setting of the root bean wrapper.
114      *
115      * <p>This is necessary because the nested bean wrapper could have been cached, and its auto-grow
116      * setting reflect an earler get or set call</p>
117      *
118      * {@inheritDoc}
119      */
120     @Override
121     protected BeanWrapperImpl getBeanWrapperForPropertyPath(String propertyPath) {
122         if (this.rootBeanWrapper != null) {
123             setAutoGrowNestedPaths(this.rootBeanWrapper.isAutoGrowNestedPaths());
124         }
125 
126         return super.getBeanWrapperForPropertyPath(propertyPath);
127     }
128 
129     /**
130      * Bean wrapper for the root data object, used for setting auto grows on nested bean wrappers.
131      *
132      * @return bean wrapper impl for root data object
133      */
134     public BeanWrapperImpl getRootBeanWrapper() {
135         if (rootBeanWrapper == null) {
136             return this;
137         }
138 
139         return rootBeanWrapper;
140     }
141 
142     /**
143      * @see UifBeanWrapper#getRootBeanWrapper()
144      */
145     public void setRootBeanWrapper(BeanWrapperImpl rootBeanWrapper) {
146         this.rootBeanWrapper = rootBeanWrapper;
147     }
148 }