001/** 002 * Copyright 2005-2016 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.web.bind; 017 018import org.springframework.beans.BeanWrapperImpl; 019import org.springframework.beans.BeansException; 020import org.springframework.beans.InvalidPropertyException; 021import org.springframework.beans.NullValueInNestedPathException; 022import org.springframework.beans.PropertyValue; 023 024/** 025 * Bean wrapper that will auto grow paths for setting the value but not grow paths for getting 026 * a value. 027 * 028 * @author Kuali Rice Team (rice.collab@kuali.org) 029 */ 030public class UifBeanWrapper extends BeanWrapperImpl { 031 032 private BeanWrapperImpl rootBeanWrapper; 033 034 public UifBeanWrapper(Object object) { 035 super(object); 036 } 037 038 public UifBeanWrapper(Object object, String nestedPath, UifBeanWrapper superBw) { 039 super(object, nestedPath, superBw); 040 041 setRootBeanWrapper(superBw.getRootBeanWrapper()); 042 } 043 044 /** 045 * Overridden to set auto grow nested paths to false for getting the value. 046 * 047 * {@inheritDoc} 048 */ 049 @Override 050 public Object getPropertyValue(String propertyName) throws BeansException { 051 return getPropertyValue(propertyName, false); 052 } 053 054 /** 055 * Returns the value for the given property growing nested paths depending on the parameter. 056 * 057 * @param propertyName name of the property to get value for 058 * @param autoGrowNestedPaths whether nested paths should be grown (initialized if null) 059 * @return value for property 060 */ 061 protected Object getPropertyValue(String propertyName, boolean autoGrowNestedPaths) { 062 setAutoGrowNestedPaths(autoGrowNestedPaths); 063 064 Object value = null; 065 try { 066 value = super.getPropertyValue(propertyName); 067 } catch (NullValueInNestedPathException e) { 068 // swallow null values in path and return null as the value 069 } catch (InvalidPropertyException e1) { 070 if (!(e1.getRootCause() instanceof NullValueInNestedPathException)) { 071 throw e1; 072 } 073 } 074 075 return value; 076 } 077 078 /** 079 * Override to set auto grow to true for setting property values. 080 * 081 * {@inheritDoc} 082 */ 083 @Override 084 public void setPropertyValue(PropertyValue pv) throws BeansException { 085 setAutoGrowNestedPaths(true); 086 087 super.setPropertyValue(pv); 088 } 089 090 /** 091 * Override to set auto grow to true for setting property values. 092 * 093 * {@inheritDoc} 094 */ 095 @Override 096 public void setPropertyValue(String propertyName, Object value) throws BeansException { 097 setAutoGrowNestedPaths(true); 098 099 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}