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