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