/*
* Copyright 2007 the original author or authors.
*
* 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.springframework.binding.support;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyAccessor;
import org.springframework.binding.MutablePropertyAccessStrategy;
import org.springframework.binding.value.ValueModel;
import org.springframework.binding.value.support.ValueHolder;
import org.springframework.richclient.beans.DefaultMemberPropertyAccessor;
/**
* An implementation of <code>MutablePropertyAccessStrategy</code> that provides access
* to the properties of any object.
*
* <p>As this class delegates to a <code>DefaultMemberPropertyAccessor</code> for property access,
* there is full support for <b>nested properties</b> and collection types.
*
* @author Arne Limburg
* @see org.springframework.richclient.beans.DefaultMemberPropertyAccessor
*/
public class ObjectPropertyAccessStrategy extends AbstractPropertyAccessStrategy {
private final DefaultMemberPropertyAccessor propertyAccessor;
/**
* Creates a new instance of <tt>ObjectPropertyAccessStrategy</tt>
* that will provide access to the properties of the provided object.
*
* @param target object to be accessed through this class.
*/
public ObjectPropertyAccessStrategy(Object target) {
this(new ValueHolder(target));
}
/**
* Creates a new instance of <tt>ObjectPropertyAccessStrategy</tt>
* that will provide access to the object contained by the provided value model.
*
* @param domainObjectHolder value model that holds the object
* to be accessed through this class
*/
public ObjectPropertyAccessStrategy(final ValueModel domainObjectHolder) {
this(domainObjectHolder, false);
}
/**
* Creates a new instance of <tt>ObjectPropertyAccessStrategy</tt>
* that will provide access to the object contained by the provided value model.
*
* @param domainObjectHolder value model that holds the object
* to be accessed through this class
* @param fieldAccessEnabled whether the fields of the objects
* should be accessed directly where possible
* instead of using methods
*/
public ObjectPropertyAccessStrategy(final ValueModel domainObjectHolder, boolean fieldAccessEnabled) {
this(domainObjectHolder, fieldAccessEnabled, true);
}
/**
* Creates a new instance of <tt>ObjectPropertyAccessStrategy</tt>
* that will provide access to the object contained by the provided value model.
*
* @param domainObjectHolder value model that holds the object
* to be accessed through this class
* @param fieldAccessEnabled whether the fields of the objects
* should be accessed directly where possible
* instead of using methods
* @param strictNullValueHandling whether a <tt>NullValueInNestedPathException</tt>
* should be thrown on nested null-values or <tt>null</tt> should be returned
*/
public ObjectPropertyAccessStrategy(final ValueModel domainObjectHolder, boolean fieldAccessEnabled, boolean strictNullValueHandling) {
super(domainObjectHolder);
propertyAccessor = new DefaultMemberPropertyAccessor(domainObjectHolder.getValue(), fieldAccessEnabled, strictNullValueHandling);
}
/**
* Creates a child instance of <tt>ObjectPropertyAccessStrategy<tt>
* that will delegate to its parent for property access.
*
* @param parent <tt>ObjectPropertyAccessStrategy</tt> which will be used to provide property access
* @param basePropertyPath property path that will as a base when accessing
* the parent <tt>ObjectPropertyAccessStrategy</tt>
*/
protected ObjectPropertyAccessStrategy(ObjectPropertyAccessStrategy parent, String basePropertyPath) {
super(parent, basePropertyPath);
propertyAccessor = parent.propertyAccessor;
}
/**
* Provides <code>DefaultMemberPropertyAccessor</code> access to subclasses.
*/
protected PropertyAccessor getPropertyAccessor() {
return propertyAccessor;
}
public MutablePropertyAccessStrategy getPropertyAccessStrategyForPath(String propertyPath) throws BeansException {
return new ObjectPropertyAccessStrategy(this, getFullPropertyPath(propertyPath));
}
public MutablePropertyAccessStrategy newPropertyAccessStrategy(ValueModel domainObjectHolder) {
return new ObjectPropertyAccessStrategy(domainObjectHolder);
}
protected void domainObjectChanged() {
propertyAccessor.setTarget(getDomainObject());
}
}