001 /* 002 * Copyright 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.BeansException; 019 import org.springframework.beans.PropertyAccessor; 020 import org.springframework.binding.MutablePropertyAccessStrategy; 021 import org.springframework.binding.value.ValueModel; 022 import org.springframework.binding.value.support.ValueHolder; 023 import org.springframework.richclient.beans.DefaultMemberPropertyAccessor; 024 025 /** 026 * An implementation of <code>MutablePropertyAccessStrategy</code> that provides access 027 * to the properties of any object. 028 * 029 * <p>As this class delegates to a <code>DefaultMemberPropertyAccessor</code> for property access, 030 * there is full support for <b>nested properties</b> and collection types. 031 * 032 * @author Arne Limburg 033 * @see org.springframework.richclient.beans.DefaultMemberPropertyAccessor 034 */ 035 public class ObjectPropertyAccessStrategy extends AbstractPropertyAccessStrategy { 036 037 private final DefaultMemberPropertyAccessor propertyAccessor; 038 039 /** 040 * Creates a new instance of <tt>ObjectPropertyAccessStrategy</tt> 041 * that will provide access to the properties of the provided object. 042 * 043 * @param target object to be accessed through this class. 044 */ 045 public ObjectPropertyAccessStrategy(Object target) { 046 this(new ValueHolder(target)); 047 } 048 049 /** 050 * Creates a new instance of <tt>ObjectPropertyAccessStrategy</tt> 051 * that will provide access to the object contained by the provided value model. 052 * 053 * @param domainObjectHolder value model that holds the object 054 * to be accessed through this class 055 */ 056 public ObjectPropertyAccessStrategy(final ValueModel domainObjectHolder) { 057 this(domainObjectHolder, false); 058 } 059 060 /** 061 * Creates a new instance of <tt>ObjectPropertyAccessStrategy</tt> 062 * that will provide access to the object contained by the provided value model. 063 * 064 * @param domainObjectHolder value model that holds the object 065 * to be accessed through this class 066 * @param fieldAccessEnabled whether the fields of the objects 067 * should be accessed directly where possible 068 * instead of using methods 069 */ 070 public ObjectPropertyAccessStrategy(final ValueModel domainObjectHolder, boolean fieldAccessEnabled) { 071 this(domainObjectHolder, fieldAccessEnabled, true); 072 } 073 074 /** 075 * Creates a new instance of <tt>ObjectPropertyAccessStrategy</tt> 076 * that will provide access to the object contained by the provided value model. 077 * 078 * @param domainObjectHolder value model that holds the object 079 * to be accessed through this class 080 * @param fieldAccessEnabled whether the fields of the objects 081 * should be accessed directly where possible 082 * instead of using methods 083 * @param strictNullValueHandling whether a <tt>NullValueInNestedPathException</tt> 084 * should be thrown on nested null-values or <tt>null</tt> should be returned 085 */ 086 public ObjectPropertyAccessStrategy(final ValueModel domainObjectHolder, boolean fieldAccessEnabled, boolean strictNullValueHandling) { 087 super(domainObjectHolder); 088 propertyAccessor = new DefaultMemberPropertyAccessor(domainObjectHolder.getValue(), fieldAccessEnabled, strictNullValueHandling); 089 } 090 091 /** 092 * Creates a child instance of <tt>ObjectPropertyAccessStrategy<tt> 093 * that will delegate to its parent for property access. 094 * 095 * @param parent <tt>ObjectPropertyAccessStrategy</tt> which will be used to provide property access 096 * @param basePropertyPath property path that will as a base when accessing 097 * the parent <tt>ObjectPropertyAccessStrategy</tt> 098 */ 099 protected ObjectPropertyAccessStrategy(ObjectPropertyAccessStrategy parent, String basePropertyPath) { 100 super(parent, basePropertyPath); 101 propertyAccessor = parent.propertyAccessor; 102 } 103 104 /** 105 * Provides <code>DefaultMemberPropertyAccessor</code> access to subclasses. 106 */ 107 protected PropertyAccessor getPropertyAccessor() { 108 return propertyAccessor; 109 } 110 111 public MutablePropertyAccessStrategy getPropertyAccessStrategyForPath(String propertyPath) throws BeansException { 112 return new ObjectPropertyAccessStrategy(this, getFullPropertyPath(propertyPath)); 113 } 114 115 public MutablePropertyAccessStrategy newPropertyAccessStrategy(ValueModel domainObjectHolder) { 116 return new ObjectPropertyAccessStrategy(domainObjectHolder); 117 } 118 119 protected void domainObjectChanged() { 120 propertyAccessor.setTarget(getDomainObject()); 121 } 122 }