001 /* 002 * Copyright 2002-2007 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 005 * use this file except in compliance with the License. You may obtain a copy of 006 * the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 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, WITHOUT 012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 013 * License for the specific language governing permissions and limitations under 014 * the License. 015 */ 016 package org.springframework.binding.support; 017 018 import org.springframework.beans.BeanWrapper; 019 import org.springframework.beans.BeanWrapperImpl; 020 import org.springframework.beans.BeansException; 021 import org.springframework.beans.PropertyAccessor; 022 import org.springframework.binding.MutablePropertyAccessStrategy; 023 import org.springframework.binding.value.ValueModel; 024 import org.springframework.binding.value.support.ValueHolder; 025 026 /** 027 * An implementation of <code>MutablePropertyAccessStrategy</code> that provides access 028 * to the properties of a JavaBean. 029 * 030 * <p>As this class delegates to a <code>BeanWrapper</code> for property access, there is 031 * full support for <b>nested properties</b>, enabling the setting/getting 032 * of properties on subproperties to an unlimited depth. 033 * 034 * @author Oliver Hutchison 035 * @author Arne Limburg 036 * @see org.springframework.beans.BeanWrapper 037 */ 038 public class BeanPropertyAccessStrategy extends AbstractPropertyAccessStrategy { 039 040 private final BeanWrapper beanWrapper; 041 042 /** 043 * Creates a new instance of BeanPropertyAccessStrategy that will provide access 044 * to the properties of the provided JavaBean. 045 * 046 * @param bean JavaBean to be accessed through this class. 047 */ 048 public BeanPropertyAccessStrategy(Object bean) { 049 this(new ValueHolder(bean)); 050 } 051 052 /** 053 * Creates a new instance of BeanPropertyAccessStrategy that will provide access 054 * to the JavaBean contained by the provided value model. 055 * 056 * @param domainObjectHolder value model that holds the JavaBean to 057 * be accessed through this class 058 */ 059 public BeanPropertyAccessStrategy(final ValueModel domainObjectHolder) { 060 super(domainObjectHolder); 061 this.beanWrapper = new BeanWrapperImpl(false); 062 this.beanWrapper.setWrappedInstance(domainObjectHolder.getValue()); 063 } 064 065 /** 066 * Creates a child instance of BeanPropertyAccessStrategy that will delegate to its 067 * parent for property access. 068 * 069 * @param parent BeanPropertyAccessStrategy which will be used to provide property access 070 * @param basePropertyPath property path that will as a base when accessing the parent 071 * BeanPropertyAccessStrategy 072 */ 073 protected BeanPropertyAccessStrategy(BeanPropertyAccessStrategy parent, String basePropertyPath) { 074 super(parent, basePropertyPath); 075 this.beanWrapper = parent.beanWrapper; 076 } 077 078 /** 079 * Provides <code>BeanWrapper</code> access to subclasses. 080 * @return Spring <code>BeanWrapper</code> used to access the bean. 081 */ 082 protected BeanWrapper getBeanWrapper() { 083 return beanWrapper; 084 } 085 086 /** 087 * Provides <code>BeanWrapper</code> access to subclasses. 088 * @return Spring <code>BeanWrapper</code> used to access the bean. 089 */ 090 protected PropertyAccessor getPropertyAccessor() { 091 return beanWrapper; 092 } 093 094 public MutablePropertyAccessStrategy getPropertyAccessStrategyForPath(String propertyPath) throws BeansException { 095 return new BeanPropertyAccessStrategy(this, getFullPropertyPath(propertyPath)); 096 } 097 098 public MutablePropertyAccessStrategy newPropertyAccessStrategy(ValueModel domainObjectHolder) { 099 return new BeanPropertyAccessStrategy(domainObjectHolder); 100 } 101 102 protected void domainObjectChanged() { 103 beanWrapper.setWrappedInstance(getDomainObject()); 104 } 105 }