Showing the changes to java/pkg/java/beans/IndexedPropertyDescriptor.java (1 of 18352 files). Show all
Unified · Split
| @@ -0,0 +1,523 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.beans; | |
| 27 | + | |
| 28 | +import java.lang.ref.Reference; | |
| 29 | +import java.lang.reflect.Method; | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * An IndexedPropertyDescriptor describes a property that acts like an | |
| 33 | + * array and has an indexed read and/or indexed write method to access | |
| 34 | + * specific elements of the array. | |
| 35 | + * <p> | |
| 36 | + * An indexed property may also provide simple non-indexed read and write | |
| 37 | + * methods. If these are present, they read and write arrays of the type | |
| 38 | + * returned by the indexed read method. | |
| 39 | + */ | |
| 40 | + | |
| 41 | +public class IndexedPropertyDescriptor extends PropertyDescriptor { | |
| 42 | + | |
| 43 | + private Reference<Class> indexedPropertyTypeRef; | |
| 44 | + private Reference<Method> indexedReadMethodRef; | |
| 45 | + private Reference<Method> indexedWriteMethodRef; | |
| 46 | + | |
| 47 | + private String indexedReadMethodName; | |
| 48 | + private String indexedWriteMethodName; | |
| 49 | + | |
| 50 | + /** | |
| 51 | + * This constructor constructs an IndexedPropertyDescriptor for a property | |
| 52 | + * that follows the standard Java conventions by having getFoo and setFoo | |
| 53 | + * accessor methods, for both indexed access and array access. | |
| 54 | + * <p> | |
| 55 | + * Thus if the argument name is "fred", it will assume that there | |
| 56 | + * is an indexed reader method "getFred", a non-indexed (array) reader | |
| 57 | + * method also called "getFred", an indexed writer method "setFred", | |
| 58 | + * and finally a non-indexed writer method "setFred". | |
| 59 | + * | |
| 60 | + * @param propertyName The programmatic name of the property. | |
| 61 | + * @param beanClass The Class object for the target bean. | |
| 62 | + * @exception IntrospectionException if an exception occurs during | |
| 63 | + * introspection. | |
| 64 | + */ | |
| 65 | + public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass) | |
| 66 | + throws IntrospectionException { | |
| 67 | + this(propertyName, beanClass, | |
| 68 | + Introspector.GET_PREFIX + NameGenerator.capitalize(propertyName), | |
| 69 | + Introspector.SET_PREFIX + NameGenerator.capitalize(propertyName), | |
| 70 | + Introspector.GET_PREFIX + NameGenerator.capitalize(propertyName), | |
| 71 | + Introspector.SET_PREFIX + NameGenerator.capitalize(propertyName)); | |
| 72 | + } | |
| 73 | + | |
| 74 | + /** | |
| 75 | + * This constructor takes the name of a simple property, and method | |
| 76 | + * names for reading and writing the property, both indexed | |
| 77 | + * and non-indexed. | |
| 78 | + * | |
| 79 | + * @param propertyName The programmatic name of the property. | |
| 80 | + * @param beanClass The Class object for the target bean. | |
| 81 | + * @param readMethodName The name of the method used for reading the property | |
| 82 | + * values as an array. May be null if the property is write-only | |
| 83 | + * or must be indexed. | |
| 84 | + * @param writeMethodName The name of the method used for writing the property | |
| 85 | + * values as an array. May be null if the property is read-only | |
| 86 | + * or must be indexed. | |
| 87 | + * @param indexedReadMethodName The name of the method used for reading | |
| 88 | + * an indexed property value. | |
| 89 | + * May be null if the property is write-only. | |
| 90 | + * @param indexedWriteMethodName The name of the method used for writing | |
| 91 | + * an indexed property value. | |
| 92 | + * May be null if the property is read-only. | |
| 93 | + * @exception IntrospectionException if an exception occurs during | |
| 94 | + * introspection. | |
| 95 | + */ | |
| 96 | + public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass, | |
| 97 | + String readMethodName, String writeMethodName, | |
| 98 | + String indexedReadMethodName, String indexedWriteMethodName) | |
| 99 | + throws IntrospectionException { | |
| 100 | + super(propertyName, beanClass, readMethodName, writeMethodName); | |
| 101 | + | |
| 102 | + this.indexedReadMethodName = indexedReadMethodName; | |
| 103 | + if (indexedReadMethodName != null && getIndexedReadMethod() == null) { | |
| 104 | + throw new IntrospectionException("Method not found: " + indexedReadMethodName); | |
| 105 | + } | |
| 106 | + | |
| 107 | + this.indexedWriteMethodName = indexedWriteMethodName; | |
| 108 | + if (indexedWriteMethodName != null && getIndexedWriteMethod() == null) { | |
| 109 | + throw new IntrospectionException("Method not found: " + indexedWriteMethodName); | |
| 110 | + } | |
| 111 | + // Implemented only for type checking. | |
| 112 | + findIndexedPropertyType(getIndexedReadMethod(), getIndexedWriteMethod()); | |
| 113 | + } | |
| 114 | + | |
| 115 | + /** | |
| 116 | + * This constructor takes the name of a simple property, and Method | |
| 117 | + * objects for reading and writing the property. | |
| 118 | + * | |
| 119 | + * @param propertyName The programmatic name of the property. | |
| 120 | + * @param readMethod The method used for reading the property values as an array. | |
| 121 | + * May be null if the property is write-only or must be indexed. | |
| 122 | + * @param writeMethod The method used for writing the property values as an array. | |
| 123 | + * May be null if the property is read-only or must be indexed. | |
| 124 | + * @param indexedReadMethod The method used for reading an indexed property value. | |
| 125 | + * May be null if the property is write-only. | |
| 126 | + * @param indexedWriteMethod The method used for writing an indexed property value. | |
| 127 | + * May be null if the property is read-only. | |
| 128 | + * @exception IntrospectionException if an exception occurs during | |
| 129 | + * introspection. | |
| 130 | + */ | |
| 131 | + public IndexedPropertyDescriptor(String propertyName, Method readMethod, Method writeMethod, | |
| 132 | + Method indexedReadMethod, Method indexedWriteMethod) | |
| 133 | + throws IntrospectionException { | |
| 134 | + super(propertyName, readMethod, writeMethod); | |
| 135 | + | |
| 136 | + setIndexedReadMethod0(indexedReadMethod); | |
| 137 | + setIndexedWriteMethod0(indexedWriteMethod); | |
| 138 | + | |
| 139 | + // Type checking | |
| 140 | + setIndexedPropertyType(findIndexedPropertyType(indexedReadMethod, indexedWriteMethod)); | |
| 141 | + } | |
| 142 | + | |
| 143 | + /** | |
| 144 | + * Creates <code>PropertyDescriptor</code> for the specified bean | |
| 145 | + * with the specified name and methods to read/write the property value. | |
| 146 | + * | |
| 147 | + * @param bean the type of the target bean | |
| 148 | + * @param base the base name of the property (the rest of the method name) | |
| 149 | + * @param read the method used for reading the property value | |
| 150 | + * @param write the method used for writing the property value | |
| 151 | + * @param readIndexed the method used for reading an indexed property value | |
| 152 | + * @param writeIndexed the method used for writing an indexed property value | |
| 153 | + * @exception IntrospectionException if an exception occurs during introspection | |
| 154 | + * | |
| 155 | + * @since 1.7 | |
| 156 | + */ | |
| 157 | + IndexedPropertyDescriptor(Class<?> bean, String base, Method read, Method write, Method readIndexed, Method writeIndexed) throws IntrospectionException { | |
| 158 | + super(bean, base, read, write); | |
| 159 | + | |
| 160 | + setIndexedReadMethod0(readIndexed); | |
| 161 | + setIndexedWriteMethod0(writeIndexed); | |
| 162 | + | |
| 163 | + // Type checking | |
| 164 | + setIndexedPropertyType(findIndexedPropertyType(readIndexed, writeIndexed)); | |
| 165 | + } | |
| 166 | + | |
| 167 | + /** | |
| 168 | + * Gets the method that should be used to read an indexed | |
| 169 | + * property value. | |
| 170 | + * | |
| 171 | + * @return The method that should be used to read an indexed | |
| 172 | + * property value. | |
| 173 | + * May return null if the property isn't indexed or is write-only. | |
| 174 | + */ | |
| 175 | + public synchronized Method getIndexedReadMethod() { | |
| 176 | + Method indexedReadMethod = getIndexedReadMethod0(); | |
| 177 | + if (indexedReadMethod == null) { | |
| 178 | + Class cls = getClass0(); | |
| 179 | + if (cls == null || | |
| 180 | + (indexedReadMethodName == null && indexedReadMethodRef == null)) { | |
| 181 | + // the Indexed readMethod was explicitly set to null. | |
| 182 | + return null; | |
| 183 | + } | |
| 184 | + if (indexedReadMethodName == null) { | |
| 185 | + Class type = getIndexedPropertyType0(); | |
| 186 | + if (type == boolean.class || type == null) { | |
| 187 | + indexedReadMethodName = Introspector.IS_PREFIX + getBaseName(); | |
| 188 | + } else { | |
| 189 | + indexedReadMethodName = Introspector.GET_PREFIX + getBaseName(); | |
| 190 | + } | |
| 191 | + } | |
| 192 | + | |
| 193 | + Class[] args = { int.class }; | |
| 194 | + indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args); | |
| 195 | + if (indexedReadMethod == null) { | |
| 196 | + // no "is" method, so look for a "get" method. | |
| 197 | + indexedReadMethodName = Introspector.GET_PREFIX + getBaseName(); | |
| 198 | + indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args); | |
| 199 | + } | |
| 200 | + setIndexedReadMethod0(indexedReadMethod); | |
| 201 | + } | |
| 202 | + return indexedReadMethod; | |
| 203 | + } | |
| 204 | + | |
| 205 | + /** | |
| 206 | + * Sets the method that should be used to read an indexed property value. | |
| 207 | + * | |
| 208 | + * @param readMethod The new indexed read method. | |
| 209 | + */ | |
| 210 | + public synchronized void setIndexedReadMethod(Method readMethod) | |
| 211 | + throws IntrospectionException { | |
| 212 | + | |
| 213 | + // the indexed property type is set by the reader. | |
| 214 | + setIndexedPropertyType(findIndexedPropertyType(readMethod, | |
| 215 | + getIndexedWriteMethod0())); | |
| 216 | + setIndexedReadMethod0(readMethod); | |
| 217 | + } | |
| 218 | + | |
| 219 | + private void setIndexedReadMethod0(Method readMethod) { | |
| 220 | + if (readMethod == null) { | |
| 221 | + indexedReadMethodName = null; | |
| 222 | + indexedReadMethodRef = null; | |
| 223 | + return; | |
| 224 | + } | |
| 225 | + setClass0(readMethod.getDeclaringClass()); | |
| 226 | + | |
| 227 | + indexedReadMethodName = readMethod.getName(); | |
| 228 | + this.indexedReadMethodRef = getSoftReference(readMethod); | |
| 229 | + setTransient(readMethod.getAnnotation(Transient.class)); | |
| 230 | + } | |
| 231 | + | |
| 232 | + | |
| 233 | + /** | |
| 234 | + * Gets the method that should be used to write an indexed property value. | |
| 235 | + * | |
| 236 | + * @return The method that should be used to write an indexed | |
| 237 | + * property value. | |
| 238 | + * May return null if the property isn't indexed or is read-only. | |
| 239 | + */ | |
| 240 | + public synchronized Method getIndexedWriteMethod() { | |
| 241 | + Method indexedWriteMethod = getIndexedWriteMethod0(); | |
| 242 | + if (indexedWriteMethod == null) { | |
| 243 | + Class cls = getClass0(); | |
| 244 | + if (cls == null || | |
| 245 | + (indexedWriteMethodName == null && indexedWriteMethodRef == null)) { | |
| 246 | + // the Indexed writeMethod was explicitly set to null. | |
| 247 | + return null; | |
| 248 | + } | |
| 249 | + | |
| 250 | + // We need the indexed type to ensure that we get the correct method. | |
| 251 | + // Cannot use the getIndexedPropertyType method since that could | |
| 252 | + // result in an infinite loop. | |
| 253 | + Class type = getIndexedPropertyType0(); | |
| 254 | + if (type == null) { | |
| 255 | + try { | |
| 256 | + type = findIndexedPropertyType(getIndexedReadMethod(), null); | |
| 257 | + setIndexedPropertyType(type); | |
| 258 | + } catch (IntrospectionException ex) { | |
| 259 | + // Set iprop type to be the classic type | |
| 260 | + Class propType = getPropertyType(); | |
| 261 | + if (propType.isArray()) { | |
| 262 | + type = propType.getComponentType(); | |
| 263 | + } | |
| 264 | + } | |
| 265 | + } | |
| 266 | + | |
| 267 | + if (indexedWriteMethodName == null) { | |
| 268 | + indexedWriteMethodName = Introspector.SET_PREFIX + getBaseName(); | |
| 269 | + } | |
| 270 | + | |
| 271 | + Class[] args = (type == null) ? null : new Class[] { int.class, type }; | |
| 272 | + indexedWriteMethod = Introspector.findMethod(cls, indexedWriteMethodName, 2, args); | |
| 273 | + if (indexedWriteMethod != null) { | |
| 274 | + if (!indexedWriteMethod.getReturnType().equals(void.class)) { | |
| 275 | + indexedWriteMethod = null; | |
| 276 | + } | |
| 277 | + } | |
| 278 | + setIndexedWriteMethod0(indexedWriteMethod); | |
| 279 | + } | |
| 280 | + return indexedWriteMethod; | |
| 281 | + } | |
| 282 | + | |
| 283 | + /** | |
| 284 | + * Sets the method that should be used to write an indexed property value. | |
| 285 | + * | |
| 286 | + * @param writeMethod The new indexed write method. | |
| 287 | + */ | |
| 288 | + public synchronized void setIndexedWriteMethod(Method writeMethod) | |
| 289 | + throws IntrospectionException { | |
| 290 | + | |
| 291 | + // If the indexed property type has not been set, then set it. | |
| 292 | + Class type = findIndexedPropertyType(getIndexedReadMethod(), | |
| 293 | + writeMethod); | |
| 294 | + setIndexedPropertyType(type); | |
| 295 | + setIndexedWriteMethod0(writeMethod); | |
| 296 | + } | |
| 297 | + | |
| 298 | + private void setIndexedWriteMethod0(Method writeMethod) { | |
| 299 | + if (writeMethod == null) { | |
| 300 | + indexedWriteMethodName = null; | |
| 301 | + indexedWriteMethodRef = null; | |
| 302 | + return; | |
| 303 | + } | |
| 304 | + setClass0(writeMethod.getDeclaringClass()); | |
| 305 | + | |
| 306 | + indexedWriteMethodName = writeMethod.getName(); | |
| 307 | + this.indexedWriteMethodRef = getSoftReference(writeMethod); | |
| 308 | + setTransient(writeMethod.getAnnotation(Transient.class)); | |
| 309 | + } | |
| 310 | + | |
| 311 | + /** | |
| 312 | + * Returns the Java type info for the indexed property. | |
| 313 | + * Note that the {@code Class} object may describe | |
| 314 | + * primitive Java types such as {@code int}. | |
| 315 | + * This type is returned by the indexed read method | |
| 316 | + * or is used as the parameter type of the indexed write method. | |
| 317 | + * | |
| 318 | + * @return the {@code Class} object that represents the Java type info, | |
| 319 | + * or {@code null} if the type cannot be determined | |
| 320 | + */ | |
| 321 | + public synchronized Class<?> getIndexedPropertyType() { | |
| 322 | + Class type = getIndexedPropertyType0(); | |
| 323 | + if (type == null) { | |
| 324 | + try { | |
| 325 | + type = findIndexedPropertyType(getIndexedReadMethod(), | |
| 326 | + getIndexedWriteMethod()); | |
| 327 | + setIndexedPropertyType(type); | |
| 328 | + } catch (IntrospectionException ex) { | |
| 329 | + // fall | |
| 330 | + } | |
| 331 | + } | |
| 332 | + return type; | |
| 333 | + } | |
| 334 | + | |
| 335 | + // Private methods which set get/set the Reference objects | |
| 336 | + | |
| 337 | + private void setIndexedPropertyType(Class type) { | |
| 338 | + this.indexedPropertyTypeRef = getWeakReference(type); | |
| 339 | + } | |
| 340 | + | |
| 341 | + private Class getIndexedPropertyType0() { | |
| 342 | + return (this.indexedPropertyTypeRef != null) | |
| 343 | + ? this.indexedPropertyTypeRef.get() | |
| 344 | + : null; | |
| 345 | + } | |
| 346 | + | |
| 347 | + private Method getIndexedReadMethod0() { | |
| 348 | + return (this.indexedReadMethodRef != null) | |
| 349 | + ? this.indexedReadMethodRef.get() | |
| 350 | + : null; | |
| 351 | + } | |
| 352 | + | |
| 353 | + private Method getIndexedWriteMethod0() { | |
| 354 | + return (this.indexedWriteMethodRef != null) | |
| 355 | + ? this.indexedWriteMethodRef.get() | |
| 356 | + : null; | |
| 357 | + } | |
| 358 | + | |
| 359 | + private Class findIndexedPropertyType(Method indexedReadMethod, | |
| 360 | + Method indexedWriteMethod) | |
| 361 | + throws IntrospectionException { | |
| 362 | + Class indexedPropertyType = null; | |
| 363 | + | |
| 364 | + if (indexedReadMethod != null) { | |
| 365 | + Class params[] = getParameterTypes(getClass0(), indexedReadMethod); | |
| 366 | + if (params.length != 1) { | |
| 367 | + throw new IntrospectionException("bad indexed read method arg count"); | |
| 368 | + } | |
| 369 | + if (params[0] != Integer.TYPE) { | |
| 370 | + throw new IntrospectionException("non int index to indexed read method"); | |
| 371 | + } | |
| 372 | + indexedPropertyType = getReturnType(getClass0(), indexedReadMethod); | |
| 373 | + if (indexedPropertyType == Void.TYPE) { | |
| 374 | + throw new IntrospectionException("indexed read method returns void"); | |
| 375 | + } | |
| 376 | + } | |
| 377 | + if (indexedWriteMethod != null) { | |
| 378 | + Class params[] = getParameterTypes(getClass0(), indexedWriteMethod); | |
| 379 | + if (params.length != 2) { | |
| 380 | + throw new IntrospectionException("bad indexed write method arg count"); | |
| 381 | + } | |
| 382 | + if (params[0] != Integer.TYPE) { | |
| 383 | + throw new IntrospectionException("non int index to indexed write method"); | |
| 384 | + } | |
| 385 | + if (indexedPropertyType != null && indexedPropertyType != params[1]) { | |
| 386 | + throw new IntrospectionException( | |
| 387 | + "type mismatch between indexed read and indexed write methods: " | |
| 388 | + + getName()); | |
| 389 | + } | |
| 390 | + indexedPropertyType = params[1]; | |
| 391 | + } | |
| 392 | + Class propertyType = getPropertyType(); | |
| 393 | + if (propertyType != null && (!propertyType.isArray() || | |
| 394 | + propertyType.getComponentType() != indexedPropertyType)) { | |
| 395 | + throw new IntrospectionException("type mismatch between indexed and non-indexed methods: " | |
| 396 | + + getName()); | |
| 397 | + } | |
| 398 | + return indexedPropertyType; | |
| 399 | + } | |
| 400 | + | |
| 401 | + /** | |
| 402 | + * Compares this <code>PropertyDescriptor</code> against the specified object. | |
| 403 | + * Returns true if the objects are the same. Two <code>PropertyDescriptor</code>s | |
| 404 | + * are the same if the read, write, property types, property editor and | |
| 405 | + * flags are equivalent. | |
| 406 | + * | |
| 407 | + * @since 1.4 | |
| 408 | + */ | |
| 409 | + public boolean equals(Object obj) { | |
| 410 | + // Note: This would be identical to PropertyDescriptor but they don't | |
| 411 | + // share the same fields. | |
| 412 | + if (this == obj) { | |
| 413 | + return true; | |
| 414 | + } | |
| 415 | + | |
| 416 | + if (obj != null && obj instanceof IndexedPropertyDescriptor) { | |
| 417 | + IndexedPropertyDescriptor other = (IndexedPropertyDescriptor)obj; | |
| 418 | + Method otherIndexedReadMethod = other.getIndexedReadMethod(); | |
| 419 | + Method otherIndexedWriteMethod = other.getIndexedWriteMethod(); | |
| 420 | + | |
| 421 | + if (!compareMethods(getIndexedReadMethod(), otherIndexedReadMethod)) { | |
| 422 | + return false; | |
| 423 | + } | |
| 424 | + | |
| 425 | + if (!compareMethods(getIndexedWriteMethod(), otherIndexedWriteMethod)) { | |
| 426 | + return false; | |
| 427 | + } | |
| 428 | + | |
| 429 | + if (getIndexedPropertyType() != other.getIndexedPropertyType()) { | |
| 430 | + return false; | |
| 431 | + } | |
| 432 | + return super.equals(obj); | |
| 433 | + } | |
| 434 | + return false; | |
| 435 | + } | |
| 436 | + | |
| 437 | + /** | |
| 438 | + * Package-private constructor. | |
| 439 | + * Merge two property descriptors. Where they conflict, give the | |
| 440 | + * second argument (y) priority over the first argumnnt (x). | |
| 441 | + * | |
| 442 | + * @param x The first (lower priority) PropertyDescriptor | |
| 443 | + * @param y The second (higher priority) PropertyDescriptor | |
| 444 | + */ | |
| 445 | + | |
| 446 | + IndexedPropertyDescriptor(PropertyDescriptor x, PropertyDescriptor y) { | |
| 447 | + super(x,y); | |
| 448 | + if (x instanceof IndexedPropertyDescriptor) { | |
| 449 | + IndexedPropertyDescriptor ix = (IndexedPropertyDescriptor)x; | |
| 450 | + try { | |
| 451 | + Method xr = ix.getIndexedReadMethod(); | |
| 452 | + if (xr != null) { | |
| 453 | + setIndexedReadMethod(xr); | |
| 454 | + } | |
| 455 | + | |
| 456 | + Method xw = ix.getIndexedWriteMethod(); | |
| 457 | + if (xw != null) { | |
| 458 | + setIndexedWriteMethod(xw); | |
| 459 | + } | |
| 460 | + } catch (IntrospectionException ex) { | |
| 461 | + // Should not happen | |
| 462 | + throw new AssertionError(ex); | |
| 463 | + } | |
| 464 | + } | |
| 465 | + if (y instanceof IndexedPropertyDescriptor) { | |
| 466 | + IndexedPropertyDescriptor iy = (IndexedPropertyDescriptor)y; | |
| 467 | + try { | |
| 468 | + Method yr = iy.getIndexedReadMethod(); | |
| 469 | + if (yr != null && yr.getDeclaringClass() == getClass0()) { | |
| 470 | + setIndexedReadMethod(yr); | |
| 471 | + } | |
| 472 | + | |
| 473 | + Method yw = iy.getIndexedWriteMethod(); | |
| 474 | + if (yw != null && yw.getDeclaringClass() == getClass0()) { | |
| 475 | + setIndexedWriteMethod(yw); | |
| 476 | + } | |
| 477 | + } catch (IntrospectionException ex) { | |
| 478 | + // Should not happen | |
| 479 | + throw new AssertionError(ex); | |
| 480 | + } | |
| 481 | + } | |
| 482 | + } | |
| 483 | + | |
| 484 | + /* | |
| 485 | + * Package-private dup constructor | |
| 486 | + * This must isolate the new object from any changes to the old object. | |
| 487 | + */ | |
| 488 | + IndexedPropertyDescriptor(IndexedPropertyDescriptor old) { | |
| 489 | + super(old); | |
| 490 | + indexedReadMethodRef = old.indexedReadMethodRef; | |
| 491 | + indexedWriteMethodRef = old.indexedWriteMethodRef; | |
| 492 | + indexedPropertyTypeRef = old.indexedPropertyTypeRef; | |
| 493 | + indexedWriteMethodName = old.indexedWriteMethodName; | |
| 494 | + indexedReadMethodName = old.indexedReadMethodName; | |
| 495 | + } | |
| 496 | + | |
| 497 | + /** | |
| 498 | + * Returns a hash code value for the object. | |
| 499 | + * See {@link java.lang.Object#hashCode} for a complete description. | |
| 500 | + * | |
| 501 | + * @return a hash code value for this object. | |
| 502 | + * @since 1.5 | |
| 503 | + */ | |
| 504 | + public int hashCode() { | |
| 505 | + int result = super.hashCode(); | |
| 506 | + | |
| 507 | + result = 37 * result + ((indexedWriteMethodName == null) ? 0 : | |
| 508 | + indexedWriteMethodName.hashCode()); | |
| 509 | + result = 37 * result + ((indexedReadMethodName == null) ? 0 : | |
| 510 | + indexedReadMethodName.hashCode()); | |
| 511 | + result = 37 * result + ((getIndexedPropertyType() == null) ? 0 : | |
| 512 | + getIndexedPropertyType().hashCode()); | |
| 513 | + | |
| 514 | + return result; | |
| 515 | + } | |
| 516 | + | |
| 517 | + void appendTo(StringBuilder sb) { | |
| 518 | + super.appendTo(sb); | |
| 519 | + appendTo(sb, "indexedPropertyType", this.indexedPropertyTypeRef); | |
| 520 | + appendTo(sb, "indexedReadMethod", this.indexedReadMethodRef); | |
| 521 | + appendTo(sb, "indexedWriteMethod", this.indexedWriteMethodRef); | |
| 522 | + } | |
| 523 | +} | |