Skip to content

Commit cfd01ab

Browse files
committed
ExtendedBeanInfo uses explicit hashCode calculation (as defensive measure against JDK PropertyDescriptor changes)
1 parent 8c9274e commit cfd01ab

File tree

1 file changed

+36
-53
lines changed

1 file changed

+36
-53
lines changed

spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java

+36-53
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -35,6 +35,8 @@
3535
import java.util.Set;
3636
import java.util.TreeSet;
3737

38+
import org.springframework.util.ObjectUtils;
39+
3840
import static org.springframework.beans.PropertyDescriptorUtils.*;
3941

4042
/**
@@ -115,7 +117,7 @@ private List<Method> findCandidateWriteMethods(MethodDescriptor[] methodDescript
115117
matches.add(method);
116118
}
117119
}
118-
// sort non-void returning write methods to guard against the ill effects of
120+
// Sort non-void returning write methods to guard against the ill effects of
119121
// non-deterministic sorting of methods returned from Class#getDeclaredMethods
120122
// under JDK 7. See http://bugs.sun.com/view_bug.do?bug_id=7023180
121123
Collections.sort(matches, new Comparator<Method>() {
@@ -310,8 +312,14 @@ public void setPropertyEditorClass(Class<?> propertyEditorClass) {
310312
}
311313

312314
@Override
313-
public boolean equals(Object obj) {
314-
return PropertyDescriptorUtils.equals(this, obj);
315+
public boolean equals(Object other) {
316+
return (this == other || (other instanceof PropertyDescriptor &&
317+
PropertyDescriptorUtils.equals(this, (PropertyDescriptor) other)));
318+
}
319+
320+
@Override
321+
public int hashCode() {
322+
return (ObjectUtils.nullSafeHashCode(getReadMethod()) * 29 + ObjectUtils.nullSafeHashCode(getWriteMethod()));
315323
}
316324

317325
@Override
@@ -437,24 +445,27 @@ public void setPropertyEditorClass(Class<?> propertyEditorClass) {
437445
* See java.beans.IndexedPropertyDescriptor#equals(java.lang.Object)
438446
*/
439447
@Override
440-
public boolean equals(Object obj) {
441-
if (this == obj) {
448+
public boolean equals(Object other) {
449+
if (this == other) {
442450
return true;
443451
}
444-
if (obj != null && obj instanceof IndexedPropertyDescriptor) {
445-
IndexedPropertyDescriptor other = (IndexedPropertyDescriptor) obj;
446-
if (!compareMethods(getIndexedReadMethod(), other.getIndexedReadMethod())) {
447-
return false;
448-
}
449-
if (!compareMethods(getIndexedWriteMethod(), other.getIndexedWriteMethod())) {
450-
return false;
451-
}
452-
if (getIndexedPropertyType() != other.getIndexedPropertyType()) {
453-
return false;
454-
}
455-
return PropertyDescriptorUtils.equals(this, obj);
452+
if (!(other instanceof IndexedPropertyDescriptor)) {
453+
return false;
456454
}
457-
return false;
455+
IndexedPropertyDescriptor otherPd = (IndexedPropertyDescriptor) other;
456+
return (ObjectUtils.nullSafeEquals(getIndexedReadMethod(), otherPd.getIndexedReadMethod()) &&
457+
ObjectUtils.nullSafeEquals(getIndexedWriteMethod(), otherPd.getIndexedWriteMethod()) &&
458+
ObjectUtils.nullSafeEquals(getIndexedPropertyType(), otherPd.getIndexedPropertyType()) &&
459+
PropertyDescriptorUtils.equals(this, otherPd));
460+
}
461+
462+
@Override
463+
public int hashCode() {
464+
int hashCode = ObjectUtils.nullSafeHashCode(getReadMethod());
465+
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getWriteMethod());
466+
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getIndexedReadMethod());
467+
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getIndexedWriteMethod());
468+
return hashCode;
458469
}
459470

460471
@Override
@@ -595,40 +606,12 @@ else if (params[1].isAssignableFrom(indexedPropertyType)) {
595606
* editor and flags are equivalent.
596607
* @see PropertyDescriptor#equals(Object)
597608
*/
598-
public static boolean equals(PropertyDescriptor pd1, Object obj) {
599-
if (pd1 == obj) {
600-
return true;
601-
}
602-
if (obj != null && obj instanceof PropertyDescriptor) {
603-
PropertyDescriptor pd2 = (PropertyDescriptor) obj;
604-
if (!compareMethods(pd1.getReadMethod(), pd2.getReadMethod())) {
605-
return false;
606-
}
607-
if (!compareMethods(pd1.getWriteMethod(), pd2.getWriteMethod())) {
608-
return false;
609-
}
610-
if (pd1.getPropertyType() == pd2.getPropertyType() &&
611-
pd1.getPropertyEditorClass() == pd2.getPropertyEditorClass() &&
612-
pd1.isBound() == pd2.isBound() && pd1.isConstrained() == pd2.isConstrained()) {
613-
return true;
614-
}
615-
}
616-
return false;
617-
}
618-
619-
/*
620-
* See PropertyDescriptor#compareMethods
621-
*/
622-
public static boolean compareMethods(Method a, Method b) {
623-
if ((a == null) != (b == null)) {
624-
return false;
625-
}
626-
if (a != null) {
627-
if (!a.equals(b)) {
628-
return false;
629-
}
630-
}
631-
return true;
609+
public static boolean equals(PropertyDescriptor pd, PropertyDescriptor otherPd) {
610+
return (ObjectUtils.nullSafeEquals(pd.getReadMethod(), otherPd.getReadMethod()) &&
611+
ObjectUtils.nullSafeEquals(pd.getWriteMethod(), otherPd.getWriteMethod()) &&
612+
ObjectUtils.nullSafeEquals(pd.getPropertyType(), otherPd.getPropertyType()) &&
613+
ObjectUtils.nullSafeEquals(pd.getPropertyEditorClass(), otherPd.getPropertyEditorClass()) &&
614+
pd.isBound() == otherPd.isBound() && pd.isConstrained() == otherPd.isConstrained());
632615
}
633616
}
634617

0 commit comments

Comments
 (0)