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 }