diff --git a/src/main/java/org/springframework/data/mapping/model/SimpleTypeHolder.java b/src/main/java/org/springframework/data/mapping/model/SimpleTypeHolder.java index 1c8168b6f..648522951 100644 --- a/src/main/java/org/springframework/data/mapping/model/SimpleTypeHolder.java +++ b/src/main/java/org/springframework/data/mapping/model/SimpleTypeHolder.java @@ -21,6 +21,7 @@ import java.util.Date; import java.util.HashSet; import java.util.Locale; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.WeakHashMap; @@ -31,6 +32,7 @@ import org.springframework.util.Assert; * * @author Oliver Gierke * @author Christoph Strobl + * @author Mark Paluch */ public class SimpleTypeHolder { @@ -72,7 +74,7 @@ public class SimpleTypeHolder { }; public static final SimpleTypeHolder DEFAULT = new SimpleTypeHolder(); - private volatile Map, Class> simpleTypes; + private volatile Map, Boolean> simpleTypes; /** * Creates a new {@link SimpleTypeHolder} containing the default types. @@ -93,6 +95,7 @@ public class SimpleTypeHolder { public SimpleTypeHolder(Set> customSimpleTypes, boolean registerDefaults) { Assert.notNull(customSimpleTypes, "CustomSimpleTypes must not be null!"); + this.simpleTypes = new WeakHashMap<>(customSimpleTypes.size() + DEFAULTS.size()); register(customSimpleTypes); @@ -116,26 +119,42 @@ public class SimpleTypeHolder { this.simpleTypes = new WeakHashMap<>(customSimpleTypes.size() + source.simpleTypes.size()); register(customSimpleTypes); + registerCachePositives(source.simpleTypes); + } - this.simpleTypes.putAll(source.simpleTypes); + private void registerCachePositives(Map, Boolean> source) { + + for (Entry, Boolean> entry : source.entrySet()) { + + if (!entry.getValue()) { + continue; + } + + this.simpleTypes.put(entry.getKey(), true); + } } /** * Returns whether the given type is considered a simple one. * - * @param type + * @param type must not be {@literal null}. * @return */ public boolean isSimpleType(Class type) { Assert.notNull(type, "Type must not be null!"); - Map, Class> localSimpleTypes = this.simpleTypes; + Map, Boolean> localSimpleTypes = this.simpleTypes; + Boolean isSimpleType = localSimpleTypes.get(type); - if (Object.class.equals(type) || localSimpleTypes.containsKey(type)) { + if (Object.class.equals(type)) { return true; } + if (isSimpleType != null) { + return isSimpleType; + } + if (type.getName().startsWith("java.lang")) { return true; } @@ -144,19 +163,25 @@ public class SimpleTypeHolder { if (simpleType.isAssignableFrom(type)) { - Map, Class> simpleTypes = new WeakHashMap<>(localSimpleTypes); - simpleTypes.put(type, type); - - this.simpleTypes = simpleTypes; - - return true; + isSimpleType = localSimpleTypes.get(simpleType); + this.simpleTypes = put(localSimpleTypes, type, isSimpleType); + return isSimpleType; } } + this.simpleTypes = put(localSimpleTypes, type, false); return false; } private void register(Collection> types) { - types.forEach(customSimpleType -> this.simpleTypes.put(customSimpleType, customSimpleType)); + types.forEach(customSimpleType -> this.simpleTypes.put(customSimpleType, true)); + } + + private static Map, Boolean> put(Map, Boolean> simpleTypes, Class type, boolean isSimpleType) { + + Map, Boolean> copy = new WeakHashMap<>(simpleTypes); + copy.put(type, isSimpleType); + + return copy; } } diff --git a/src/test/java/org/springframework/data/mapping/SimpleTypeHolderUnitTests.java b/src/test/java/org/springframework/data/mapping/SimpleTypeHolderUnitTests.java index 90d1ed770..34caed74e 100755 --- a/src/test/java/org/springframework/data/mapping/SimpleTypeHolderUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/SimpleTypeHolderUnitTests.java @@ -27,8 +27,9 @@ import org.springframework.data.mapping.model.SimpleTypeHolder; /** * Unit tests for {@link SimpleTypeHolder}. - * + * * @author Oliver Gierke + * @author Mark Paluch */ public class SimpleTypeHolderUnitTests { @@ -113,6 +114,23 @@ public class SimpleTypeHolderUnitTests { assertThat(holder.isSimpleType(Type.class)).isTrue(); } + @Test // DATACMNS-1101 + public void considersExtendedTypeAsSimple() { + + SimpleTypeHolder holder = SimpleTypeHolder.DEFAULT; + + assertThat(holder.isSimpleType(ExtendedPerson.class)).isFalse(); + } + + @Test // DATACMNS-1101 + public void considersExtendedTypeAsSimpleSeenBaseClassBefore() { + + SimpleTypeHolder holder = SimpleTypeHolder.DEFAULT; + + assertThat(holder.isSimpleType(Person.class)).isFalse(); + assertThat(holder.isSimpleType(ExtendedPerson.class)).isFalse(); + } + enum SimpleEnum { FOO; @@ -129,4 +147,12 @@ public class SimpleTypeHolderUnitTests { abstract boolean method(); } + + static class Person { + + } + + static class ExtendedPerson extends Person { + + } }