001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://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, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.beans; 018 019import java.util.Map; 020 021import org.springframework.core.convert.TypeDescriptor; 022 023/** 024 * Common interface for classes that can access named properties 025 * (such as bean properties of an object or fields in an object) 026 * Serves as base interface for {@link BeanWrapper}. 027 * 028 * @author Juergen Hoeller 029 * @since 1.1 030 * @see BeanWrapper 031 * @see PropertyAccessorFactory#forBeanPropertyAccess 032 * @see PropertyAccessorFactory#forDirectFieldAccess 033 */ 034public interface PropertyAccessor { 035 036 /** 037 * Path separator for nested properties. 038 * Follows normal Java conventions: getFoo().getBar() would be "foo.bar". 039 */ 040 String NESTED_PROPERTY_SEPARATOR = "."; 041 char NESTED_PROPERTY_SEPARATOR_CHAR = '.'; 042 043 /** 044 * Marker that indicates the start of a property key for an 045 * indexed or mapped property like "person.addresses[0]". 046 */ 047 String PROPERTY_KEY_PREFIX = "["; 048 char PROPERTY_KEY_PREFIX_CHAR = '['; 049 050 /** 051 * Marker that indicates the end of a property key for an 052 * indexed or mapped property like "person.addresses[0]". 053 */ 054 String PROPERTY_KEY_SUFFIX = "]"; 055 char PROPERTY_KEY_SUFFIX_CHAR = ']'; 056 057 058 /** 059 * Determine whether the specified property is readable. 060 * <p>Returns {@code false} if the property doesn't exist. 061 * @param propertyName the property to check 062 * (may be a nested path and/or an indexed/mapped property) 063 * @return whether the property is readable 064 */ 065 boolean isReadableProperty(String propertyName); 066 067 /** 068 * Determine whether the specified property is writable. 069 * <p>Returns {@code false} if the property doesn't exist. 070 * @param propertyName the property to check 071 * (may be a nested path and/or an indexed/mapped property) 072 * @return whether the property is writable 073 */ 074 boolean isWritableProperty(String propertyName); 075 076 /** 077 * Determine the property type for the specified property, 078 * either checking the property descriptor or checking the value 079 * in case of an indexed or mapped element. 080 * @param propertyName the property to check 081 * (may be a nested path and/or an indexed/mapped property) 082 * @return the property type for the particular property, 083 * or {@code null} if not determinable 084 * @throws PropertyAccessException if the property was valid but the 085 * accessor method failed 086 */ 087 Class<?> getPropertyType(String propertyName) throws BeansException; 088 089 /** 090 * Return a type descriptor for the specified property: 091 * preferably from the read method, falling back to the write method. 092 * @param propertyName the property to check 093 * (may be a nested path and/or an indexed/mapped property) 094 * @return the property type for the particular property, 095 * or {@code null} if not determinable 096 * @throws PropertyAccessException if the property was valid but the 097 * accessor method failed 098 */ 099 TypeDescriptor getPropertyTypeDescriptor(String propertyName) throws BeansException; 100 101 /** 102 * Get the current value of the specified property. 103 * @param propertyName the name of the property to get the value of 104 * (may be a nested path and/or an indexed/mapped property) 105 * @return the value of the property 106 * @throws InvalidPropertyException if there is no such property or 107 * if the property isn't readable 108 * @throws PropertyAccessException if the property was valid but the 109 * accessor method failed 110 */ 111 Object getPropertyValue(String propertyName) throws BeansException; 112 113 /** 114 * Set the specified value as current property value. 115 * @param propertyName the name of the property to set the value of 116 * (may be a nested path and/or an indexed/mapped property) 117 * @param value the new value 118 * @throws InvalidPropertyException if there is no such property or 119 * if the property isn't writable 120 * @throws PropertyAccessException if the property was valid but the 121 * accessor method failed or a type mismatch occurred 122 */ 123 void setPropertyValue(String propertyName, Object value) throws BeansException; 124 125 /** 126 * Set the specified value as current property value. 127 * @param pv an object containing the new property value 128 * @throws InvalidPropertyException if there is no such property or 129 * if the property isn't writable 130 * @throws PropertyAccessException if the property was valid but the 131 * accessor method failed or a type mismatch occurred 132 */ 133 void setPropertyValue(PropertyValue pv) throws BeansException; 134 135 /** 136 * Perform a batch update from a Map. 137 * <p>Bulk updates from PropertyValues are more powerful: This method is 138 * provided for convenience. Behavior will be identical to that of 139 * the {@link #setPropertyValues(PropertyValues)} method. 140 * @param map Map to take properties from. Contains property value objects, 141 * keyed by property name 142 * @throws InvalidPropertyException if there is no such property or 143 * if the property isn't writable 144 * @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions 145 * occurred for specific properties during the batch update. This exception bundles 146 * all individual PropertyAccessExceptions. All other properties will have been 147 * successfully updated. 148 */ 149 void setPropertyValues(Map<?, ?> map) throws BeansException; 150 151 /** 152 * The preferred way to perform a batch update. 153 * <p>Note that performing a batch update differs from performing a single update, 154 * in that an implementation of this class will continue to update properties 155 * if a <b>recoverable</b> error (such as a type mismatch, but <b>not</b> an 156 * invalid field name or the like) is encountered, throwing a 157 * {@link PropertyBatchUpdateException} containing all the individual errors. 158 * This exception can be examined later to see all binding errors. 159 * Properties that were successfully updated remain changed. 160 * <p>Does not allow unknown fields or invalid fields. 161 * @param pvs PropertyValues to set on the target object 162 * @throws InvalidPropertyException if there is no such property or 163 * if the property isn't writable 164 * @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions 165 * occurred for specific properties during the batch update. This exception bundles 166 * all individual PropertyAccessExceptions. All other properties will have been 167 * successfully updated. 168 * @see #setPropertyValues(PropertyValues, boolean, boolean) 169 */ 170 void setPropertyValues(PropertyValues pvs) throws BeansException; 171 172 /** 173 * Perform a batch update with more control over behavior. 174 * <p>Note that performing a batch update differs from performing a single update, 175 * in that an implementation of this class will continue to update properties 176 * if a <b>recoverable</b> error (such as a type mismatch, but <b>not</b> an 177 * invalid field name or the like) is encountered, throwing a 178 * {@link PropertyBatchUpdateException} containing all the individual errors. 179 * This exception can be examined later to see all binding errors. 180 * Properties that were successfully updated remain changed. 181 * @param pvs PropertyValues to set on the target object 182 * @param ignoreUnknown should we ignore unknown properties (not found in the bean) 183 * @throws InvalidPropertyException if there is no such property or 184 * if the property isn't writable 185 * @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions 186 * occurred for specific properties during the batch update. This exception bundles 187 * all individual PropertyAccessExceptions. All other properties will have been 188 * successfully updated. 189 * @see #setPropertyValues(PropertyValues, boolean, boolean) 190 */ 191 void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown) 192 throws BeansException; 193 194 /** 195 * Perform a batch update with full control over behavior. 196 * <p>Note that performing a batch update differs from performing a single update, 197 * in that an implementation of this class will continue to update properties 198 * if a <b>recoverable</b> error (such as a type mismatch, but <b>not</b> an 199 * invalid field name or the like) is encountered, throwing a 200 * {@link PropertyBatchUpdateException} containing all the individual errors. 201 * This exception can be examined later to see all binding errors. 202 * Properties that were successfully updated remain changed. 203 * @param pvs PropertyValues to set on the target object 204 * @param ignoreUnknown should we ignore unknown properties (not found in the bean) 205 * @param ignoreInvalid should we ignore invalid properties (found but not accessible) 206 * @throws InvalidPropertyException if there is no such property or 207 * if the property isn't writable 208 * @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions 209 * occurred for specific properties during the batch update. This exception bundles 210 * all individual PropertyAccessExceptions. All other properties will have been 211 * successfully updated. 212 */ 213 void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid) 214 throws BeansException; 215 216}