/**
* Copyright (C) 2015 Valkyrie RCP
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.valkyriercp.binding.support;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyAccessor;
import org.valkyriercp.binding.MutablePropertyAccessStrategy;
import org.valkyriercp.binding.value.ValueModel;
import org.valkyriercp.binding.value.support.ValueHolder;
/**
* An implementation of <code>MutablePropertyAccessStrategy</code> that provides access
* to the properties of a JavaBean.
*
* <p>As this class delegates to a <code>BeanWrapper</code> for property access, there is
* full support for <b>nested properties</b>, enabling the setting/getting
* of properties on subproperties to an unlimited depth.
*
* @author Oliver Hutchison
* @author Arne Limburg
* @see org.springframework.beans.BeanWrapper
*/
public class BeanPropertyAccessStrategy extends AbstractPropertyAccessStrategy {
private final BeanWrapperImpl beanWrapper;
/**
* Creates a new instance of BeanPropertyAccessStrategy that will provide access
* to the properties of the provided JavaBean.
*
* @param bean JavaBean to be accessed through this class.
*/
public BeanPropertyAccessStrategy(Object bean) {
this(new ValueHolder(bean));
}
/**
* Creates a new instance of BeanPropertyAccessStrategy that will provide access
* to the JavaBean contained by the provided value model.
*
* @param domainObjectHolder value model that holds the JavaBean to
* be accessed through this class
*/
public BeanPropertyAccessStrategy(final ValueModel domainObjectHolder) {
super(domainObjectHolder);
this.beanWrapper = new BeanWrapperImpl(false);
this.beanWrapper. setWrappedInstance(domainObjectHolder.getValue());
}
/**
* Creates a child instance of BeanPropertyAccessStrategy that will delegate to its
* parent for property access.
*
* @param parent BeanPropertyAccessStrategy which will be used to provide property access
* @param basePropertyPath property path that will as a base when accessing the parent
* BeanPropertyAccessStrategy
*/
protected BeanPropertyAccessStrategy(BeanPropertyAccessStrategy parent, String basePropertyPath) {
super(parent, basePropertyPath);
this.beanWrapper = parent.beanWrapper;
}
/**
* Provides <code>BeanWrapper</code> access to subclasses.
* @return Spring <code>BeanWrapper</code> used to access the bean.
*/
protected BeanWrapper getBeanWrapper() {
return beanWrapper;
}
/**
* Provides <code>BeanWrapper</code> access to subclasses.
* @return Spring <code>BeanWrapper</code> used to access the bean.
*/
protected PropertyAccessor getPropertyAccessor() {
return beanWrapper;
}
public MutablePropertyAccessStrategy getPropertyAccessStrategyForPath(String propertyPath) throws BeansException {
return new BeanPropertyAccessStrategy(this, getFullPropertyPath(propertyPath));
}
public MutablePropertyAccessStrategy newPropertyAccessStrategy(ValueModel domainObjectHolder) {
return new BeanPropertyAccessStrategy(domainObjectHolder);
}
protected void domainObjectChanged() {
beanWrapper.setWrappedInstance(getDomainObject());
}
}