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 }