From 03a6a84bf97b5cfcf5bd48a0f76421aca3bd3fbd Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Wed, 1 Mar 2023 22:34:24 +0100 Subject: [PATCH] Polishing in mapping package. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nullable annotations and Objects.equals(…) and Objects.hash(…)/Objects.hashCode(…). Records for internal cache key. Related issue: #2813. --- .../springframework/data/mapping/Alias.java | 11 +-- .../data/mapping/Parameter.java | 29 ++---- .../data/mapping/PreferredConstructor.java | 13 ++- .../data/mapping/PropertyPath.java | 89 +++---------------- 4 files changed, 34 insertions(+), 108 deletions(-) diff --git a/src/main/java/org/springframework/data/mapping/Alias.java b/src/main/java/org/springframework/data/mapping/Alias.java index dc3f73f76..36e66c54c 100644 --- a/src/main/java/org/springframework/data/mapping/Alias.java +++ b/src/main/java/org/springframework/data/mapping/Alias.java @@ -15,9 +15,10 @@ */ package org.springframework.data.mapping; +import java.util.Objects; + import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.ObjectUtils; /** * A container object which may or may not contain a type alias value. If a value is present, {@code isPresent()} will @@ -144,21 +145,21 @@ public final class Alias { } @Override - public boolean equals(Object o) { + public boolean equals(@Nullable Object o) { if (this == o) { return true; } - if (!(o instanceof Alias alias)) { + if (!(o instanceof Alias that)) { return false; } - return ObjectUtils.nullSafeEquals(value, alias.value); + return Objects.equals(this.value, that.value); } @Override public int hashCode() { - return ObjectUtils.nullSafeHashCode(value); + return Objects.hashCode(value); } } diff --git a/src/main/java/org/springframework/data/mapping/Parameter.java b/src/main/java/org/springframework/data/mapping/Parameter.java index 0f067a338..d7fe00135 100644 --- a/src/main/java/org/springframework/data/mapping/Parameter.java +++ b/src/main/java/org/springframework/data/mapping/Parameter.java @@ -16,6 +16,7 @@ package org.springframework.data.mapping; import java.lang.annotation.Annotation; +import java.util.Objects; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.annotation.MergedAnnotations; @@ -23,7 +24,6 @@ import org.springframework.data.util.Lazy; import org.springframework.data.util.TypeInformation; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; /** @@ -144,38 +144,25 @@ public class Parameter> { } @Override - public boolean equals(Object o) { + public boolean equals(@Nullable Object o) { if (this == o) { return true; } - if (!(o instanceof Parameter parameter)) { + if (!(o instanceof Parameter that)) { return false; } - if (!ObjectUtils.nullSafeEquals(name, parameter.name)) { - return false; - } - - if (!ObjectUtils.nullSafeEquals(type, parameter.type)) { - return false; - } - - if (!ObjectUtils.nullSafeEquals(key, parameter.key)) { - return false; - } - - return ObjectUtils.nullSafeEquals(entity, parameter.entity); + return Objects.equals(this.name, that.name) + && Objects.equals(this.type, that.type) + && Objects.equals(this.key, that.key) + && Objects.equals(this.entity, that.entity); } @Override public int hashCode() { - int result = ObjectUtils.nullSafeHashCode(name); - result = 31 * result + ObjectUtils.nullSafeHashCode(type); - result = 31 * result + ObjectUtils.nullSafeHashCode(key); - result = 31 * result + ObjectUtils.nullSafeHashCode(entity); - return result; + return Objects.hash(name, type, key, entity); } /** diff --git a/src/main/java/org/springframework/data/mapping/PreferredConstructor.java b/src/main/java/org/springframework/data/mapping/PreferredConstructor.java index f3a9e9177..58b128000 100644 --- a/src/main/java/org/springframework/data/mapping/PreferredConstructor.java +++ b/src/main/java/org/springframework/data/mapping/PreferredConstructor.java @@ -21,6 +21,7 @@ import java.util.List; import org.springframework.core.annotation.MergedAnnotations; import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.annotation.PersistenceCreator; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; @@ -35,7 +36,9 @@ import org.springframework.util.ReflectionUtils; * @author Myeonghyeon Lee * @author Xeno Amess */ -public final class PreferredConstructor> extends InstanceCreatorMetadataSupport { +@SuppressWarnings("deprecation") +public final class PreferredConstructor> + extends InstanceCreatorMetadataSupport { private final List> parameters; @@ -59,11 +62,11 @@ public final class PreferredConstructor> exte * * @return */ + @SuppressWarnings("unchecked") public Constructor getConstructor() { return (Constructor) getExecutable(); } - /** * Returns whether the constructor does not have any arguments. * @@ -80,7 +83,11 @@ public final class PreferredConstructor> exte * @return */ public boolean isExplicitlyAnnotated() { - return MergedAnnotations.from(getExecutable()).isPresent(PersistenceConstructor.class); + + var annotations = MergedAnnotations.from(getExecutable()); + + return annotations.isPresent(PersistenceConstructor.class) + || annotations.isPresent(PersistenceCreator.class); } /** diff --git a/src/main/java/org/springframework/data/mapping/PropertyPath.java b/src/main/java/org/springframework/data/mapping/PropertyPath.java index a81093c53..f5ed23a28 100644 --- a/src/main/java/org/springframework/data/mapping/PropertyPath.java +++ b/src/main/java/org/springframework/data/mapping/PropertyPath.java @@ -21,6 +21,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -30,7 +31,6 @@ import org.springframework.data.util.TypeInformation; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ConcurrentReferenceHashMap; -import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; /** @@ -244,7 +244,7 @@ public class PropertyPath implements Streamable { } @Override - public boolean equals(Object o) { + public boolean equals(@Nullable Object o) { if (this == o) { return true; @@ -258,34 +258,16 @@ public class PropertyPath implements Streamable { return false; } - if (!ObjectUtils.nullSafeEquals(owningType, that.owningType)) { - return false; - } - - if (!ObjectUtils.nullSafeEquals(name, that.name)) { - return false; - } - - if (!ObjectUtils.nullSafeEquals(typeInformation, that.typeInformation)) { - return false; - } - - if (!ObjectUtils.nullSafeEquals(actualTypeInformation, that.actualTypeInformation)) { - return false; - } - - return ObjectUtils.nullSafeEquals(next, that.next); + return Objects.equals(this.owningType, that.owningType) + && Objects.equals(this.name, that.name) + && Objects.equals(this.typeInformation, that.typeInformation) + && Objects.equals(this.actualTypeInformation, that.actualTypeInformation) + && Objects.equals(next, that.next); } @Override public int hashCode() { - int result = ObjectUtils.nullSafeHashCode(owningType); - result = 31 * result + ObjectUtils.nullSafeHashCode(name); - result = 31 * result + ObjectUtils.nullSafeHashCode(typeInformation); - result = 31 * result + ObjectUtils.nullSafeHashCode(actualTypeInformation); - result = 31 * result + (isCollection ? 1 : 0); - result = 31 * result + ObjectUtils.nullSafeHashCode(next); - return result; + return Objects.hash(owningType, name, typeInformation, actualTypeInformation, isCollection, next); } /** @@ -331,7 +313,7 @@ public class PropertyPath implements Streamable { Assert.hasText(source, "Source must not be null or empty"); Assert.notNull(type, "TypeInformation must not be null or empty"); - return cache.computeIfAbsent(Key.of(type, source), it -> { + return cache.computeIfAbsent(new Key(type, source), it -> { List iteratorSource = new ArrayList<>(); @@ -467,56 +449,5 @@ public class PropertyPath implements Streamable { return String.format("%s.%s", owningType.getType().getSimpleName(), toDotPath()); } - private static final class Key { - - private final TypeInformation type; - private final String path; - - private Key(TypeInformation type, String path) { - this.type = type; - this.path = path; - } - - public static Key of(TypeInformation type, String path) { - return new Key(type, path); - } - - public TypeInformation getType() { - return this.type; - } - - public String getPath() { - return this.path; - } - - @Override - public boolean equals(Object o) { - - if (this == o) { - return true; - } - - if (!(o instanceof Key key)) { - return false; - } - - if (!ObjectUtils.nullSafeEquals(type, key.type)) { - return false; - } - - return ObjectUtils.nullSafeEquals(path, key.path); - } - - @Override - public int hashCode() { - int result = ObjectUtils.nullSafeHashCode(type); - result = 31 * result + ObjectUtils.nullSafeHashCode(path); - return result; - } - - @Override - public String toString() { - return "PropertyPath.Key(type=" + this.getType() + ", path=" + this.getPath() + ")"; - } - } + private record Key(TypeInformation type, String path) {}; }