Browse Source

Polishing.

Move all primary interaction API into TypeInformation to prepare making all implementations package protected. Adapt all deprecated API usage in Spring Data Commons to the new one.

Benchmark results look as follows:

2.7
                                                                                                Mode  Cnt          Score          Error  Units
TypicalEntityReaderBenchmark.hasReadTarget                                                     thrpt   10   81982861,995 ±   269948,368  ops/s
TypicalEntityReaderBenchmark.kotlinDataClass                                                   thrpt   10   18472975,689 ±   161234,912  ops/s
TypicalEntityReaderBenchmark.kotlinDataClassWithDefaulting                                     thrpt   10    4029631,568 ±    18990,863  ops/s
TypicalEntityReaderBenchmark.simpleEntityGeneratedConstructorAndField                          thrpt   10   11495517,933 ±   209269,454  ops/s
TypicalEntityReaderBenchmark.simpleEntityGeneratedConstructorAndProperty                       thrpt   10   11192152,036 ±   249721,563  ops/s
TypicalEntityReaderBenchmark.simpleEntityGeneratedConstructorArgsCreation                      thrpt   10   18835101,279 ±    81895,338  ops/s
TypicalEntityReaderBenchmark.simpleEntityGeneratedFieldAccess                                  thrpt   10   16309896,939 ±    80376,406  ops/s
TypicalEntityReaderBenchmark.simpleEntityGeneratedPropertyAccess                               thrpt   10   15471691,537 ±    52426,121  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectiveConstructorAndField                         thrpt   10   12080159,283 ±    49922,326  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectiveConstructorAndProperty                      thrpt   10   12166160,066 ±   173876,051  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectiveConstructorArgsCreation                     thrpt   10   13548906,437 ±   485944,886  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectiveFieldAccess                                 thrpt   10   16457347,670 ±    64170,567  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectivePropertyAccess                              thrpt   10   14115878,948 ±    57491,268  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectivePropertyAccessWithCustomConversionRegistry  thrpt   10   15137904,257 ±    51148,726  ops/s

DefaultTypeMapperBenchmark.readTyped                                                           thrpt   10  146820080,682 ± 13254238,407  ops/s
DefaultTypeMapperBenchmark.readTypedWithBaseType                                               thrpt   10   55420351,827 ±  1888634,217  ops/s
DefaultTypeMapperBenchmark.readUntyped                                                         thrpt   10  193934847,273 ±   442867,276  ops/s
DefaultTypeMapperBenchmark.readUntypedWithBaseType                                             thrpt   10  192032977,366 ±  4300192,665  ops/s

3.0 – Before this change
                                                                                                Mode  Cnt          Score         Error  Units
TypicalEntityReaderBenchmark.hasReadTarget                                                     thrpt   10   81124249,138 ±  174095,495  ops/s
TypicalEntityReaderBenchmark.kotlinDataClass                                                   thrpt   10   18685936,220 ±  243939,063  ops/s
TypicalEntityReaderBenchmark.kotlinDataClassWithDefaulting                                     thrpt   10    4125709,048 ±   17615,890  ops/s
TypicalEntityReaderBenchmark.simpleEntityGeneratedConstructorAndField                          thrpt   10   12277837,989 ±   96973,908  ops/s
TypicalEntityReaderBenchmark.simpleEntityGeneratedConstructorAndProperty                       thrpt   10   12419978,391 ±   45780,658  ops/s
TypicalEntityReaderBenchmark.simpleEntityGeneratedConstructorArgsCreation                      thrpt   10   18744593,010 ±   71655,735  ops/s
TypicalEntityReaderBenchmark.simpleEntityGeneratedFieldAccess                                  thrpt   10   16497286,465 ±   41150,718  ops/s
TypicalEntityReaderBenchmark.simpleEntityGeneratedPropertyAccess                               thrpt   10   15639640,554 ±   69758,391  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectiveConstructorAndField                         thrpt   10   11715068,503 ±   66085,900  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectiveConstructorAndProperty                      thrpt   10   12159285,083 ±   58171,950  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectiveConstructorArgsCreation                     thrpt   10   13711647,512 ±   66496,271  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectiveFieldAccess                                 thrpt   10   16287057,838 ±   54826,532  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectivePropertyAccess                              thrpt   10   13847665,634 ±  127834,292  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectivePropertyAccessWithCustomConversionRegistry  thrpt   10   15099300,270 ±   89030,403  ops/s

DefaultTypeMapperBenchmark.readTyped                                                           thrpt   10  151893972,774 ±  494555,250  ops/s
DefaultTypeMapperBenchmark.readTypedWithBaseType                                               thrpt   10   55869432,892 ±  389099,409  ops/s
DefaultTypeMapperBenchmark.readUntyped                                                         thrpt   10  192661151,755 ± 1075079,924  ops/s
DefaultTypeMapperBenchmark.readUntypedWithBaseType                                             thrpt   10  192315554,269 ± 3061160,314  ops/s

3.0 – After this change
                                                                                                Mode  Cnt          Score         Error  Units
TypicalEntityReaderBenchmark.hasReadTarget                                                     thrpt   10   82650245,236 ±  321384,577  ops/s
TypicalEntityReaderBenchmark.kotlinDataClass                                                   thrpt   10   21304680,430 ±  396764,834  ops/s
TypicalEntityReaderBenchmark.kotlinDataClassWithDefaulting                                     thrpt   10    4422187,275 ±   35088,721  ops/s
TypicalEntityReaderBenchmark.simpleEntityGeneratedConstructorAndField                          thrpt   10   13345503,496 ±  180490,423  ops/s
TypicalEntityReaderBenchmark.simpleEntityGeneratedConstructorAndProperty                       thrpt   10   13911653,366 ±  266028,886  ops/s
TypicalEntityReaderBenchmark.simpleEntityGeneratedConstructorArgsCreation                      thrpt   10   21192316,261 ±  356534,938  ops/s
TypicalEntityReaderBenchmark.simpleEntityGeneratedFieldAccess                                  thrpt   10   17533419,173 ±   49226,408  ops/s
TypicalEntityReaderBenchmark.simpleEntityGeneratedPropertyAccess                               thrpt   10   17393382,078 ±  114774,442  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectiveConstructorAndField                         thrpt   10   12867285,952 ±   62870,980  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectiveConstructorAndProperty                      thrpt   10   13208453,130 ±  272795,070  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectiveConstructorArgsCreation                     thrpt   10   14998467,714 ±   84265,782  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectiveFieldAccess                                 thrpt   10   17365982,413 ±  115287,403  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectivePropertyAccess                              thrpt   10   15503841,949 ±  123631,592  ops/s
TypicalEntityReaderBenchmark.simpleEntityReflectivePropertyAccessWithCustomConversionRegistry  thrpt   10   15716685,449 ±   64686,646  ops/s

DefaultTypeMapperBenchmark.readTyped                                                           thrpt   10  154433835,941 ± 1391455,835  ops/s
DefaultTypeMapperBenchmark.readTypedWithBaseType                                               thrpt   10   77919886,633 ±  438244,738  ops/s
DefaultTypeMapperBenchmark.readUntyped                                                         thrpt   10  194435210,217 ±  936274,571  ops/s
DefaultTypeMapperBenchmark.readUntypedWithBaseType                                             thrpt   10  193768718,043 ±  475103,167  ops/s

Original pull request: #2572.
Related ticket: #2312.
pull/2635/head
Oliver Drotbohm 4 years ago
parent
commit
07342cffb5
No known key found for this signature in database
GPG Key ID: C25FBFA0DA493A1D
  1. 7
      src/main/java/org/springframework/data/convert/ConfigurableTypeInformationMapper.java
  2. 11
      src/main/java/org/springframework/data/convert/DefaultTypeMapper.java
  3. 7
      src/main/java/org/springframework/data/convert/SimpleTypeInformationMapper.java
  4. 4
      src/main/java/org/springframework/data/convert/ValueConversionContext.java
  5. 4
      src/main/java/org/springframework/data/mapping/PropertyPath.java
  6. 14
      src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java
  7. 6
      src/main/java/org/springframework/data/mapping/context/PersistentPropertyPathFactory.java
  8. 2
      src/main/java/org/springframework/data/mapping/model/AnnotationBasedPersistentProperty.java
  9. 2
      src/main/java/org/springframework/data/mapping/model/PreferredConstructorDiscoverer.java
  10. 6
      src/main/java/org/springframework/data/projection/EntityProjection.java
  11. 17
      src/main/java/org/springframework/data/projection/EntityProjectionIntrospector.java
  12. 8
      src/main/java/org/springframework/data/projection/ProjectingMethodInterceptor.java
  13. 7
      src/main/java/org/springframework/data/querydsl/binding/QuerydslBindings.java
  14. 3
      src/main/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadata.java
  15. 3
      src/main/java/org/springframework/data/repository/core/support/AnnotationRepositoryMetadata.java
  16. 3
      src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadata.java
  17. 11
      src/main/java/org/springframework/data/repository/core/support/MethodInvocationValidator.java
  18. 6
      src/main/java/org/springframework/data/repository/core/support/MethodLookup.java
  19. 11
      src/main/java/org/springframework/data/repository/core/support/MethodLookups.java
  20. 8
      src/main/java/org/springframework/data/repository/core/support/RepositoryComposition.java
  21. 7
      src/main/java/org/springframework/data/repository/query/Parameter.java
  22. 7
      src/main/java/org/springframework/data/repository/query/QueryMethod.java
  23. 17
      src/main/java/org/springframework/data/repository/util/ClassUtils.java
  24. 104
      src/main/java/org/springframework/data/util/ClassTypeInformation.java
  25. 386
      src/main/java/org/springframework/data/util/TypeDiscoverer.java
  26. 94
      src/main/java/org/springframework/data/util/TypeInformation.java
  27. 4
      src/main/java/org/springframework/data/web/JsonProjectingMethodInterceptorFactory.java
  28. 5
      src/main/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolverSupport.java
  29. 9
      src/test/java/org/springframework/data/convert/ConfigurableTypeInformationMapperUnitTests.java
  30. 6
      src/test/java/org/springframework/data/convert/DefaultTypeMapperUnitTests.java
  31. 11
      src/test/java/org/springframework/data/convert/MappingContextTypeInformationMapperUnitTests.java
  32. 4
      src/test/java/org/springframework/data/convert/SimpleTypeInformationMapperUnitTests.java
  33. 6
      src/test/java/org/springframework/data/mapping/ParameterUnitTests.java
  34. 11
      src/test/java/org/springframework/data/mapping/PreferredConstructorDiscovererUnitTests.java
  35. 4
      src/test/java/org/springframework/data/mapping/PropertyPathUnitTests.java
  36. 4
      src/test/java/org/springframework/data/mapping/PropertyReferenceExceptionUnitTests.java
  37. 3
      src/test/java/org/springframework/data/mapping/context/AbstractMappingContextIntegrationTests.java
  38. 8
      src/test/java/org/springframework/data/mapping/context/AbstractMappingContextUnitTests.java
  39. 5
      src/test/java/org/springframework/data/mapping/context/PersistentEntitiesUnitTests.java
  40. 11
      src/test/java/org/springframework/data/mapping/model/AbstractPersistentPropertyUnitTests.java
  41. 8
      src/test/java/org/springframework/data/mapping/model/AnnotationBasedPersistentPropertyUnitTests.java
  42. 7
      src/test/java/org/springframework/data/mapping/model/BasicPersistentEntityUnitTests.java
  43. 16
      src/test/java/org/springframework/data/mapping/model/ClassGeneratingEntityInstantiatorUnitTests.java
  44. 1
      src/test/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactoryEntityTypeTests.java
  45. 10
      src/test/java/org/springframework/data/mapping/model/EntityCreatorMetadataDiscovererUnitTests.java
  46. 4
      src/test/java/org/springframework/data/mapping/model/FactoryMethodUnitTests.java
  47. 6
      src/test/java/org/springframework/data/mapping/model/PersistentEntityParameterValueProviderUnitTests.java
  48. 15
      src/test/java/org/springframework/data/mapping/model/PropertyUnitTests.java
  49. 6
      src/test/java/org/springframework/data/mapping/model/ReflectionEntityInstantiatorUnitTests.java
  50. 6
      src/test/java/org/springframework/data/querydsl/binding/QuerydslBindingsFactoryUnitTests.java
  51. 11
      src/test/java/org/springframework/data/querydsl/binding/QuerydslBindingsUnitTests.java
  52. 17
      src/test/java/org/springframework/data/querydsl/binding/QuerydslPredicateBuilderUnitTests.java
  53. 4
      src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadataUnitTests.java
  54. 5
      src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java
  55. 7
      src/test/java/org/springframework/data/repository/support/DomainClassConverterIntegrationTests.java
  56. 14
      src/test/java/org/springframework/data/repository/util/QueryExecutionConvertersUnitTests.java
  57. 144
      src/test/java/org/springframework/data/util/ClassTypeInformationUnitTests.java
  58. 2
      src/test/java/org/springframework/data/util/DataCmns511Tests.java
  59. 190
      src/test/java/org/springframework/data/util/TypeDiscovererUnitTests.java
  60. 10
      src/test/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolverUnitTests.java

7
src/main/java/org/springframework/data/convert/ConfigurableTypeInformationMapper.java

@ -22,7 +22,6 @@ import java.util.Map.Entry;
import org.springframework.data.mapping.Alias; import org.springframework.data.mapping.Alias;
import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -37,8 +36,8 @@ import org.springframework.util.Assert;
*/ */
public class ConfigurableTypeInformationMapper implements TypeInformationMapper { public class ConfigurableTypeInformationMapper implements TypeInformationMapper {
private final Map<ClassTypeInformation<?>, Alias> typeToAlias; private final Map<TypeInformation<?>, Alias> typeToAlias;
private final Map<Alias, ClassTypeInformation<?>> aliasToType; private final Map<Alias, TypeInformation<?>> aliasToType;
/** /**
* Creates a new {@link ConfigurableTypeInformationMapper} for the given type map. * Creates a new {@link ConfigurableTypeInformationMapper} for the given type map.
@ -54,7 +53,7 @@ public class ConfigurableTypeInformationMapper implements TypeInformationMapper
for (Entry<? extends Class<?>, String> entry : sourceTypeMap.entrySet()) { for (Entry<? extends Class<?>, String> entry : sourceTypeMap.entrySet()) {
ClassTypeInformation<?> type = ClassTypeInformation.from(entry.getKey()); TypeInformation<?> type = TypeInformation.of(entry.getKey());
Alias alias = Alias.of(entry.getValue()); Alias alias = Alias.of(entry.getValue());
if (typeToAlias.containsValue(alias)) { if (typeToAlias.containsValue(alias)) {

11
src/main/java/org/springframework/data/convert/DefaultTypeMapper.java

@ -27,7 +27,6 @@ import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.data.mapping.Alias; import org.springframework.data.mapping.Alias;
import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -149,16 +148,16 @@ public class DefaultTypeMapper<S> implements TypeMapper<S>, BeanClassLoaderAware
Class<T> rawType = basicType.getType(); Class<T> rawType = basicType.getType();
boolean isMoreConcreteCustomType = rawType == null boolean isMoreConcreteCustomType = (rawType == null)
|| rawType.isAssignableFrom(documentsTargetType) && !rawType.equals(documentsTargetType); || (rawType.isAssignableFrom(documentsTargetType) && !rawType.equals(documentsTargetType));
if (!isMoreConcreteCustomType) { if (!isMoreConcreteCustomType) {
return basicType; return basicType;
} }
ClassTypeInformation<?> targetType = ClassTypeInformation.from(documentsTargetType); TypeInformation<?> targetType = TypeInformation.of(documentsTargetType);
return (TypeInformation<? extends T>) basicType.specialize(targetType); return basicType.specialize(targetType);
} }
/** /**
@ -190,7 +189,7 @@ public class DefaultTypeMapper<S> implements TypeMapper<S>, BeanClassLoaderAware
@Override @Override
public void writeType(Class<?> type, S dbObject) { public void writeType(Class<?> type, S dbObject) {
writeType(ClassTypeInformation.from(type), dbObject); writeType(TypeInformation.of(type), dbObject);
} }
@Override @Override

7
src/main/java/org/springframework/data/convert/SimpleTypeInformationMapper.java

@ -21,7 +21,6 @@ import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.data.mapping.Alias; import org.springframework.data.mapping.Alias;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
@ -36,7 +35,7 @@ import org.springframework.util.ClassUtils;
*/ */
public class SimpleTypeInformationMapper implements TypeInformationMapper, BeanClassLoaderAware { public class SimpleTypeInformationMapper implements TypeInformationMapper, BeanClassLoaderAware {
private final Map<String, Optional<ClassTypeInformation<?>>> cache = new ConcurrentHashMap<>(); private final Map<String, Optional<TypeInformation<?>>> cache = new ConcurrentHashMap<>();
private @Nullable ClassLoader classLoader; private @Nullable ClassLoader classLoader;
@ -79,10 +78,10 @@ public class SimpleTypeInformationMapper implements TypeInformationMapper, BeanC
this.classLoader = classLoader; this.classLoader = classLoader;
} }
private Optional<ClassTypeInformation<?>> loadClass(String typeName) { private Optional<TypeInformation<?>> loadClass(String typeName) {
try { try {
return Optional.of(ClassTypeInformation.from(ClassUtils.forName(typeName, this.classLoader))); return Optional.of(TypeInformation.of(ClassUtils.forName(typeName, this.classLoader)));
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
return Optional.empty(); return Optional.empty();
} }

4
src/main/java/org/springframework/data/convert/ValueConversionContext.java

@ -69,7 +69,7 @@ public interface ValueConversionContext<P extends PersistentProperty<P>> {
*/ */
@Nullable @Nullable
default <T> T write(@Nullable Object value, @NonNull Class<T> target) { default <T> T write(@Nullable Object value, @NonNull Class<T> target) {
return write(value, ClassTypeInformation.from(target)); return write(value, TypeInformation.of(target));
} }
/** /**
@ -119,7 +119,7 @@ public interface ValueConversionContext<P extends PersistentProperty<P>> {
*/ */
@Nullable @Nullable
default <T> T read(@Nullable Object value, @NonNull Class<T> target) { default <T> T read(@Nullable Object value, @NonNull Class<T> target) {
return read(value, ClassTypeInformation.from(target)); return read(value, TypeInformation.of(target));
} }
/** /**

4
src/main/java/org/springframework/data/mapping/PropertyPath.java

@ -68,7 +68,7 @@ public class PropertyPath implements Streamable<PropertyPath> {
* @param owningType must not be {@literal null}. * @param owningType must not be {@literal null}.
*/ */
PropertyPath(String name, Class<?> owningType) { PropertyPath(String name, Class<?> owningType) {
this(name, ClassTypeInformation.from(owningType), Collections.emptyList()); this(name, TypeInformation.of(owningType), Collections.emptyList());
} }
/** /**
@ -315,7 +315,7 @@ public class PropertyPath implements Streamable<PropertyPath> {
* @return * @return
*/ */
public static PropertyPath from(String source, Class<?> type) { public static PropertyPath from(String source, Class<?> type) {
return from(source, ClassTypeInformation.from(type)); return from(source, TypeInformation.of(type));
} }
/** /**

14
src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java

@ -189,7 +189,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
@Nullable @Nullable
public E getPersistentEntity(Class<?> type) { public E getPersistentEntity(Class<?> type) {
return getPersistentEntity(ClassTypeInformation.from(type)); return getPersistentEntity(TypeInformation.of(type));
} }
@Override @Override
@ -197,7 +197,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
Assert.notNull(type, "Type must not be null"); Assert.notNull(type, "Type must not be null");
TypeInformation<?> typeInformation = ClassTypeInformation.from(type); TypeInformation<?> typeInformation = TypeInformation.of(type);
try { try {
@ -312,7 +312,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
*/ */
protected final <T> PersistentPropertyPaths<T, P> doFindPersistentPropertyPaths(Class<T> type, protected final <T> PersistentPropertyPaths<T, P> doFindPersistentPropertyPaths(Class<T> type,
Predicate<? super P> predicate, Predicate<P> traversalGuard) { Predicate<? super P> predicate, Predicate<P> traversalGuard) {
return persistentPropertyPathFactory.from(ClassTypeInformation.from(type), predicate, traversalGuard); return persistentPropertyPathFactory.from(TypeInformation.of(type), predicate, traversalGuard);
} }
/** /**
@ -322,7 +322,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
* @return * @return
*/ */
protected Optional<E> addPersistentEntity(Class<?> type) { protected Optional<E> addPersistentEntity(Class<?> type) {
return addPersistentEntity(ClassTypeInformation.from(type)); return addPersistentEntity(TypeInformation.of(type));
} }
/** /**
@ -728,7 +728,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
*/ */
public PropertyMatch(@Nullable String namePattern, @Nullable String typeName) { public PropertyMatch(@Nullable String namePattern, @Nullable String typeName) {
Assert.isTrue(!(namePattern == null && typeName == null), "Either name pattern or type name must be given"); Assert.isTrue(!((namePattern == null) && (typeName == null)), "Either name pattern or type name must be given");
this.namePattern = namePattern; this.namePattern = namePattern;
this.typeName = typeName; this.typeName = typeName;
@ -746,11 +746,11 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
Assert.notNull(name, "Name must not be null"); Assert.notNull(name, "Name must not be null");
Assert.notNull(type, "Type must not be null"); Assert.notNull(type, "Type must not be null");
if (namePattern != null && !name.matches(namePattern)) { if ((namePattern != null) && !name.matches(namePattern)) {
return false; return false;
} }
if (typeName != null && !type.getName().equals(typeName)) { if ((typeName != null) && !type.getName().equals(typeName)) {
return false; return false;
} }

6
src/main/java/org/springframework/data/mapping/context/PersistentPropertyPathFactory.java

@ -68,7 +68,7 @@ class PersistentPropertyPathFactory<E extends PersistentEntity<?, P>, P extends
Assert.notNull(type, "Type must not be null"); Assert.notNull(type, "Type must not be null");
Assert.notNull(propertyPath, "Property path must not be null"); Assert.notNull(propertyPath, "Property path must not be null");
return getPersistentPropertyPath(ClassTypeInformation.from(type), propertyPath); return getPersistentPropertyPath(TypeInformation.of(type), propertyPath);
} }
/** /**
@ -112,7 +112,7 @@ class PersistentPropertyPathFactory<E extends PersistentEntity<?, P>, P extends
Assert.notNull(type, "Type must not be null"); Assert.notNull(type, "Type must not be null");
Assert.notNull(propertyFilter, "Property filter must not be null"); Assert.notNull(propertyFilter, "Property filter must not be null");
return from(ClassTypeInformation.from(type), propertyFilter); return from(TypeInformation.of(type), propertyFilter);
} }
/** /**
@ -131,7 +131,7 @@ class PersistentPropertyPathFactory<E extends PersistentEntity<?, P>, P extends
Assert.notNull(propertyFilter, "Property filter must not be null"); Assert.notNull(propertyFilter, "Property filter must not be null");
Assert.notNull(traversalGuard, "Traversal guard must not be null"); Assert.notNull(traversalGuard, "Traversal guard must not be null");
return from(ClassTypeInformation.from(type), propertyFilter, traversalGuard); return from(TypeInformation.of(type), propertyFilter, traversalGuard);
} }
/** /**

2
src/main/java/org/springframework/data/mapping/model/AnnotationBasedPersistentProperty.java

@ -88,7 +88,7 @@ public abstract class AnnotationBasedPersistentProperty<P extends PersistentProp
return Optional.of(Reference.class) // return Optional.of(Reference.class) //
.map(this::findAnnotation) // .map(this::findAnnotation) //
.map(Reference::to) // .map(Reference::to) //
.map(it -> !Class.class.equals(it) ? ClassTypeInformation.from(it) : getActualTypeInformation()) // .map(it -> !Class.class.equals(it) ? TypeInformation.of(it) : getActualTypeInformation()) //
.orElseGet(() -> super.getAssociationTargetTypeInformation()); .orElseGet(() -> super.getAssociationTargetTypeInformation());
}); });

2
src/main/java/org/springframework/data/mapping/model/PreferredConstructorDiscoverer.java

@ -63,7 +63,7 @@ public interface PreferredConstructorDiscoverer<T, P extends PersistentProperty<
Assert.notNull(type, "Type must not be null"); Assert.notNull(type, "Type must not be null");
return Discoverers.findDiscoverer(type) // return Discoverers.findDiscoverer(type) //
.discover(ClassTypeInformation.from(type), null); .discover(TypeInformation.of(type), null);
} }
/** /**

6
src/main/java/org/springframework/data/projection/EntityProjection.java

@ -24,7 +24,6 @@ import java.util.Map;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.springframework.data.mapping.PropertyPath; import org.springframework.data.mapping.PropertyPath;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.Streamable; import org.springframework.data.util.Streamable;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
@ -37,6 +36,7 @@ import org.springframework.lang.Nullable;
* @param <D> the domain type. * @param <D> the domain type.
* @author Mark Paluch * @author Mark Paluch
* @author Christoph Strobl * @author Christoph Strobl
* @author Oliver Drotbohm
* @since 2.7 * @since 2.7
*/ */
public class EntityProjection<M, D> implements Streamable<EntityProjection.PropertyProjection<?, ?>> { public class EntityProjection<M, D> implements Streamable<EntityProjection.PropertyProjection<?, ?>> {
@ -90,7 +90,9 @@ public class EntityProjection<M, D> implements Streamable<EntityProjection.Prope
* @return new instance of {@link EntityProjection}. * @return new instance of {@link EntityProjection}.
*/ */
public static <T> EntityProjection<T, T> nonProjecting(Class<T> type) { public static <T> EntityProjection<T, T> nonProjecting(Class<T> type) {
ClassTypeInformation<T> typeInformation = ClassTypeInformation.from(type);
TypeInformation<T> typeInformation = TypeInformation.of(type);
return new EntityProjection<>(typeInformation, typeInformation, Collections.emptyList(), false, return new EntityProjection<>(typeInformation, typeInformation, Collections.emptyList(), false,
ProjectionType.CLOSED); ProjectionType.CLOSED);
} }

17
src/main/java/org/springframework/data/projection/EntityProjectionIntrospector.java

@ -25,9 +25,8 @@ import java.util.Set;
import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PropertyPath; import org.springframework.data.mapping.PropertyPath;
import org.springframework.data.projection.EntityProjection.ProjectionType;
import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.projection.EntityProjection.ProjectionType;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -39,6 +38,7 @@ import org.springframework.util.Assert;
* @author Gerrit Meier * @author Gerrit Meier
* @author Mark Paluch * @author Mark Paluch
* @author Christoph Strobl * @author Christoph Strobl
* @author Oliver Drotbohm
* @since 2.7 * @since 2.7
*/ */
public class EntityProjectionIntrospector { public class EntityProjectionIntrospector {
@ -91,8 +91,8 @@ public class EntityProjectionIntrospector {
*/ */
public <M, D> EntityProjection<M, D> introspect(Class<M> mappedType, Class<D> domainType) { public <M, D> EntityProjection<M, D> introspect(Class<M> mappedType, Class<D> domainType) {
ClassTypeInformation<M> returnedTypeInformation = ClassTypeInformation.from(mappedType); TypeInformation<M> returnedTypeInformation = TypeInformation.of(mappedType);
ClassTypeInformation<D> domainTypeInformation = ClassTypeInformation.from(domainType); TypeInformation<D> domainTypeInformation = TypeInformation.of(domainType);
boolean isProjection = projectionPredicate.test(mappedType, domainType); boolean isProjection = projectionPredicate.test(mappedType, domainType);
@ -111,7 +111,8 @@ public class EntityProjectionIntrospector {
List<EntityProjection.PropertyProjection<?, ?>> propertyDescriptors = getProperties(null, projectionInformation, List<EntityProjection.PropertyProjection<?, ?>> propertyDescriptors = getProperties(null, projectionInformation,
returnedTypeInformation, persistentEntity, null); returnedTypeInformation, persistentEntity, null);
return EntityProjection.projecting(returnedTypeInformation, domainTypeInformation, propertyDescriptors, ProjectionType.CLOSED); return EntityProjection.projecting(returnedTypeInformation, domainTypeInformation, propertyDescriptors,
ProjectionType.CLOSED);
} }
private List<EntityProjection.PropertyProjection<?, ?>> getProperties(@Nullable PropertyPath propertyPath, private List<EntityProjection.PropertyProjection<?, ?>> getProperties(@Nullable PropertyPath propertyPath,
@ -157,10 +158,12 @@ public class EntityProjectionIntrospector {
if (container) { if (container) {
propertyDescriptors.add(EntityProjection.ContainerPropertyProjection.projecting(nestedPropertyPath, property, propertyDescriptors.add(EntityProjection.ContainerPropertyProjection.projecting(nestedPropertyPath, property,
persistentProperty.getTypeInformation(), nestedPropertyDescriptors, ProjectionType.from(projectionInformation))); persistentProperty.getTypeInformation(), nestedPropertyDescriptors,
ProjectionType.from(projectionInformation)));
} else { } else {
propertyDescriptors.add(EntityProjection.PropertyProjection.projecting(nestedPropertyPath, property, propertyDescriptors.add(EntityProjection.PropertyProjection.projecting(nestedPropertyPath, property,
persistentProperty.getTypeInformation(), nestedPropertyDescriptors, ProjectionType.from(projectionInformation))); persistentProperty.getTypeInformation(), nestedPropertyDescriptors,
ProjectionType.from(projectionInformation)));
} }
} else { } else {

8
src/main/java/org/springframework/data/projection/ProjectingMethodInterceptor.java

@ -25,10 +25,8 @@ import java.util.Map.Entry;
import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; import org.aopalliance.intercept.MethodInvocation;
import org.springframework.core.CollectionFactory; import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.ConversionService;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.NullableWrapper; import org.springframework.data.util.NullableWrapper;
import org.springframework.data.util.NullableWrapperConverters; import org.springframework.data.util.NullableWrapperConverters;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
@ -66,7 +64,7 @@ class ProjectingMethodInterceptor implements MethodInterceptor {
@Override @Override
public Object invoke(@SuppressWarnings("null") @NonNull MethodInvocation invocation) throws Throwable { public Object invoke(@SuppressWarnings("null") @NonNull MethodInvocation invocation) throws Throwable {
TypeInformation<?> type = ClassTypeInformation.fromReturnTypeOf(invocation.getMethod()); TypeInformation<?> type = TypeInformation.fromReturnTypeOf(invocation.getMethod());
TypeInformation<?> resultType = type; TypeInformation<?> resultType = type;
TypeInformation<?> typeToReturn = type; TypeInformation<?> typeToReturn = type;
@ -74,7 +72,7 @@ class ProjectingMethodInterceptor implements MethodInterceptor {
boolean applyWrapper = false; boolean applyWrapper = false;
if (NullableWrapperConverters.supports(type.getType()) if (NullableWrapperConverters.supports(type.getType())
&& (result == null || !NullableWrapperConverters.supports(result.getClass()))) { && ((result == null) || !NullableWrapperConverters.supports(result.getClass()))) {
resultType = NullableWrapperConverters.unwrapActualType(typeToReturn); resultType = NullableWrapperConverters.unwrapActualType(typeToReturn);
applyWrapper = true; applyWrapper = true;
} }
@ -161,7 +159,7 @@ class ProjectingMethodInterceptor implements MethodInterceptor {
@Nullable @Nullable
private Object getProjection(@Nullable Object result, Class<?> returnType) { private Object getProjection(@Nullable Object result, Class<?> returnType) {
return result == null || ClassUtils.isAssignable(returnType, result.getClass()) ? result return (result == null) || ClassUtils.isAssignable(returnType, result.getClass()) ? result
: factory.createProjection(returnType, result); : factory.createProjection(returnType, result);
} }

7
src/main/java/org/springframework/data/querydsl/binding/QuerydslBindings.java

@ -25,7 +25,6 @@ import java.util.Set;
import org.springframework.data.mapping.PropertyPath; import org.springframework.data.mapping.PropertyPath;
import org.springframework.data.mapping.PropertyReferenceException; import org.springframework.data.mapping.PropertyReferenceException;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.Optionals; import org.springframework.data.util.Optionals;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
@ -175,7 +174,7 @@ public class QuerydslBindings {
Assert.notNull(path, "Path must not be null"); Assert.notNull(path, "Path must not be null");
Assert.notNull(type, "Type must not be null"); Assert.notNull(type, "Type must not be null");
return isPathAvailable(path, ClassTypeInformation.from(type)); return isPathAvailable(path, TypeInformation.of(type));
} }
/** /**
@ -573,7 +572,7 @@ public class QuerydslBindings {
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(@Nullable Object o) {
if (this == o) { if (this == o) {
return true; return true;
} }
@ -589,7 +588,7 @@ public class QuerydslBindings {
@Override @Override
public int hashCode() { public int hashCode() {
int result = ObjectUtils.nullSafeHashCode(path); int result = ObjectUtils.nullSafeHashCode(path);
result = 31 * result + ObjectUtils.nullSafeHashCode(binding); result = (31 * result) + ObjectUtils.nullSafeHashCode(binding);
return result; return result;
} }

3
src/main/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadata.java

@ -29,7 +29,6 @@ import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.util.QueryExecutionConverters; import org.springframework.data.repository.util.QueryExecutionConverters;
import org.springframework.data.repository.util.ReactiveWrapperConverters; import org.springframework.data.repository.util.ReactiveWrapperConverters;
import org.springframework.data.repository.util.ReactiveWrappers; import org.springframework.data.repository.util.ReactiveWrappers;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.KotlinReflectionUtils; import org.springframework.data.util.KotlinReflectionUtils;
import org.springframework.data.util.Lazy; import org.springframework.data.util.Lazy;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
@ -60,7 +59,7 @@ public abstract class AbstractRepositoryMetadata implements RepositoryMetadata {
Assert.isTrue(repositoryInterface.isInterface(), "Given type must be an interface"); Assert.isTrue(repositoryInterface.isInterface(), "Given type must be an interface");
this.repositoryInterface = repositoryInterface; this.repositoryInterface = repositoryInterface;
this.typeInformation = ClassTypeInformation.from(repositoryInterface); this.typeInformation = TypeInformation.of(repositoryInterface);
this.crudMethods = Lazy.of(() -> new DefaultCrudMethods(this)); this.crudMethods = Lazy.of(() -> new DefaultCrudMethods(this));
} }

3
src/main/java/org/springframework/data/repository/core/support/AnnotationRepositoryMetadata.java

@ -20,7 +20,6 @@ import java.util.function.Function;
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.repository.RepositoryDefinition; import org.springframework.data.repository.RepositoryDefinition;
import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -78,6 +77,6 @@ public class AnnotationRepositoryMetadata extends AbstractRepositoryMetadata {
throw new IllegalArgumentException(String.format("Could not resolve domain type of %s", repositoryInterface)); throw new IllegalArgumentException(String.format("Could not resolve domain type of %s", repositoryInterface));
} }
return ClassTypeInformation.from(extractor.apply(annotation)); return TypeInformation.of(extractor.apply(annotation));
} }
} }

3
src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadata.java

@ -20,7 +20,6 @@ import java.util.function.Supplier;
import org.springframework.data.repository.Repository; import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -50,7 +49,7 @@ public class DefaultRepositoryMetadata extends AbstractRepositoryMetadata {
super(repositoryInterface); super(repositoryInterface);
Assert.isTrue(Repository.class.isAssignableFrom(repositoryInterface), MUST_BE_A_REPOSITORY); Assert.isTrue(Repository.class.isAssignableFrom(repositoryInterface), MUST_BE_A_REPOSITORY);
List<TypeInformation<?>> arguments = ClassTypeInformation.from(repositoryInterface)// List<TypeInformation<?>> arguments = TypeInformation.of(repositoryInterface)//
.getRequiredSuperTypeInformation(Repository.class)// .getRequiredSuperTypeInformation(Repository.class)//
.getTypeArguments(); .getTypeArguments();

11
src/main/java/org/springframework/data/repository/core/support/MethodInvocationValidator.java

@ -21,7 +21,6 @@ import java.util.Map;
import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; import org.aopalliance.intercept.MethodInvocation;
import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.core.ParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer;
@ -85,7 +84,7 @@ public class MethodInvocationValidator implements MethodInterceptor {
continue; continue;
} }
if (arguments.length < i || arguments[i] == null) { if ((arguments.length < i) || (arguments[i] == null)) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
String.format("Parameter %s in %s.%s must not be null", nullability.getMethodParameterName(i), String.format("Parameter %s in %s.%s must not be null", nullability.getMethodParameterName(i),
ClassUtils.getShortName(method.getDeclaringClass()), method.getName())); ClassUtils.getShortName(method.getDeclaringClass()), method.getName()));
@ -94,7 +93,7 @@ public class MethodInvocationValidator implements MethodInterceptor {
Object result = invocation.proceed(); Object result = invocation.proceed();
if (result == null && !nullability.isNullableReturn()) { if ((result == null) && !nullability.isNullableReturn()) {
throw new EmptyResultDataAccessException("Result must not be null", 1); throw new EmptyResultDataAccessException("Result must not be null", 1);
} }
@ -170,7 +169,7 @@ public class MethodInvocationValidator implements MethodInterceptor {
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(@Nullable Object o) {
if (this == o) { if (this == o) {
return true; return true;
@ -194,8 +193,8 @@ public class MethodInvocationValidator implements MethodInterceptor {
@Override @Override
public int hashCode() { public int hashCode() {
int result = (nullableReturn ? 1 : 0); int result = (nullableReturn ? 1 : 0);
result = 31 * result + ObjectUtils.nullSafeHashCode(nullableParameters); result = (31 * result) + ObjectUtils.nullSafeHashCode(nullableParameters);
result = 31 * result + ObjectUtils.nullSafeHashCode(methodParameters); result = (31 * result) + ObjectUtils.nullSafeHashCode(methodParameters);
return result; return result;
} }

6
src/main/java/org/springframework/data/repository/core/support/MethodLookup.java

@ -21,6 +21,7 @@ import java.util.function.BiPredicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
@ -75,8 +76,7 @@ public interface MethodLookup {
/** /**
* Value object representing an invoked {@link Method}. * Value object representing an invoked {@link Method}.
*/ */
final final class InvokedMethod {
class InvokedMethod {
private final Method method; private final Method method;
@ -109,7 +109,7 @@ public interface MethodLookup {
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(@Nullable Object o) {
if (this == o) { if (this == o) {
return true; return true;

11
src/main/java/org/springframework/data/repository/core/support/MethodLookups.java

@ -37,6 +37,7 @@ import org.springframework.data.repository.core.support.MethodLookup.MethodPredi
import org.springframework.data.repository.util.QueryExecutionConverters; import org.springframework.data.repository.util.QueryExecutionConverters;
import org.springframework.data.repository.util.ReactiveWrapperConverters; import org.springframework.data.repository.util.ReactiveWrapperConverters;
import org.springframework.data.repository.util.ReactiveWrappers; import org.springframework.data.repository.util.ReactiveWrappers;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
@ -58,7 +59,7 @@ interface MethodLookups {
static MethodLookup direct() { static MethodLookup direct() {
MethodPredicate direct = (MethodPredicate) (invoked, candidate) -> candidate.getName().equals(invoked.getName()) MethodPredicate direct = (MethodPredicate) (invoked, candidate) -> candidate.getName().equals(invoked.getName())
&& candidate.getParameterCount() == invoked.getParameterCount() && (candidate.getParameterCount() == invoked.getParameterCount())
&& Arrays.equals(candidate.getParameterTypes(), invoked.getParameterTypes()); && Arrays.equals(candidate.getParameterTypes(), invoked.getParameterTypes());
return () -> Collections.singletonList(direct); return () -> Collections.singletonList(direct);
@ -248,8 +249,8 @@ interface MethodLookups {
MethodPredicate detailedComparison = (MethodPredicate) (invokedMethod, MethodPredicate detailedComparison = (MethodPredicate) (invokedMethod,
candidate) -> getMethodCandidate(invokedMethod, candidate) -> getMethodCandidate(invokedMethod,
candidate, candidate,
matchParameterOrComponentType(repositoryMetadata.getRepositoryInterface())).isPresent(); matchParameterOrComponentType(repositoryMetadata.getRepositoryInterface())).isPresent();
return Arrays.asList(convertibleComparison, detailedComparison); return Arrays.asList(convertibleComparison, detailedComparison);
} }
@ -434,7 +435,7 @@ interface MethodLookups {
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(@Nullable Object o) {
if (this == o) { if (this == o) {
return true; return true;
@ -454,7 +455,7 @@ interface MethodLookups {
@Override @Override
public int hashCode() { public int hashCode() {
int result = ObjectUtils.nullSafeHashCode(declared); int result = ObjectUtils.nullSafeHashCode(declared);
result = 31 * result + ObjectUtils.nullSafeHashCode(base); result = (31 * result) + ObjectUtils.nullSafeHashCode(base);
return result; return result;
} }

8
src/main/java/org/springframework/data/repository/core/support/RepositoryComposition.java

@ -81,7 +81,7 @@ public class RepositoryComposition {
Class<?> parameterType = parameterTypes.length > i ? parameterTypes[i] : null; Class<?> parameterType = parameterTypes.length > i ? parameterTypes[i] : null;
if (value != null && parameterType != null) { if ((value != null) && (parameterType != null)) {
if (!parameterType.isAssignableFrom(value.getClass()) if (!parameterType.isAssignableFrom(value.getClass())
&& ReactiveWrapperConverters.canConvert(value.getClass(), parameterType)) { && ReactiveWrapperConverters.canConvert(value.getClass(), parameterType)) {
@ -558,7 +558,7 @@ public class RepositoryComposition {
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(@Nullable Object o) {
if (this == o) { if (this == o) {
return true; return true;
@ -582,8 +582,8 @@ public class RepositoryComposition {
@Override @Override
public int hashCode() { public int hashCode() {
int result = ObjectUtils.nullSafeHashCode(fragmentCache); int result = ObjectUtils.nullSafeHashCode(fragmentCache);
result = 31 * result + ObjectUtils.nullSafeHashCode(invocationMetadataCache); result = (31 * result) + ObjectUtils.nullSafeHashCode(invocationMetadataCache);
result = 31 * result + ObjectUtils.nullSafeHashCode(fragments); result = (31 * result) + ObjectUtils.nullSafeHashCode(fragments);
return result; return result;
} }
} }

7
src/main/java/org/springframework/data/repository/query/Parameter.java

@ -17,7 +17,6 @@ package org.springframework.data.repository.query;
import static java.lang.String.*; import static java.lang.String.*;
import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@ -32,10 +31,8 @@ import org.springframework.data.domain.Sort;
import org.springframework.data.repository.util.ClassUtils; import org.springframework.data.repository.util.ClassUtils;
import org.springframework.data.repository.util.QueryExecutionConverters; import org.springframework.data.repository.util.QueryExecutionConverters;
import org.springframework.data.repository.util.ReactiveWrapperConverters; import org.springframework.data.repository.util.ReactiveWrapperConverters;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.Lazy; import org.springframework.data.util.Lazy;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.data.util.TypeDiscoverer;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
@ -218,7 +215,9 @@ public class Parameter {
} }
ResolvableType returnType = ResolvableType.forMethodReturnType(parameter.getMethod()); ResolvableType returnType = ResolvableType.forMethodReturnType(parameter.getMethod());
if(new TypeDiscoverer(returnType).isCollectionLike() || org.springframework.util.ClassUtils.isAssignable(Stream.class, returnType.toClass())) {
if (TypeInformation.of(returnType).isCollectionLike()
|| org.springframework.util.ClassUtils.isAssignable(Stream.class, returnType.toClass())) {
returnType = returnType.getGeneric(0); returnType = returnType.getGeneric(0);
} }

7
src/main/java/org/springframework/data/repository/query/QueryMethod.java

@ -30,7 +30,6 @@ import org.springframework.data.repository.core.EntityMetadata;
import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.util.QueryExecutionConverters; import org.springframework.data.repository.util.QueryExecutionConverters;
import org.springframework.data.repository.util.ReactiveWrapperConverters; import org.springframework.data.repository.util.ReactiveWrapperConverters;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.Lazy; import org.springframework.data.util.Lazy;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -108,7 +107,7 @@ public class QueryMethod {
Class<?> repositoryDomainClass = metadata.getDomainType(); Class<?> repositoryDomainClass = metadata.getDomainType();
Class<?> methodDomainClass = metadata.getReturnedDomainClass(method); Class<?> methodDomainClass = metadata.getReturnedDomainClass(method);
return repositoryDomainClass == null || repositoryDomainClass.isAssignableFrom(methodDomainClass) return (repositoryDomainClass == null) || repositoryDomainClass.isAssignableFrom(methodDomainClass)
? methodDomainClass ? methodDomainClass
: repositoryDomainClass; : repositoryDomainClass;
}); });
@ -271,7 +270,7 @@ public class QueryMethod {
return !QueryExecutionConverters.isSingleValue(unwrappedReturnType); return !QueryExecutionConverters.isSingleValue(unwrappedReturnType);
} }
return ClassTypeInformation.from(unwrappedReturnType).isCollectionLike(); return TypeInformation.of(unwrappedReturnType).isCollectionLike();
} }
private static Class<? extends Object> potentiallyUnwrapReturnTypeFor(RepositoryMetadata metadata, Method method) { private static Class<? extends Object> potentiallyUnwrapReturnTypeFor(RepositoryMetadata metadata, Method method) {
@ -301,7 +300,7 @@ public class QueryMethod {
Assert.notEmpty(types, "Types must not be null or empty"); Assert.notEmpty(types, "Types must not be null or empty");
// TODO: to resolve generics fully we'd need the actual repository interface here // TODO: to resolve generics fully we'd need the actual repository interface here
TypeInformation<?> returnType = ClassTypeInformation.fromReturnTypeOf(method); TypeInformation<?> returnType = TypeInformation.fromReturnTypeOf(method);
returnType = QueryExecutionConverters.isSingleValue(returnType.getType()) // returnType = QueryExecutionConverters.isSingleValue(returnType.getType()) //
? returnType.getRequiredComponentType() // ? returnType.getRequiredComponentType() //

17
src/main/java/org/springframework/data/repository/util/ClassUtils.java

@ -22,7 +22,6 @@ import java.util.Collection;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.springframework.data.repository.Repository; import org.springframework.data.repository.Repository;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.lang.NonNull; import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
@ -114,13 +113,13 @@ public abstract class ClassUtils {
} }
/** /**
* Returns the number of occurrences for the given {@link Method#getParameterTypes() parameter type} * Returns the number of occurrences for the given {@link Method#getParameterTypes() parameter type} in the given
* in the given {@link Method}. * {@link Method}.
* *
* @param method {@link Method} to evaluate. * @param method {@link Method} to evaluate.
* @param parameterType {@link Class} of the {@link Method} parameter type to count. * @param parameterType {@link Class} of the {@link Method} parameter type to count.
* @return the number of occurrences for the given {@link Method#getParameterTypes() parameter type} * @return the number of occurrences for the given {@link Method#getParameterTypes() parameter type} in the given
* in the given {@link Method}. * {@link Method}.
* @see java.lang.reflect.Method#getParameterTypes() * @see java.lang.reflect.Method#getParameterTypes()
*/ */
public static int getNumberOfOccurrences(@NonNull Method method, @NonNull Class<?> parameterType) { public static int getNumberOfOccurrences(@NonNull Method method, @NonNull Class<?> parameterType) {
@ -195,9 +194,11 @@ public abstract class ClassUtils {
// TODO: we should also consider having the owning type here so we can resolve generics better. // TODO: we should also consider having the owning type here so we can resolve generics better.
private static TypeInformation<?> getEffectivelyReturnedTypeFrom(Method method) { private static TypeInformation<?> getEffectivelyReturnedTypeFrom(Method method) {
TypeInformation<?> returnType = ClassTypeInformation.fromReturnTypeOf(method); TypeInformation<?> returnType = TypeInformation.fromReturnTypeOf(method);
return QueryExecutionConverters.supports(returnType.getType())
|| ReactiveWrapperConverters.supports(returnType.getType()) ? returnType.getRequiredComponentType() return QueryExecutionConverters.supports(returnType.getType()) //
|| ReactiveWrapperConverters.supports(returnType.getType()) //
? returnType.getRequiredComponentType() //
: returnType; : returnType;
} }
} }

104
src/main/java/org/springframework/data/util/ClassTypeInformation.java

@ -16,45 +16,85 @@
package org.springframework.data.util; package org.springframework.data.util;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.ResolvableType; import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ConcurrentLruCache;
import org.springframework.util.ConcurrentReferenceHashMap.ReferenceType;
/** /**
* {@link TypeInformation} for a plain {@link Class}. * {@link TypeInformation} for a plain {@link Class}.
* *
* @author Oliver Gierke * @author Oliver Gierke
* @author Christoph Strobl * @author Christoph Strobl
* @deprecated since 3.0 to go package protected at some point. Refer to {@link TypeInformation} only.
*/ */
@Deprecated
@SuppressWarnings({ "rawtypes", "unchecked" })
public class ClassTypeInformation<S> extends TypeDiscoverer<S> { public class ClassTypeInformation<S> extends TypeDiscoverer<S> {
public static final ClassTypeInformation<Collection> COLLECTION = new ClassTypeInformation(Collection.class); private static final ConcurrentLruCache<ResolvableType, ClassTypeInformation<?>> cache = new ConcurrentLruCache<>(64,
public static final ClassTypeInformation<List> LIST = new ClassTypeInformation(List.class); ClassTypeInformation::new);
public static final ClassTypeInformation<Set> SET = new ClassTypeInformation(Set.class);
public static final ClassTypeInformation<Map> MAP = new ClassTypeInformation(Map.class);
public static final ClassTypeInformation<Object> OBJECT = new ClassTypeInformation(Object.class);
private static final Map<Class<?>, ClassTypeInformation<?>> cache = new ConcurrentReferenceHashMap<>(64, @Deprecated public static final ClassTypeInformation<Collection> COLLECTION;
ReferenceType.WEAK); @Deprecated public static final ClassTypeInformation<List> LIST;
@Deprecated public static final ClassTypeInformation<Set> SET;
@Deprecated public static final ClassTypeInformation<Map> MAP;
@Deprecated public static final ClassTypeInformation<Object> OBJECT;
static {
OBJECT = (ClassTypeInformation<Object>) cache.get(ResolvableType.forClass(Object.class));
COLLECTION = (ClassTypeInformation<Collection>) cache.get(ResolvableType.forClass(Collection.class));
LIST = (ClassTypeInformation<List>) cache.get(ResolvableType.forClass(List.class));
SET = (ClassTypeInformation<Set>) cache.get(ResolvableType.forClass(Set.class));
MAP = (ClassTypeInformation<Map>) cache.get(ResolvableType.forClass(Map.class));
}
private final Class<S> type;
ClassTypeInformation(ResolvableType type) {
super(type);
this.type = (Class<S>) type.resolve(Object.class);
}
private ClassTypeInformation(Class<S> type) {
super(ResolvableType.forClass(type));
this.type = type;
}
/**
* @param <S>
* @param type
* @return
* @deprecated since 3.0. Use {@link TypeInformation#of} instead.
*/
@Deprecated
public static <S> ClassTypeInformation<S> from(Class<S> type) {
return cti(ResolvableType.forClass(type));
}
static <S> ClassTypeInformation<S> cti(ResolvableType type) {
Assert.notNull(type, "Type must not be null");
return (ClassTypeInformation<S>) cache.get(type);
}
/** /**
* Warning: Does not fully resolve generic arguments. * Warning: Does not fully resolve generic arguments.
*
* @param method * @param method
* @return * @return
* @deprecated since 3.0 Use {@link #fromReturnTypeOf(Method, Class)} instead. * @deprecated since 3.0. Use {@link TypeInformation#fromReturnTypeOf(Method)} instead.
*/ */
@Deprecated @Deprecated
public static TypeInformation<?> fromReturnTypeOf(Method method) { public static <S> TypeInformation<S> fromReturnTypeOf(Method method) {
return new TypeDiscoverer<>(ResolvableType.forMethodReturnType(method)); return (TypeInformation<S>) TypeInformation.of(ResolvableType.forMethodReturnType(method));
} }
/** /**
@ -62,35 +102,18 @@ public class ClassTypeInformation<S> extends TypeDiscoverer<S> {
* @param actualType can be {@literal null}. * @param actualType can be {@literal null}.
* @return * @return
*/ */
public static TypeInformation<?> fromReturnTypeOf(Method method, @Nullable Class<?> actualType) { static TypeInformation<?> fromReturnTypeOf(Method method, @Nullable Class<?> actualType) {
if(actualType == null) {
return new TypeDiscoverer<>(ResolvableType.forMethodReturnType(method));
}
return new TypeDiscoverer<>(ResolvableType.forMethodReturnType(method, actualType));
}
Class<?> type; var type = actualType == null
? ResolvableType.forMethodReturnType(method)
: ResolvableType.forMethodReturnType(method, actualType);
static { return TypeInformation.of(type);
Arrays.asList(COLLECTION, LIST, SET, MAP, OBJECT).forEach(it -> cache.put(it.getType(), it));
}
public static <S> ClassTypeInformation<S> from(Class<S> type) {
Assert.notNull(type, "Type must not be null");
return (ClassTypeInformation<S>) cache.computeIfAbsent(type, ClassTypeInformation::new);
}
ClassTypeInformation(Class<S> type) {
super(ResolvableType.forClass(type));
this.type = type;
} }
@Override @Override
public Class<S> getType() { public Class<S> getType() {
return (Class<S>) type; return type;
} }
@Override @Override
@ -104,7 +127,7 @@ public class ClassTypeInformation<S> extends TypeDiscoverer<S> {
} }
@Override @Override
public TypeInformation<? extends S> specialize(ClassTypeInformation<?> type) { public TypeInformation<? extends S> specialize(TypeInformation<?> type) {
return (TypeInformation<? extends S>) type; return (TypeInformation<? extends S>) type;
} }
@ -112,9 +135,4 @@ public class ClassTypeInformation<S> extends TypeDiscoverer<S> {
public String toString() { public String toString() {
return type.getName(); return type.getName();
} }
@Override
public boolean equals(Object o) {
return super.equals(o);
}
} }

386
src/main/java/org/springframework/data/util/TypeDiscoverer.java

@ -22,11 +22,9 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -37,6 +35,7 @@ import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ConcurrentLruCache;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
@ -49,55 +48,36 @@ import org.springframework.util.ReflectionUtils;
* @author Jürgen Diez * @author Jürgen Diez
* @author Alessandro Nistico * @author Alessandro Nistico
* @author Johannes Englmeier * @author Johannes Englmeier
* @deprecated since 3.0 to go package protected at some point. Prefer to refer to {@link TypeInformation} instead.
*/ */
public class TypeDiscoverer<S> implements TypeInformation<S> { @Deprecated
class TypeDiscoverer<S> implements TypeInformation<S> {
protected static final Class<?>[] MAP_TYPES; private static final ConcurrentLruCache<ResolvableType, TypeInformation<?>> CACHE = new ConcurrentLruCache<>(64,
private static final Class<?>[] COLLECTION_TYPES; TypeDiscoverer::new);
static {
var classLoader = TypeDiscoverer.class.getClassLoader();
Set<Class<?>> mapTypes = new HashSet<>();
mapTypes.add(Map.class);
try {
mapTypes.add(ClassUtils.forName("io.vavr.collection.Map", classLoader));
} catch (ClassNotFoundException o_O) {}
MAP_TYPES = mapTypes.toArray(new Class[0]);
Set<Class<?>> collectionTypes = new HashSet<>();
collectionTypes.add(Collection.class);
try {
collectionTypes.add(ClassUtils.forName("io.vavr.collection.Seq", classLoader));
} catch (ClassNotFoundException o_O) {}
try {
collectionTypes.add(ClassUtils.forName("io.vavr.collection.Set", classLoader));
} catch (ClassNotFoundException o_O) {}
COLLECTION_TYPES = collectionTypes.toArray(new Class[0]);
}
ResolvableType resolvableType;
private Map<String, Optional<TypeInformation<?>>> fields = new ConcurrentHashMap<>();
private final ResolvableType resolvableType;
private final Map<String, Optional<TypeInformation<?>>> fields = new ConcurrentHashMap<>();
private final Lazy<TypeInformation<?>> componentType; private final Lazy<TypeInformation<?>> componentType;
private final Lazy<TypeInformation<?>> valueType; private final Lazy<TypeInformation<?>> valueType;
private final Map<Constructor<?>, List<TypeInformation<?>>> constructorParameters = new ConcurrentHashMap<>();
private final Lazy<List<TypeInformation<?>>> typeArguments;
public TypeDiscoverer(Class<?> type) { protected TypeDiscoverer(ResolvableType type) {
this(ResolvableType.forClass(type));
}
public TypeDiscoverer(ResolvableType type) {
Assert.notNull(type, "Type must not be null"); Assert.notNull(type, "Type must not be null");
this.resolvableType = type; this.resolvableType = type;
this.componentType = Lazy.of(this::doGetComponentType); this.componentType = Lazy.of(this::doGetComponentType);
this.valueType = Lazy.of(this::doGetMapValueType); this.valueType = Lazy.of(this::doGetMapValueType);
this.typeArguments = Lazy.of(this::doGetTypeArguments);
}
static TypeDiscoverer<?> td(ResolvableType type) {
Assert.notNull(type, "Type must not be null");
return (TypeDiscoverer<?>) CACHE.get(type);
} }
@Override @Override
@ -105,16 +85,16 @@ public class TypeDiscoverer<S> implements TypeInformation<S> {
Assert.notNull(constructor, "Constructor must not be null"); Assert.notNull(constructor, "Constructor must not be null");
List<TypeInformation<?>> target = new ArrayList<>(); return constructorParameters.computeIfAbsent(constructor, it -> {
for (int i = 0; i < constructor.getParameterCount(); i++) {
target.add(new TypeDiscoverer<>(ResolvableType.forConstructorParameter(constructor, i)));
}
return target;
}
@Override List<TypeInformation<?>> target = new ArrayList<>();
public TypeDescriptor toTypeDescriptor() {
return new TypeDescriptor(resolvableType, null, null); for (int i = 0; i < it.getParameterCount(); i++) {
target.add(TypeInformation.of(ResolvableType.forConstructorParameter(it, i)));
}
return target;
});
} }
@Nullable @Nullable
@ -137,56 +117,11 @@ public class TypeDiscoverer<S> implements TypeInformation<S> {
return info.getProperty(name.substring(separatorIndex + 1)); return info.getProperty(name.substring(separatorIndex + 1));
} }
private Optional<TypeInformation<?>> getPropertyInformation(String fieldname) {
Class<?> rawType = resolvableType.toClass();
var field = ReflectionUtils.findField(rawType, fieldname);
if (field != null) {
return Optional.of(new TypeDiscoverer(ResolvableType.forField(field, resolvableType)));
}
return findPropertyDescriptor(rawType, fieldname).map(it -> {
if (it.getReadMethod() != null) {
return new TypeDiscoverer(ResolvableType.forMethodReturnType(it.getReadMethod(), rawType));
}
if (it.getWriteMethod() != null) {
return new TypeDiscoverer(ResolvableType.forMethodParameter(it.getWriteMethod(), 0, rawType));
}
return new TypeDiscoverer(ResolvableType.forType(it.getPropertyType(), resolvableType));
});
}
private Optional<PropertyDescriptor> findPropertyDescriptor(Class<?> type, String fieldname) {
PropertyDescriptor descriptor = BeanUtils.getPropertyDescriptor(type, fieldname);
if (descriptor != null) {
return Optional.of(descriptor);
}
List<Class<?>> superTypes = new ArrayList<>();
superTypes.addAll(Arrays.asList(type.getInterfaces()));
superTypes.add(type.getSuperclass());
return Streamable.of(type.getInterfaces()).stream()//
.flatMap(it -> Optionals.toStream(findPropertyDescriptor(it, fieldname)))//
.findFirst();
}
@Override @Override
public boolean isCollectionLike() { public boolean isCollectionLike() {
Class<S> type = getType(); Class<S> type = getType();
for (Class<?> collectionType : COLLECTION_TYPES) {
if (collectionType.isAssignableFrom(type)) {
return true;
}
}
return type.isArray() // return type.isArray() //
|| Iterable.class.equals(type) // || Iterable.class.equals(type) //
|| Collection.class.isAssignableFrom(type) // || Collection.class.isAssignableFrom(type) //
@ -203,66 +138,27 @@ public class TypeDiscoverer<S> implements TypeInformation<S> {
@Nullable @Nullable
protected TypeInformation<?> doGetComponentType() { protected TypeInformation<?> doGetComponentType() {
var rawType = getType(); if (resolvableType.isArray()) {
return TypeInformation.of(resolvableType.getComponentType());
if (rawType.isArray()) {
return new TypeDiscoverer<>(resolvableType.getComponentType());
} }
if (isMap()) { Class<S> rawType = getType();
if (ClassUtils.isAssignable(Map.class, rawType)) {
ResolvableType mapValueType = resolvableType.asMap().getGeneric(0);
if (ResolvableType.NONE.equals(mapValueType)) {
return null;
}
return mapValueType != null ? new TypeDiscoverer(mapValueType) : new ClassTypeInformation<>(Object.class); if (isMap()) {
} return getTypeArgument(CustomCollections.getMapBaseType(rawType), 0);
if (resolvableType.hasGenerics()) {
ResolvableType mapValueType = resolvableType.getGeneric(0);
return mapValueType != null ? new TypeDiscoverer(mapValueType) : new ClassTypeInformation<>(Object.class);
}
return Arrays.stream(resolvableType.getInterfaces()).filter(ResolvableType::hasGenerics)
.findFirst()
.map(it -> it.getGeneric(0))
.map(TypeDiscoverer::new)
.orElse(null);
} }
if (Iterable.class.isAssignableFrom(rawType)) { if (Iterable.class.isAssignableFrom(rawType)) {
return getTypeArgument(Iterable.class, 0);
ResolvableType iterableType = resolvableType.as(Iterable.class);
ResolvableType mapValueType = iterableType.getGeneric(0);
if (ResolvableType.NONE.equals(mapValueType)) {
return null;
}
if (resolvableType.hasGenerics()) {
mapValueType = resolvableType.getGeneric(0);
return mapValueType != null ? new TypeDiscoverer(mapValueType) : new ClassTypeInformation<>(Object.class);
}
return mapValueType.resolve() != null ? new TypeDiscoverer<>(mapValueType) : null;
} }
if (isNullableWrapper()) { if (isNullableWrapper()) {
ResolvableType mapValueType = resolvableType.getGeneric(0); return getTypeArgument(rawType, 0);
if (ResolvableType.NONE.equals(mapValueType)) {
return null;
}
return mapValueType != null ? new TypeDiscoverer(mapValueType) : new ClassTypeInformation<>(Object.class);
}
if (resolvableType.hasGenerics()) {
ResolvableType mapValueType = resolvableType.getGeneric(0);
return mapValueType != null ? new TypeDiscoverer(mapValueType) : new ClassTypeInformation<>(Object.class);
} }
return null; List<TypeInformation<?>> arguments = getTypeArguments();
}
private boolean isNullableWrapper() { return arguments.size() > 0 ? arguments.get(0) : null;
return NullableWrapperConverters.supports(getType());
} }
@Override @Override
@ -279,50 +175,31 @@ public class TypeDiscoverer<S> implements TypeInformation<S> {
@Nullable @Nullable
protected TypeInformation<?> doGetMapValueType() { protected TypeInformation<?> doGetMapValueType() {
if (isMap()) { return isMap() //
if (ClassUtils.isAssignable(Map.class, getType())) { ? getTypeArgument(CustomCollections.getMapBaseType(getType()), 1)
ResolvableType mapValueType = resolvableType.asMap().getGeneric(1); : getTypeArguments().stream().skip(1).findFirst().orElse(null);
if (ResolvableType.NONE.equals(mapValueType)) {
return null;
}
return mapValueType != null ? new TypeDiscoverer(mapValueType) : new ClassTypeInformation<>(Object.class);
}
if (resolvableType.hasGenerics()) {
ResolvableType mapValueType = resolvableType.getGeneric(1);
return mapValueType != null ? new TypeDiscoverer(mapValueType) : new ClassTypeInformation<>(Object.class);
}
return Arrays.stream(resolvableType.getInterfaces()).filter(ResolvableType::hasGenerics)
.findFirst()
.map(it -> it.getGeneric(1))
.map(TypeDiscoverer::new)
.orElse(null);
}
if (!resolvableType.hasGenerics()) {
return null;
}
ResolvableType x = Arrays.stream(resolvableType.getGenerics()).skip(1).findFirst().orElse(null);
if ((x == null) || ResolvableType.NONE.equals(x)) {
return null;
}
return new TypeDiscoverer<>(x);
} }
@Override @Override
@SuppressWarnings("unchecked")
public Class<S> getType() { public Class<S> getType() {
return (Class<S>) resolvableType.toClass(); return (Class<S>) resolvableType.toClass();
} }
@Override
public TypeDescriptor toTypeDescriptor() {
return new TypeDescriptor(resolvableType, getType(), null);
}
@Override @Override
public ClassTypeInformation<?> getRawTypeInformation() { public ClassTypeInformation<?> getRawTypeInformation() {
return new ClassTypeInformation<>(this.resolvableType.getRawClass()); return new ClassTypeInformation<>(ResolvableType.forRawClass(resolvableType.getRawClass()));
} }
@Nullable @Nullable
@Override @Override
public TypeInformation<?> getActualType() { public TypeInformation<?> getActualType() {
if (isMap()) { if (isMap()) {
return getMapValueType(); return getMapValueType();
} }
@ -331,8 +208,6 @@ public class TypeDiscoverer<S> implements TypeInformation<S> {
return getComponentType(); return getComponentType();
} }
// TODO: Consider that we will support value types beyond Optional<T>, such as Json<T>, Foo<T> that should remain
// configurable.
if (isNullableWrapper()) { if (isNullableWrapper()) {
return getComponentType(); return getComponentType();
} }
@ -342,10 +217,7 @@ public class TypeDiscoverer<S> implements TypeInformation<S> {
@Override @Override
public TypeInformation<?> getReturnType(Method method) { public TypeInformation<?> getReturnType(Method method) {
return TypeInformation.of(ResolvableType.forMethodReturnType(method, getType()));
Assert.notNull(method, "Method must not be null");
return new TypeDiscoverer(ResolvableType.forMethodReturnType(method, getType()));
} }
@Override @Override
@ -353,9 +225,11 @@ public class TypeDiscoverer<S> implements TypeInformation<S> {
Assert.notNull(method, "Method most not be null"); Assert.notNull(method, "Method most not be null");
return Streamable.of(method.getParameters()).stream().map(MethodParameter::forParameter) return Arrays.stream(method.getParameters()) //
.map(it -> ResolvableType.forMethodParameter(it, resolvableType)).map(TypeDiscoverer::new) .map(MethodParameter::forParameter) //
.collect(Collectors.toList()); .map(it -> ResolvableType.forMethodParameter(it, resolvableType)) //
.<TypeInformation<?>> map(TypeInformation::of) //
.toList();
} }
@ -373,46 +247,24 @@ public class TypeDiscoverer<S> implements TypeInformation<S> {
return this; return this;
} }
List<ResolvableType> candidates = new ArrayList<>(); var resolvableSuperType = resolvableType.as(superType);
var type = resolvableType.getType();
ResolvableType genericSuperclass = resolvableType.getSuperType(); if (!(type instanceof Class) || !ObjectUtils.isEmpty(((Class<?>) type).getTypeParameters())) {
if ((genericSuperclass != null) && !genericSuperclass.equals(ResolvableType.NONE)) { return TypeInformation.of(resolvableSuperType);
candidates.add(genericSuperclass);
} }
candidates.addAll(Arrays.asList(resolvableType.getInterfaces())); var noGenericsResolvable = !Arrays.stream(resolvableSuperType.resolveGenerics())
.filter(it -> it != null)
for (var candidate : candidates) { .findAny()
if (ObjectUtils.nullSafeEquals(superType, candidate.toClass())) { .isPresent();
if (resolvableType.getType() instanceof Class) {
if (ObjectUtils.isEmpty(((Class) resolvableType.getType()).getTypeParameters())) {
Class<?>[] classes = candidate.resolveGenerics(null);
if (!Arrays.stream(classes).filter(it -> it != null).findAny().isPresent()) {
return new TypeDiscoverer<>(ResolvableType.forRawClass(superType));
}
}
}
return new TypeDiscoverer(ResolvableType.forClass(superType, getType()));
} else {
var sup = candidate.getSuperType();
if ((sup != null) && !ResolvableType.NONE.equals(sup)) {
if (sup.equals(resolvableType)) {
return this;
}
return new TypeDiscoverer(sup);
}
}
}
return new TypeDiscoverer(resolvableType.as(superType)); return noGenericsResolvable
? new ClassTypeInformation<>(ResolvableType.forRawClass(superType))
: TypeInformation.of(resolvableSuperType);
} }
/* (non-Javadoc) @Override
* @see org.springframework.data.util.TypeInformation#isAssignableFrom(org.springframework.data.util.TypeInformation)
*/
public boolean isAssignableFrom(TypeInformation<?> target) { public boolean isAssignableFrom(TypeInformation<?> target) {
TypeInformation<?> superTypeInformation = target.getSuperTypeInformation(getType()); TypeInformation<?> superTypeInformation = target.getSuperTypeInformation(getType());
@ -420,6 +272,7 @@ public class TypeDiscoverer<S> implements TypeInformation<S> {
if (superTypeInformation == null) { if (superTypeInformation == null) {
return false; return false;
} }
if (superTypeInformation.equals(this)) { if (superTypeInformation.equals(this)) {
return true; return true;
} }
@ -433,62 +286,58 @@ public class TypeDiscoverer<S> implements TypeInformation<S> {
@Override @Override
public List<TypeInformation<?>> getTypeArguments() { public List<TypeInformation<?>> getTypeArguments() {
return typeArguments.get();
}
private List<TypeInformation<?>> doGetTypeArguments() {
if (!resolvableType.hasGenerics()) { if (!resolvableType.hasGenerics()) {
return Collections.emptyList(); return Collections.emptyList();
} }
return Arrays.stream(resolvableType.getGenerics()).map(it -> { return Arrays.stream(resolvableType.getGenerics())
if ((it == null) || ResolvableType.NONE.equals(it)) { .<TypeInformation<?>> map(it -> it.resolve(Object.class) == null ? null : TypeInformation.of(it))
return null; .toList();
}
return new TypeDiscoverer<>(it);
}).collect(Collectors.toList());
} }
@Override @Override
public TypeInformation<? extends S> specialize(ClassTypeInformation<?> type) { @SuppressWarnings("unchecked")
// if(isAssignableFrom(type)) { public TypeInformation<? extends S> specialize(TypeInformation<?> type) {
// return new ClassTypeInformation(type.getType());
// } if (this.getTypeArguments().size() == type.getTypeArguments().size()) {
// return new NewTypeDiscoverer(type.resolvableType.as(getType())); return (TypeInformation<? extends S>) TypeInformation.of(
// if(type.resolvableType.isAssignableFrom(type.resolvableType)) {
// return (TypeInformation<? extends S>) type;
// }
if (this.resolvableType.getGenerics().length == type.resolvableType.getGenerics().length) {
return new TypeDiscoverer<>(
ResolvableType.forClassWithGenerics(type.getType(), this.resolvableType.getGenerics())); ResolvableType.forClassWithGenerics(type.getType(), this.resolvableType.getGenerics()));
} }
return new ClassTypeInformation(type.getType()); return TypeInformation.of((Class<S>) type.getType());
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(@Nullable Object o) {
if (this == o) { if (this == o) {
return true; return true;
} }
if ((o == null) || !ClassUtils.isAssignable(getClass(), o.getClass())) { if ((o == null) || !ClassUtils.isAssignable(getClass(), o.getClass())) {
return false; return false;
} }
TypeDiscoverer<?> that = (TypeDiscoverer<?>) o; var that = (TypeDiscoverer<?>) o;
if (!ObjectUtils.nullSafeEquals(getType(), that.getType())) { if (!ObjectUtils.nullSafeEquals(getType(), that.getType())) {
return false; return false;
} }
List<? extends Class<?>> collect1 = Arrays.stream(resolvableType.getGenerics()).map(ResolvableType::toClass) var collect1 = Arrays.stream(resolvableType.getGenerics()) //
.map(ResolvableType::toClass) //
.collect(Collectors.toList()); .collect(Collectors.toList());
List<? extends Class<?>> collect2 = Arrays.stream(that.resolvableType.getGenerics()).map(ResolvableType::toClass)
var collect2 = Arrays.stream(that.resolvableType.getGenerics()) //
.map(ResolvableType::toClass) //
.collect(Collectors.toList()); .collect(Collectors.toList());
if (!ObjectUtils.nullSafeEquals(collect1, collect2)) { return ObjectUtils.nullSafeEquals(collect1, collect2);
return false;
}
return true;
} }
@Override @Override
@ -498,6 +347,57 @@ public class TypeDiscoverer<S> implements TypeInformation<S> {
@Override @Override
public String toString() { public String toString() {
return getType().getName(); return resolvableType.toString();
}
@Nullable
private TypeInformation<?> getTypeArgument(Class<?> bound, int index) {
var superTypeInformation = getSuperTypeInformation(bound);
if (superTypeInformation == null) {
return null;
}
var arguments = superTypeInformation.getTypeArguments();
if (arguments.isEmpty() || (index > (arguments.size() - 1))) {
return null;
}
return arguments.get(index);
}
private Optional<TypeInformation<?>> getPropertyInformation(String fieldname) {
var rawType = getType();
var field = ReflectionUtils.findField(rawType, fieldname);
return field != null
? Optional.of(TypeInformation.of(ResolvableType.forField(field, resolvableType)))
: Optional.ofNullable(BeanUtils.getPropertyDescriptor(rawType, fieldname))
.map(it -> from(it, rawType))
.map(TypeInformation::of);
}
private ResolvableType from(PropertyDescriptor descriptor, Class<?> rawType) {
var method = descriptor.getReadMethod();
if (method != null) {
return ResolvableType.forMethodReturnType(method, rawType);
}
method = descriptor.getWriteMethod();
if (method != null) {
return ResolvableType.forMethodParameter(method, 0, rawType);
}
return ResolvableType.forType(descriptor.getPropertyType(), resolvableType);
}
private boolean isNullableWrapper() {
return NullableWrapperConverters.supports(getType());
} }
} }

94
src/main/java/org/springframework/data/util/TypeInformation.java

@ -17,10 +17,15 @@ package org.springframework.data.util;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.core.ResolvableType;
import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/** /**
* Interface to access property types and resolving generics on the way. Starting with a {@link ClassTypeInformation} * Interface to access property types and resolving generics on the way. Starting with a {@link ClassTypeInformation}
@ -30,9 +35,77 @@ import org.springframework.lang.Nullable;
* @author Mark Paluch * @author Mark Paluch
* @author Alessandro Nistico * @author Alessandro Nistico
* @author Johannes Englmeier * @author Johannes Englmeier
* @author Christoph Strobl
*/ */
@SuppressWarnings({ "deprecation", "rawtypes" })
public interface TypeInformation<S> { public interface TypeInformation<S> {
public static final TypeInformation<Collection> COLLECTION = ClassTypeInformation.COLLECTION;
public static final TypeInformation<List> LIST = ClassTypeInformation.LIST;
public static final TypeInformation<Set> SET = ClassTypeInformation.SET;
public static final TypeInformation<Map> MAP = ClassTypeInformation.MAP;
public static final TypeInformation<Object> OBJECT = ClassTypeInformation.OBJECT;
static TypeInformation<?> orObject(@Nullable ResolvableType type) {
return type == null ? ClassTypeInformation.OBJECT : of(type);
}
/**
* Creates a new {@link TypeInformation} from the given {@link ResolvableType}.
*
* @param type must not be {@literal null}.
* @return will never be {@literal null}.
* @since 3.0
*/
public static TypeInformation<?> of(ResolvableType type) {
Assert.notNull(type, "Type must not be null");
return type.hasGenerics() || (type.isArray() && type.getComponentType().hasGenerics()) //
? TypeDiscoverer.td(type)
: ClassTypeInformation.cti(type);
}
/**
* Creates a new {@link TypeInformation} for the given {@link Class}.
*
* @param type must not be {@literal null}.
* @return will never be {@literal null}.
* @since 3.0
*/
public static <S> TypeInformation<S> of(Class<S> type) {
Assert.notNull(type, "Type must not be null");
return ClassTypeInformation.from(type);
}
/**
* Returns a {@link TypeInformation} for the given {@link Method}.
*
* @param method must not be {@literal null}.
* @return will never be {@literal null}.
* @since 3.0
*/
public static TypeInformation<?> fromReturnTypeOf(Method method) {
Assert.notNull(method, "Method must not be null");
return fromReturnTypeOf(method, null);
}
/**
* Returns a {@link TypeInformation} for the given method as declared on the given type.
*
* @param method must not be {@literal null}.
* @param type can be {@literal null}.
* @return will never be {@literal null}.
* @since 3.0
*/
public static TypeInformation<?> fromReturnTypeOf(Method method, @Nullable Class<?> type) {
return ClassTypeInformation.fromReturnTypeOf(method, type);
}
/** /**
* Returns the {@link TypeInformation}s for the parameters of the given {@link Constructor}. * Returns the {@link TypeInformation}s for the parameters of the given {@link Constructor}.
* *
@ -162,7 +235,7 @@ public interface TypeInformation<S> {
default TypeInformation<?> getUserTypeInformation() { default TypeInformation<?> getUserTypeInformation() {
Class<?> userType = ProxyUtils.getUserClass(getType()); Class<?> userType = ProxyUtils.getUserClass(getType());
return userType.equals(getType()) ? this : ClassTypeInformation.from(userType); return userType.equals(getType()) ? this : TypeInformation.of(userType);
} }
/** /**
@ -276,12 +349,27 @@ public interface TypeInformation<S> {
* *
* @param type must not be {@literal null}. * @param type must not be {@literal null}.
* @return will never be {@literal null}. * @return will never be {@literal null}.
* @deprecated since 3.0. Use {@link #specialize(TypeInformation)} instead, i.e. switch the given parameter's type to
* {@link TypeInformation} in the first place.
*/ */
TypeInformation<? extends S> specialize(ClassTypeInformation<?> type); @Deprecated
default TypeInformation<? extends S> specialize(ClassTypeInformation<?> type) {
return specialize((TypeInformation<?>) type);
}
/**
* Specializes the given (raw) {@link TypeInformation} using the context of the current potentially parameterized
* type, basically turning the given raw type into a parameterized one. Will return the given type as is if no
* generics are involved.
*
* @param type must not be {@literal null}.
* @return will never be {@literal null}.
*/
@SuppressWarnings("unchecked")
default TypeInformation<? extends S> specialize(TypeInformation<?> type) { default TypeInformation<? extends S> specialize(TypeInformation<?> type) {
return specialize(ClassTypeInformation.from(type.getType())); return (TypeInformation<? extends S>) type;
} }
/** /**
* Returns whether the current type is a sub type of the given one, i.e. whether it's assignable but not the same one. * Returns whether the current type is a sub type of the given one, i.e. whether it's assignable but not the same one.
* *

4
src/main/java/org/springframework/data/web/JsonProjectingMethodInterceptorFactory.java

@ -29,12 +29,10 @@ import java.util.Map;
import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; import org.aopalliance.intercept.MethodInvocation;
import org.springframework.core.ResolvableType; import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.projection.Accessor; import org.springframework.data.projection.Accessor;
import org.springframework.data.projection.MethodInterceptorFactory; import org.springframework.data.projection.MethodInterceptorFactory;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -146,7 +144,7 @@ public class JsonProjectingMethodInterceptorFactory implements MethodInterceptor
public Object invoke(MethodInvocation invocation) throws Throwable { public Object invoke(MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod(); Method method = invocation.getMethod();
TypeInformation<?> returnType = ClassTypeInformation.fromReturnTypeOf(method); TypeInformation<?> returnType = TypeInformation.fromReturnTypeOf(method);
ResolvableType type = ResolvableType.forMethodReturnType(method); ResolvableType type = ResolvableType.forMethodReturnType(method);
boolean isCollectionResult = Collection.class.isAssignableFrom(type.getRawClass()); boolean isCollectionResult = Collection.class.isAssignableFrom(type.getRawClass());
type = isCollectionResult ? type : ResolvableType.forClassWithGenerics(List.class, type); type = isCollectionResult ? type : ResolvableType.forClassWithGenerics(List.class, type);

5
src/main/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolverSupport.java

@ -29,7 +29,6 @@ import org.springframework.data.querydsl.binding.QuerydslBindingsFactory;
import org.springframework.data.querydsl.binding.QuerydslPredicate; import org.springframework.data.querydsl.binding.QuerydslPredicate;
import org.springframework.data.querydsl.binding.QuerydslPredicateBuilder; import org.springframework.data.querydsl.binding.QuerydslPredicateBuilder;
import org.springframework.data.util.CastUtils; import org.springframework.data.util.CastUtils;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -135,7 +134,7 @@ public abstract class QuerydslPredicateArgumentResolverSupport {
Optional<QuerydslPredicate> annotation = predicateAnnotation.synthesize(MergedAnnotation::isPresent); Optional<QuerydslPredicate> annotation = predicateAnnotation.synthesize(MergedAnnotation::isPresent);
return annotation.filter(it -> !Object.class.equals(it.root()))// return annotation.filter(it -> !Object.class.equals(it.root()))//
.<TypeInformation<?>> map(it -> ClassTypeInformation.from(it.root()))// .<TypeInformation<?>> map(it -> TypeInformation.of(it.root()))//
.orElseGet(() -> detectDomainType(parameter)); .orElseGet(() -> detectDomainType(parameter));
} }
@ -147,7 +146,7 @@ public abstract class QuerydslPredicateArgumentResolverSupport {
throw new IllegalArgumentException("Method parameter is not backed by a method"); throw new IllegalArgumentException("Method parameter is not backed by a method");
} }
return detectDomainType(ClassTypeInformation.fromReturnTypeOf(method)); return detectDomainType(TypeInformation.fromReturnTypeOf(method));
} }
private static TypeInformation<?> detectDomainType(TypeInformation<?> source) { private static TypeInformation<?> detectDomainType(TypeInformation<?> source) {

9
src/test/java/org/springframework/data/convert/ConfigurableTypeInformationMapperUnitTests.java

@ -25,10 +25,9 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.mapping.Alias; import org.springframework.data.mapping.Alias;
import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation;
/** /**
* Unit tests for {@link ConfigurableTypeInformationMapper}. * Unit tests for {@link ConfigurableTypeInformationMapper}.
@ -64,14 +63,14 @@ class ConfigurableTypeInformationMapperUnitTests<T extends PersistentProperty<T>
@Test @Test
void writesMapKeyForType() { void writesMapKeyForType() {
assertThat(mapper.createAliasFor(ClassTypeInformation.from(String.class))).isEqualTo(Alias.of("1")); assertThat(mapper.createAliasFor(TypeInformation.of(String.class))).isEqualTo(Alias.of("1"));
assertThat(mapper.createAliasFor(ClassTypeInformation.from(Object.class))).isEqualTo(Alias.NONE); assertThat(mapper.createAliasFor(TypeInformation.of(Object.class))).isEqualTo(Alias.NONE);
} }
@Test @Test
void readsTypeForMapKey() { void readsTypeForMapKey() {
assertThat(mapper.resolveTypeFrom(Alias.of("1"))).isEqualTo(ClassTypeInformation.from(String.class)); assertThat(mapper.resolveTypeFrom(Alias.of("1"))).isEqualTo(TypeInformation.of(String.class));
assertThat(mapper.resolveTypeFrom(Alias.of("unmapped"))).isNull(); assertThat(mapper.resolveTypeFrom(Alias.of("unmapped"))).isNull();
} }
} }

6
src/test/java/org/springframework/data/convert/DefaultTypeMapperUnitTests.java

@ -46,7 +46,7 @@ import org.springframework.data.util.TypeInformation;
@MockitoSettings(strictness = Strictness.LENIENT) @MockitoSettings(strictness = Strictness.LENIENT)
class DefaultTypeMapperUnitTests { class DefaultTypeMapperUnitTests {
static final TypeInformation<String> STRING_TYPE_INFO = ClassTypeInformation.from(String.class); static final TypeInformation<String> STRING_TYPE_INFO = TypeInformation.of(String.class);
static final Alias ALIAS = Alias.of(String.class.getName()); static final Alias ALIAS = Alias.of(String.class.getName());
@Mock TypeAliasAccessor<Map<String, String>> accessor; @Mock TypeAliasAccessor<Map<String, String>> accessor;
@ -88,9 +88,9 @@ class DefaultTypeMapperUnitTests {
@Test // DATACMNS-783 @Test // DATACMNS-783
void specializesRawSourceTypeUsingGenericContext() { void specializesRawSourceTypeUsingGenericContext() {
var root = ClassTypeInformation.from(Foo.class); var root = TypeInformation.of(Foo.class);
var propertyType = root.getProperty("abstractBar"); var propertyType = root.getProperty("abstractBar");
TypeInformation<?> barType = ClassTypeInformation.from(Bar.class); TypeInformation<?> barType = TypeInformation.of(Bar.class);
doReturn(Alias.of(barType)).when(accessor).readAliasFrom(source); doReturn(Alias.of(barType)).when(accessor).readAliasFrom(source);
doReturn(barType).when(mapper).resolveTypeFrom(Alias.of(barType)); doReturn(barType).when(mapper).resolveTypeFrom(Alias.of(barType));

11
src/test/java/org/springframework/data/convert/MappingContextTypeInformationMapperUnitTests.java

@ -16,7 +16,6 @@
package org.springframework.data.convert; package org.springframework.data.convert;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.util.ClassTypeInformation.from;
import java.util.Collections; import java.util.Collections;
@ -28,7 +27,7 @@ import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.context.SampleMappingContext; import org.springframework.data.mapping.context.SampleMappingContext;
import org.springframework.data.mapping.context.SamplePersistentProperty; import org.springframework.data.mapping.context.SamplePersistentProperty;
import org.springframework.data.util.AnnotatedTypeScanner; import org.springframework.data.util.AnnotatedTypeScanner;
import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation;
/** /**
* Unit tests for {@link MappingContextTypeInformationMapper}. * Unit tests for {@link MappingContextTypeInformationMapper}.
@ -58,7 +57,7 @@ class MappingContextTypeInformationMapperUnitTests {
mapper = new MappingContextTypeInformationMapper(mappingContext); mapper = new MappingContextTypeInformationMapper(mappingContext);
assertThat(mapper.createAliasFor(ClassTypeInformation.from(Entity.class)).hasValue("foo")).isTrue(); assertThat(mapper.createAliasFor(TypeInformation.of(Entity.class)).hasValue("foo")).isTrue();
} }
@Test @Test
@ -69,7 +68,7 @@ class MappingContextTypeInformationMapperUnitTests {
mapper = new MappingContextTypeInformationMapper(mappingContext); mapper = new MappingContextTypeInformationMapper(mappingContext);
assertThat(mapper.createAliasFor(from(Entity.class)).hasValue("foo")).isTrue(); assertThat(mapper.createAliasFor(TypeInformation.of(Entity.class)).hasValue("foo")).isTrue();
} }
@Test @Test
@ -79,7 +78,7 @@ class MappingContextTypeInformationMapperUnitTests {
mappingContext.initialize(); mappingContext.initialize();
mapper = new MappingContextTypeInformationMapper(mappingContext); mapper = new MappingContextTypeInformationMapper(mappingContext);
assertThat(mapper.createAliasFor(from(String.class)).isPresent()).isFalse(); assertThat(mapper.createAliasFor(TypeInformation.of(String.class)).isPresent()).isFalse();
} }
@Test @Test
@ -94,7 +93,7 @@ class MappingContextTypeInformationMapperUnitTests {
PersistentEntity<?, SamplePersistentProperty> entity = mappingContext.getRequiredPersistentEntity(Entity.class); PersistentEntity<?, SamplePersistentProperty> entity = mappingContext.getRequiredPersistentEntity(Entity.class);
assertThat(entity).isNotNull(); assertThat(entity).isNotNull();
assertThat(mapper.resolveTypeFrom(Alias.of("foo"))).isEqualTo(from(Entity.class)); assertThat(mapper.resolveTypeFrom(Alias.of("foo"))).isEqualTo(TypeInformation.of(Entity.class));
} }
@Test // DATACMNS-485 @Test // DATACMNS-485

4
src/test/java/org/springframework/data/convert/SimpleTypeInformationMapperUnitTests.java

@ -39,7 +39,7 @@ class SimpleTypeInformationMapperUnitTests {
var type = mapper.resolveTypeFrom(Alias.of("java.lang.String")); var type = mapper.resolveTypeFrom(Alias.of("java.lang.String"));
TypeInformation<?> expected = ClassTypeInformation.from(String.class); TypeInformation<?> expected = TypeInformation.of(String.class);
assertThat(type).isEqualTo(expected); assertThat(type).isEqualTo(expected);
} }
@ -73,7 +73,7 @@ class SimpleTypeInformationMapperUnitTests {
@Test @Test
void usesFullyQualifiedClassNameAsTypeKey() { void usesFullyQualifiedClassNameAsTypeKey() {
assertThat(mapper.createAliasFor(ClassTypeInformation.from(String.class))) assertThat(mapper.createAliasFor(TypeInformation.of(String.class)))
.isEqualTo(Alias.of(String.class.getName())); .isEqualTo(Alias.of(String.class.getName()));
} }

6
src/test/java/org/springframework/data/mapping/ParameterUnitTests.java

@ -23,8 +23,6 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
/** /**
@ -38,7 +36,7 @@ class ParameterUnitTests<P extends PersistentProperty<P>> {
@Mock PersistentEntity<Object, P> entity; @Mock PersistentEntity<Object, P> entity;
@Mock PersistentEntity<String, P> stringEntity; @Mock PersistentEntity<String, P> stringEntity;
private TypeInformation<Object> type = ClassTypeInformation.from(Object.class); private TypeInformation<Object> type = TypeInformation.of(Object.class);
private Annotation[] annotations = new Annotation[0]; private Annotation[] annotations = new Annotation[0];
@Test @Test
@ -84,7 +82,7 @@ class ParameterUnitTests<P extends PersistentProperty<P>> {
void twoParametersWithDifferenTypeAreNotEqual() { void twoParametersWithDifferenTypeAreNotEqual() {
var left = new Parameter<Object, P>("name", type, annotations, entity); var left = new Parameter<Object, P>("name", type, annotations, entity);
var right = new Parameter<String, P>("name", ClassTypeInformation.from(String.class), annotations, var right = new Parameter<String, P>("name", TypeInformation.of(String.class), annotations,
stringEntity); stringEntity);
assertThat(left).isNotEqualTo(right); assertThat(left).isNotEqualTo(right);

11
src/test/java/org/springframework/data/mapping/PreferredConstructorDiscovererUnitTests.java

@ -24,13 +24,12 @@ import java.lang.annotation.Target;
import java.util.Iterator; import java.util.Iterator;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.annotation.PersistenceConstructor; import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.mapping.PreferredConstructorDiscovererUnitTests.Outer.Inner; import org.springframework.data.mapping.PreferredConstructorDiscovererUnitTests.Outer.Inner;
import org.springframework.data.mapping.model.BasicPersistentEntity; import org.springframework.data.mapping.model.BasicPersistentEntity;
import org.springframework.data.mapping.model.PreferredConstructorDiscoverer; import org.springframework.data.mapping.model.PreferredConstructorDiscoverer;
import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation;
/** /**
* Unit tests for {@link PreferredConstructorDiscoverer}. * Unit tests for {@link PreferredConstructorDiscoverer}.
@ -94,7 +93,7 @@ class PreferredConstructorDiscovererUnitTests<P extends PersistentProperty<P>> {
@Test // DATACMNS-134, DATACMNS-1126 @Test // DATACMNS-134, DATACMNS-1126
void discoversInnerClassConstructorCorrectly() { void discoversInnerClassConstructorCorrectly() {
PersistentEntity<Inner, P> entity = new BasicPersistentEntity<>(ClassTypeInformation.from(Inner.class)); PersistentEntity<Inner, P> entity = new BasicPersistentEntity<>(TypeInformation.of(Inner.class));
assertThat(PreferredConstructorDiscoverer.discover(entity)).satisfies(constructor -> { assertThat(PreferredConstructorDiscoverer.discover(entity)).satisfies(constructor -> {
@ -107,7 +106,7 @@ class PreferredConstructorDiscovererUnitTests<P extends PersistentProperty<P>> {
void skipsSyntheticConstructor() { void skipsSyntheticConstructor() {
PersistentEntity<SyntheticConstructor, P> entity = new BasicPersistentEntity<>( PersistentEntity<SyntheticConstructor, P> entity = new BasicPersistentEntity<>(
ClassTypeInformation.from(SyntheticConstructor.class)); TypeInformation.of(SyntheticConstructor.class));
assertThat(PreferredConstructorDiscoverer.discover(entity)).satisfies(constructor -> { assertThat(PreferredConstructorDiscoverer.discover(entity)).satisfies(constructor -> {
@ -222,11 +221,11 @@ class PreferredConstructorDiscovererUnitTests<P extends PersistentProperty<P>> {
static class ClassWithMetaAnnotatedParameter { static class ClassWithMetaAnnotatedParameter {
ClassWithMetaAnnotatedParameter(@MyValue String value) { } ClassWithMetaAnnotatedParameter(@MyValue String value) {}
} }
@Target(ElementType.PARAMETER) @Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Value("${hello-world}") @Value("${hello-world}")
@interface MyValue { } @interface MyValue {}
} }

4
src/test/java/org/springframework/data/mapping/PropertyPathUnitTests.java

@ -23,8 +23,6 @@ import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
/** /**
@ -44,7 +42,7 @@ class PropertyPathUnitTests {
assertThat(reference.hasNext()).isFalse(); assertThat(reference.hasNext()).isFalse();
assertThat(reference.toDotPath()).isEqualTo("userName"); assertThat(reference.toDotPath()).isEqualTo("userName");
assertThat(reference.getOwningType()).isEqualTo(ClassTypeInformation.from(Foo.class)); assertThat(reference.getOwningType()).isEqualTo(TypeInformation.of(Foo.class));
} }
@Test @Test

4
src/test/java/org/springframework/data/mapping/PropertyReferenceExceptionUnitTests.java

@ -21,8 +21,6 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
/** /**
@ -33,7 +31,7 @@ import org.springframework.data.util.TypeInformation;
*/ */
public class PropertyReferenceExceptionUnitTests { public class PropertyReferenceExceptionUnitTests {
static final TypeInformation<Sample> TYPE_INFO = ClassTypeInformation.from(Sample.class); static final TypeInformation<Sample> TYPE_INFO = TypeInformation.of(Sample.class);
static final List<PropertyPath> NO_PATHS = Collections.emptyList(); static final List<PropertyPath> NO_PATHS = Collections.emptyList();
@Test @Test

3
src/test/java/org/springframework/data/mapping/context/AbstractMappingContextIntegrationTests.java

@ -28,7 +28,6 @@ import org.springframework.data.mapping.PropertyHandler;
import org.springframework.data.mapping.model.BasicPersistentEntity; import org.springframework.data.mapping.model.BasicPersistentEntity;
import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.Property;
import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
/** /**
@ -45,7 +44,7 @@ class AbstractMappingContextIntegrationTests<T extends PersistentProperty<T>> {
context.setInitialEntitySet(Collections.singleton(Person.class)); context.setInitialEntitySet(Collections.singleton(Person.class));
context.initialize(); context.initialize();
assertThat(context.getManagedTypes()).contains(ClassTypeInformation.from(Person.class)); assertThat(context.getManagedTypes()).contains(TypeInformation.of(Person.class));
} }
@Test // DATACMNS-457 @Test // DATACMNS-457

8
src/test/java/org/springframework/data/mapping/context/AbstractMappingContextUnitTests.java

@ -232,7 +232,7 @@ class AbstractMappingContextUnitTests {
void shouldIgnoreKotlinOverrideCtorPropertyInSuperClass() { void shouldIgnoreKotlinOverrideCtorPropertyInSuperClass() {
var entity = context var entity = context
.getPersistentEntity(ClassTypeInformation.from(ShadowingPropertyTypeWithCtor.class)); .getPersistentEntity(TypeInformation.of(ShadowingPropertyTypeWithCtor.class));
entity.doWithProperties((PropertyHandler<SamplePersistentProperty>) property -> { entity.doWithProperties((PropertyHandler<SamplePersistentProperty>) property -> {
assertThat(property.getField().getDeclaringClass()).isIn(ShadowingPropertyTypeWithCtor.class, assertThat(property.getField().getDeclaringClass()).isIn(ShadowingPropertyTypeWithCtor.class,
ShadowedPropertyTypeWithCtor.class); ShadowedPropertyTypeWithCtor.class);
@ -243,7 +243,7 @@ class AbstractMappingContextUnitTests {
void shouldIncludeAssignableKotlinOverridePropertyInSuperClass() { void shouldIncludeAssignableKotlinOverridePropertyInSuperClass() {
var entity = context var entity = context
.getPersistentEntity(ClassTypeInformation.from(ShadowingPropertyType.class)); .getPersistentEntity(TypeInformation.of(ShadowingPropertyType.class));
entity.doWithProperties((PropertyHandler<SamplePersistentProperty>) property -> { entity.doWithProperties((PropertyHandler<SamplePersistentProperty>) property -> {
assertThat(property.getField().getDeclaringClass()).isIn(ShadowedPropertyType.class, ShadowingPropertyType.class); assertThat(property.getField().getDeclaringClass()).isIn(ShadowedPropertyType.class, ShadowingPropertyType.class);
}); });
@ -253,7 +253,7 @@ class AbstractMappingContextUnitTests {
void shouldIncludeAssignableShadowedPropertyInSuperClass() { void shouldIncludeAssignableShadowedPropertyInSuperClass() {
var entity = context var entity = context
.getPersistentEntity(ClassTypeInformation.from(ShadowingPropertyAssignable.class)); .getPersistentEntity(TypeInformation.of(ShadowingPropertyAssignable.class));
assertThat(StreamUtils.createStreamFromIterator(entity.iterator()) assertThat(StreamUtils.createStreamFromIterator(entity.iterator())
.filter(it -> it.getField().getDeclaringClass().equals(ShadowedPropertyAssignable.class)).findFirst() // .filter(it -> it.getField().getDeclaringClass().equals(ShadowedPropertyAssignable.class)).findFirst() //
@ -271,7 +271,7 @@ class AbstractMappingContextUnitTests {
void shouldIgnoreNonAssignableOverridePropertyInSuperClass() { void shouldIgnoreNonAssignableOverridePropertyInSuperClass() {
var entity = context var entity = context
.getPersistentEntity(ClassTypeInformation.from(ShadowingPropertyNotAssignable.class)); .getPersistentEntity(TypeInformation.of(ShadowingPropertyNotAssignable.class));
entity.doWithProperties((PropertyHandler<SamplePersistentProperty>) property -> { entity.doWithProperties((PropertyHandler<SamplePersistentProperty>) property -> {
assertThat(property.getField().getDeclaringClass()).isEqualTo(ShadowingPropertyNotAssignable.class); assertThat(property.getField().getDeclaringClass()).isEqualTo(ShadowingPropertyNotAssignable.class);
}); });

5
src/test/java/org/springframework/data/mapping/context/PersistentEntitiesUnitTests.java

@ -24,12 +24,11 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Reference; import org.springframework.data.annotation.Reference;
import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.MappingException;
import org.springframework.data.mapping.model.BasicPersistentEntity; import org.springframework.data.mapping.model.BasicPersistentEntity;
import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation;
/** /**
* Unit tests for {@link PersistentEntities}. * Unit tests for {@link PersistentEntities}.
@ -76,7 +75,7 @@ class PersistentEntitiesUnitTests {
assertThat(entities.getPersistentEntity(Sample.class)).isPresent(); assertThat(entities.getPersistentEntity(Sample.class)).isPresent();
assertThat(entities.getPersistentEntity(Object.class)).isNotPresent(); assertThat(entities.getPersistentEntity(Object.class)).isNotPresent();
assertThat(entities.getManagedTypes()).contains(ClassTypeInformation.from(Sample.class)); assertThat(entities.getManagedTypes()).contains(TypeInformation.of(Sample.class));
assertThat(entities.getPersistentEntity(Sample.class)).hasValueSatisfying(it -> assertThat(entities).contains(it)); assertThat(entities.getPersistentEntity(Sample.class)).hasValueSatisfying(it -> assertThat(entities).contains(it));
} }

11
src/test/java/org/springframework/data/mapping/model/AbstractPersistentPropertyUnitTests.java

@ -35,13 +35,10 @@ import org.jmolecules.ddd.types.AggregateRoot;
import org.jmolecules.ddd.types.Identifier; import org.jmolecules.ddd.types.Identifier;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.data.convert.PropertyValueConverter;
import org.springframework.data.mapping.Association; import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.Person; import org.springframework.data.mapping.Person;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.Optionals; import org.springframework.data.util.Optionals;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
@ -62,7 +59,7 @@ public class AbstractPersistentPropertyUnitTests {
@BeforeEach @BeforeEach
void setUp() { void setUp() {
typeInfo = ClassTypeInformation.from(TestClassComplex.class); typeInfo = TypeInformation.of(TestClassComplex.class);
entity = new BasicPersistentEntity<>(typeInfo); entity = new BasicPersistentEntity<>(typeInfo);
typeHolder = new SimpleTypeHolder(); typeHolder = new SimpleTypeHolder();
} }
@ -142,7 +139,7 @@ public class AbstractPersistentPropertyUnitTests {
void doesNotDiscoverGetterAndSetterIfNoPropertyDescriptorGiven() { void doesNotDiscoverGetterAndSetterIfNoPropertyDescriptorGiven() {
var field = ReflectionUtils.findField(AccessorTestClass.class, "id"); var field = ReflectionUtils.findField(AccessorTestClass.class, "id");
var property = Property.of(ClassTypeInformation.from(AccessorTestClass.class), field); var property = Property.of(TypeInformation.of(AccessorTestClass.class), field);
PersistentProperty<SamplePersistentProperty> persistentProperty = new SamplePersistentProperty(property, PersistentProperty<SamplePersistentProperty> persistentProperty = new SamplePersistentProperty(property,
getEntity(AccessorTestClass.class), typeHolder); getEntity(AccessorTestClass.class), typeHolder);
@ -247,12 +244,12 @@ public class AbstractPersistentPropertyUnitTests {
} }
private <T> BasicPersistentEntity<T, SamplePersistentProperty> getEntity(Class<T> type) { private <T> BasicPersistentEntity<T, SamplePersistentProperty> getEntity(Class<T> type) {
return new BasicPersistentEntity<>(ClassTypeInformation.from(type)); return new BasicPersistentEntity<>(TypeInformation.of(type));
} }
private <T> SamplePersistentProperty getProperty(Class<T> type, String name) { private <T> SamplePersistentProperty getProperty(Class<T> type, String name) {
TypeInformation<?> typeInformation = ClassTypeInformation.from(type); TypeInformation<?> typeInformation = TypeInformation.of(type);
var field = Optional.ofNullable(ReflectionUtils.findField(type, name)); var field = Optional.ofNullable(ReflectionUtils.findField(type, name));
var descriptor = getPropertyDescriptor(type, name); var descriptor = getPropertyDescriptor(type, name);

8
src/test/java/org/springframework/data/mapping/model/AnnotationBasedPersistentPropertyUnitTests.java

@ -36,7 +36,6 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory; import org.junit.jupiter.api.TestFactory;
import org.springframework.core.annotation.AliasFor; import org.springframework.core.annotation.AliasFor;
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.annotation.AccessType; import org.springframework.data.annotation.AccessType;
@ -49,7 +48,7 @@ import org.springframework.data.mapping.MappingException;
import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.context.SampleMappingContext; import org.springframework.data.mapping.context.SampleMappingContext;
import org.springframework.data.mapping.context.SamplePersistentProperty; import org.springframework.data.mapping.context.SamplePersistentProperty;
import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;
@ -328,7 +327,7 @@ public class AnnotationBasedPersistentPropertyUnitTests<P extends AnnotationBase
assertThat(property.getPersistentEntityTypeInformation()) // assertThat(property.getPersistentEntityTypeInformation()) //
.isNotEmpty() // .isNotEmpty() //
.allMatch(it -> it.equals(ClassTypeInformation.from(Sample.class))); .allMatch(it -> it.equals(TypeInformation.of(Sample.class)));
} }
@Test // #2438 @Test // #2438
@ -461,8 +460,7 @@ public class AnnotationBasedPersistentPropertyUnitTests<P extends AnnotationBase
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(value = { FIELD, METHOD, ANNOTATION_TYPE }) @Target(value = { FIELD, METHOD, ANNOTATION_TYPE })
@Id @Id
public @interface MyId { public @interface MyId {}
}
static class FieldAccess { static class FieldAccess {
String name; String name;

7
src/test/java/org/springframework/data/mapping/model/BasicPersistentEntityUnitTests.java

@ -36,7 +36,6 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.core.annotation.AliasFor; import org.springframework.core.annotation.AliasFor;
import org.springframework.data.annotation.AccessType; import org.springframework.data.annotation.AccessType;
import org.springframework.data.annotation.AccessType.Type; import org.springframework.data.annotation.AccessType.Type;
@ -59,7 +58,7 @@ import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.Person; import org.springframework.data.mapping.Person;
import org.springframework.data.mapping.context.SampleMappingContext; import org.springframework.data.mapping.context.SampleMappingContext;
import org.springframework.data.mapping.context.SamplePersistentProperty; import org.springframework.data.mapping.context.SamplePersistentProperty;
import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;
@ -287,7 +286,7 @@ class BasicPersistentEntityUnitTests<T extends PersistentProperty<T>> {
var failed = new AtomicBoolean(false); var failed = new AtomicBoolean(false);
PersistentEntity<EntityWithAnnotation, T> entity = new BasicPersistentEntity<EntityWithAnnotation, T>( PersistentEntity<EntityWithAnnotation, T> entity = new BasicPersistentEntity<EntityWithAnnotation, T>(
ClassTypeInformation.from(EntityWithAnnotation.class), null) { TypeInformation.of(EntityWithAnnotation.class), null) {
@Nullable @Nullable
@Override @Override
@ -378,7 +377,7 @@ class BasicPersistentEntityUnitTests<T extends PersistentProperty<T>> {
} }
private <S> BasicPersistentEntity<S, T> createEntity(Class<S> type, Comparator<T> comparator) { private <S> BasicPersistentEntity<S, T> createEntity(Class<S> type, Comparator<T> comparator) {
return new BasicPersistentEntity<>(ClassTypeInformation.from(type), comparator); return new BasicPersistentEntity<>(TypeInformation.of(type), comparator);
} }
private static PersistentEntity<Object, ?> createPopulatedPersistentEntity(Class<?> type) { private static PersistentEntity<Object, ?> createPopulatedPersistentEntity(Class<?> type) {

16
src/test/java/org/springframework/data/mapping/model/ClassGeneratingEntityInstantiatorUnitTests.java

@ -18,7 +18,6 @@ package org.springframework.data.mapping.model;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*; import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import static org.springframework.data.util.ClassTypeInformation.from;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.Arrays; import java.util.Arrays;
@ -40,7 +39,6 @@ import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PreferredConstructor; import org.springframework.data.mapping.PreferredConstructor;
import org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.ObjectInstantiator; import org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.ObjectInstantiator;
import org.springframework.data.mapping.model.ClassGeneratingEntityInstantiatorUnitTests.Outer.Inner; import org.springframework.data.mapping.model.ClassGeneratingEntityInstantiatorUnitTests.Outer.Inner;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
@ -104,7 +102,7 @@ class ClassGeneratingEntityInstantiatorUnitTests<P extends PersistentProperty<P>
@Test // DATACMNS-134, DATACMNS-578 @Test // DATACMNS-134, DATACMNS-578
void createsInnerClassInstanceCorrectly() { void createsInnerClassInstanceCorrectly() {
var entity = new BasicPersistentEntity<Inner, P>(from(Inner.class)); var entity = new BasicPersistentEntity<Inner, P>(TypeInformation.of(Inner.class));
assertThat(entity.getInstanceCreatorMetadata()).satisfies(constructor -> { assertThat(entity.getInstanceCreatorMetadata()).satisfies(constructor -> {
var parameter = constructor.getParameters().iterator().next(); var parameter = constructor.getParameters().iterator().next();
@ -130,7 +128,7 @@ class ClassGeneratingEntityInstantiatorUnitTests<P extends PersistentProperty<P>
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
void capturesContextOnInstantiationException() throws Exception { void capturesContextOnInstantiationException() throws Exception {
PersistentEntity<Sample, P> entity = new BasicPersistentEntity<>(from(Sample.class)); PersistentEntity<Sample, P> entity = new BasicPersistentEntity<>(TypeInformation.of(Sample.class));
doReturn("FOO").when(provider).getParameterValue(any(Parameter.class)); doReturn("FOO").when(provider).getParameterValue(any(Parameter.class));
@ -159,8 +157,9 @@ class ClassGeneratingEntityInstantiatorUnitTests<P extends PersistentProperty<P>
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
void createsInstancesWithRecursionAndSameCtorArgCountCorrectly() { void createsInstancesWithRecursionAndSameCtorArgCountCorrectly() {
PersistentEntity<SampleWithReference, P> outer = new BasicPersistentEntity<>(from(SampleWithReference.class)); PersistentEntity<SampleWithReference, P> outer = new BasicPersistentEntity<>(
PersistentEntity<Sample, P> inner = new BasicPersistentEntity<>(from(Sample.class)); TypeInformation.of(SampleWithReference.class));
PersistentEntity<Sample, P> inner = new BasicPersistentEntity<>(TypeInformation.of(Sample.class));
doReturn(2L, "FOO").when(provider).getParameterValue(any(Parameter.class)); doReturn(2L, "FOO").when(provider).getParameterValue(any(Parameter.class));
@ -193,7 +192,8 @@ class ClassGeneratingEntityInstantiatorUnitTests<P extends PersistentProperty<P>
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
void createsInstancesWithFactoryMethodCorrectly() { void createsInstancesWithFactoryMethodCorrectly() {
PersistentEntity<WithFactoryMethod, P> entity = new BasicPersistentEntity<>(from(WithFactoryMethod.class)); PersistentEntity<WithFactoryMethod, P> entity = new BasicPersistentEntity<>(
TypeInformation.of(WithFactoryMethod.class));
doReturn(2L, "FOO").when(provider).getParameterValue(any(Parameter.class)); doReturn(2L, "FOO").when(provider).getParameterValue(any(Parameter.class));
@ -436,7 +436,7 @@ class ClassGeneratingEntityInstantiatorUnitTests<P extends PersistentProperty<P>
void entityInstantiatorShouldFailForAbstractClass() { void entityInstantiatorShouldFailForAbstractClass() {
assertThatExceptionOfType(MappingInstantiationException.class).isThrownBy(() -> this.instance assertThatExceptionOfType(MappingInstantiationException.class).isThrownBy(() -> this.instance
.createInstance(new BasicPersistentEntity<>(ClassTypeInformation.from(AbstractDto.class)), provider)); .createInstance(new BasicPersistentEntity<>(TypeInformation.of(AbstractDto.class)), provider));
} }
private void prepareMocks(Class<?> type) { private void prepareMocks(Class<?> type) {

1
src/test/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactoryEntityTypeTests.java

@ -21,7 +21,6 @@ import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.context.SampleMappingContext; import org.springframework.data.mapping.context.SampleMappingContext;

10
src/test/java/org/springframework/data/mapping/model/EntityCreatorMetadataDiscovererUnitTests.java

@ -21,7 +21,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.annotation.PersistenceCreator;
import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.MappingException;
import org.springframework.data.mapping.PreferredConstructor; import org.springframework.data.mapping.PreferredConstructor;
import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation;
/** /**
* Unit tests for {@link InstanceCreatorMetadataDiscoverer}. * Unit tests for {@link InstanceCreatorMetadataDiscoverer}.
@ -33,7 +33,7 @@ class EntityCreatorMetadataDiscovererUnitTests {
@Test @Test
void shouldDiscoverAnnotatedFactoryMethod() { void shouldDiscoverAnnotatedFactoryMethod() {
var entity = new BasicPersistentEntity<>(ClassTypeInformation.from(FactoryMethodsPerson.class)); var entity = new BasicPersistentEntity<>(TypeInformation.of(FactoryMethodsPerson.class));
var creator = InstanceCreatorMetadataDiscoverer.discover(entity); var creator = InstanceCreatorMetadataDiscoverer.discover(entity);
assertThat(creator).isInstanceOf(org.springframework.data.mapping.FactoryMethod.class); assertThat(creator).isInstanceOf(org.springframework.data.mapping.FactoryMethod.class);
@ -44,7 +44,7 @@ class EntityCreatorMetadataDiscovererUnitTests {
@Test @Test
void shouldDiscoverAnnotatedConstructor() { void shouldDiscoverAnnotatedConstructor() {
var entity = new BasicPersistentEntity<>(ClassTypeInformation.from(ConstructorPerson.class)); var entity = new BasicPersistentEntity<>(TypeInformation.of(ConstructorPerson.class));
var creator = InstanceCreatorMetadataDiscoverer.discover(entity); var creator = InstanceCreatorMetadataDiscoverer.discover(entity);
assertThat(creator).isInstanceOf(PreferredConstructor.class); assertThat(creator).isInstanceOf(PreferredConstructor.class);
@ -53,7 +53,7 @@ class EntityCreatorMetadataDiscovererUnitTests {
@Test @Test
void shouldDiscoverDefaultConstructor() { void shouldDiscoverDefaultConstructor() {
var entity = new BasicPersistentEntity<>(ClassTypeInformation.from(Person.class)); var entity = new BasicPersistentEntity<>(TypeInformation.of(Person.class));
var creator = InstanceCreatorMetadataDiscoverer.discover(entity); var creator = InstanceCreatorMetadataDiscoverer.discover(entity);
assertThat(creator).isInstanceOf(PreferredConstructor.class); assertThat(creator).isInstanceOf(PreferredConstructor.class);
@ -62,7 +62,7 @@ class EntityCreatorMetadataDiscovererUnitTests {
@Test @Test
void shouldRejectNonStaticFactoryMethod() { void shouldRejectNonStaticFactoryMethod() {
assertThatExceptionOfType(MappingException.class) assertThatExceptionOfType(MappingException.class)
.isThrownBy(() -> new BasicPersistentEntity<>(ClassTypeInformation.from(NonStaticFactoryMethod.class))); .isThrownBy(() -> new BasicPersistentEntity<>(TypeInformation.of(NonStaticFactoryMethod.class)));
} }
static class Person { static class Person {

4
src/test/java/org/springframework/data/mapping/model/FactoryMethodUnitTests.java

@ -20,7 +20,7 @@ import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.PersistenceCreator; import org.springframework.data.annotation.PersistenceCreator;
import org.springframework.data.mapping.Parameter; import org.springframework.data.mapping.Parameter;
import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation;
/** /**
* Unit tests for {@link org.springframework.data.mapping.FactoryMethod}. * Unit tests for {@link org.springframework.data.mapping.FactoryMethod}.
@ -34,7 +34,7 @@ class FactoryMethodUnitTests {
@Test @Test
void shouldCreateInstanceThroughFactoryMethod() { void shouldCreateInstanceThroughFactoryMethod() {
var entity = new BasicPersistentEntity<>(ClassTypeInformation.from(FactoryPerson.class)); var entity = new BasicPersistentEntity<>(TypeInformation.of(FactoryPerson.class));
var result = instantiators.getInstantiatorFor(entity).createInstance(entity, var result = instantiators.getInstantiatorFor(entity).createInstance(entity,
new ParameterValueProvider() { new ParameterValueProvider() {

6
src/test/java/org/springframework/data/mapping/model/PersistentEntityParameterValueProviderUnitTests.java

@ -27,7 +27,7 @@ import org.springframework.data.mapping.MappingException;
import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.model.PersistentEntityParameterValueProviderUnitTests.Outer.Inner; import org.springframework.data.mapping.model.PersistentEntityParameterValueProviderUnitTests.Outer.Inner;
import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation;
/** /**
* Unit tests for {@link PersistentEntityParameterValueProvider}. * Unit tests for {@link PersistentEntityParameterValueProvider}.
@ -46,7 +46,7 @@ class PersistentEntityParameterValueProviderUnitTests<P extends PersistentProper
Object outer = new Outer(); Object outer = new Outer();
PersistentEntity<Inner, P> entity = new BasicPersistentEntity<Inner, P>(ClassTypeInformation.from(Inner.class)) { PersistentEntity<Inner, P> entity = new BasicPersistentEntity<Inner, P>(TypeInformation.of(Inner.class)) {
@Override @Override
public P getPersistentProperty(String name) { public P getPersistentProperty(String name) {
@ -69,7 +69,7 @@ class PersistentEntityParameterValueProviderUnitTests<P extends PersistentProper
@Test @Test
void rejectsPropertyIfNameDoesNotMatch() { void rejectsPropertyIfNameDoesNotMatch() {
PersistentEntity<Entity, P> entity = new BasicPersistentEntity<>(ClassTypeInformation.from(Entity.class)); PersistentEntity<Entity, P> entity = new BasicPersistentEntity<>(TypeInformation.of(Entity.class));
ParameterValueProvider<P> provider = new PersistentEntityParameterValueProvider<>(entity, propertyValueProvider, ParameterValueProvider<P> provider = new PersistentEntityParameterValueProvider<>(entity, propertyValueProvider,
Optional.of(property)); Optional.of(property));

15
src/test/java/org/springframework/data/mapping/model/PropertyUnitTests.java

@ -21,7 +21,7 @@ import lombok.Value;
import lombok.With; import lombok.With;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
/** /**
@ -35,17 +35,17 @@ class PropertyUnitTests {
void shouldNotFindWitherMethod() { void shouldNotFindWitherMethod() {
assertThat(Property assertThat(Property
.of(ClassTypeInformation.from(ImmutableType.class), ReflectionUtils.findField(ImmutableType.class, "id")) .of(TypeInformation.of(ImmutableType.class), ReflectionUtils.findField(ImmutableType.class, "id"))
.getWither()).isEmpty(); .getWither()).isEmpty();
assertThat(Property assertThat(Property
.of(ClassTypeInformation.from(ImmutableType.class), ReflectionUtils.findField(ImmutableType.class, "name")) .of(TypeInformation.of(ImmutableType.class), ReflectionUtils.findField(ImmutableType.class, "name"))
.getWither()).isEmpty(); .getWither()).isEmpty();
} }
@Test // DATACMNS-1322 @Test // DATACMNS-1322
void shouldDiscoverWitherMethod() { void shouldDiscoverWitherMethod() {
var property = Property.of(ClassTypeInformation.from(WitherType.class), var property = Property.of(TypeInformation.of(WitherType.class),
ReflectionUtils.findField(WitherType.class, "id")); ReflectionUtils.findField(WitherType.class, "id"));
assertThat(property.getWither()).isPresent().hasValueSatisfying(actual -> { assertThat(property.getWither()).isPresent().hasValueSatisfying(actual -> {
@ -57,7 +57,7 @@ class PropertyUnitTests {
@Test // DATACMNS-1421 @Test // DATACMNS-1421
void shouldDiscoverDerivedWitherMethod() { void shouldDiscoverDerivedWitherMethod() {
var property = Property.of(ClassTypeInformation.from(DerivedWitherClass.class), var property = Property.of(TypeInformation.of(DerivedWitherClass.class),
ReflectionUtils.findField(DerivedWitherClass.class, "id")); ReflectionUtils.findField(DerivedWitherClass.class, "id"));
assertThat(property.getWither()).isPresent().hasValueSatisfying(actual -> { assertThat(property.getWither()).isPresent().hasValueSatisfying(actual -> {
@ -70,7 +70,7 @@ class PropertyUnitTests {
@Test // DATACMNS-1421 @Test // DATACMNS-1421
void shouldNotDiscoverWitherMethodWithIncompatibleReturnType() { void shouldNotDiscoverWitherMethodWithIncompatibleReturnType() {
var property = Property.of(ClassTypeInformation.from(AnotherLevel.class), var property = Property.of(TypeInformation.of(AnotherLevel.class),
ReflectionUtils.findField(AnotherLevel.class, "id")); ReflectionUtils.findField(AnotherLevel.class, "id"));
assertThat(property.getWither()).isEmpty(); assertThat(property.getWither()).isEmpty();
@ -110,6 +110,7 @@ class PropertyUnitTests {
static abstract class WitherIntermediateClass extends WitherBaseClass { static abstract class WitherIntermediateClass extends WitherBaseClass {
@Override
abstract WitherIntermediateClass withId(String id); abstract WitherIntermediateClass withId(String id);
} }
@ -121,6 +122,7 @@ class PropertyUnitTests {
this.id = id; this.id = id;
} }
@Override
DerivedWitherClass withId(String id) { DerivedWitherClass withId(String id) {
return new DerivedWitherClass(id); return new DerivedWitherClass(id);
} }
@ -132,6 +134,7 @@ class PropertyUnitTests {
super(id); super(id);
} }
@Override
DerivedWitherClass withId(String id) { DerivedWitherClass withId(String id) {
return new AnotherLevel(id); return new AnotherLevel(id);
} }

6
src/test/java/org/springframework/data/mapping/model/ReflectionEntityInstantiatorUnitTests.java

@ -19,7 +19,6 @@ import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*; import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import static org.springframework.data.mapping.model.ReflectionEntityInstantiator.*; import static org.springframework.data.mapping.model.ReflectionEntityInstantiator.*;
import static org.springframework.data.util.ClassTypeInformation.from;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.Arrays; import java.util.Arrays;
@ -34,6 +33,7 @@ import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PreferredConstructor; import org.springframework.data.mapping.PreferredConstructor;
import org.springframework.data.mapping.model.ReflectionEntityInstantiatorUnitTests.Outer.Inner; import org.springframework.data.mapping.model.ReflectionEntityInstantiatorUnitTests.Outer.Inner;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
/** /**
@ -90,7 +90,7 @@ class ReflectionEntityInstantiatorUnitTests<P extends PersistentProperty<P>> {
@Test // DATACMNS-134 @Test // DATACMNS-134
void createsInnerClassInstanceCorrectly() { void createsInnerClassInstanceCorrectly() {
var entity = new BasicPersistentEntity<Inner, P>(from(Inner.class)); var entity = new BasicPersistentEntity<Inner, P>(TypeInformation.of(Inner.class));
assertThat(entity.getInstanceCreatorMetadata()).satisfies(it -> { assertThat(entity.getInstanceCreatorMetadata()).satisfies(it -> {
var parameter = it.getParameters().iterator().next(); var parameter = it.getParameters().iterator().next();
@ -116,7 +116,7 @@ class ReflectionEntityInstantiatorUnitTests<P extends PersistentProperty<P>> {
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
void capturesContextOnInstantiationException() throws Exception { void capturesContextOnInstantiationException() throws Exception {
PersistentEntity<Sample, P> entity = new BasicPersistentEntity<>(from(Sample.class)); PersistentEntity<Sample, P> entity = new BasicPersistentEntity<>(TypeInformation.of(Sample.class));
doReturn("FOO").when(provider).getParameterValue(any(Parameter.class)); doReturn("FOO").when(provider).getParameterValue(any(Parameter.class));

6
src/test/java/org/springframework/data/querydsl/binding/QuerydslBindingsFactoryUnitTests.java

@ -23,14 +23,12 @@ import java.util.Optional;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.support.GenericApplicationContext; import org.springframework.context.support.GenericApplicationContext;
import org.springframework.data.querydsl.QUser; import org.springframework.data.querydsl.QUser;
import org.springframework.data.querydsl.SimpleEntityPathResolver; import org.springframework.data.querydsl.SimpleEntityPathResolver;
import org.springframework.data.querydsl.User; import org.springframework.data.querydsl.User;
import org.springframework.data.repository.support.Repositories; import org.springframework.data.repository.support.Repositories;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
@ -47,7 +45,7 @@ import com.querydsl.core.types.Predicate;
*/ */
class QuerydslBindingsFactoryUnitTests { class QuerydslBindingsFactoryUnitTests {
static final TypeInformation<?> USER_TYPE = ClassTypeInformation.from(User.class); static final TypeInformation<?> USER_TYPE = TypeInformation.of(User.class);
QuerydslBindingsFactory factory; QuerydslBindingsFactory factory;
@ -123,7 +121,7 @@ class QuerydslBindingsFactoryUnitTests {
void rejectsPredicateResolutionIfDomainTypeCantBeAutoDetected() { void rejectsPredicateResolutionIfDomainTypeCantBeAutoDetected() {
assertThatIllegalStateException()// assertThatIllegalStateException()//
.isThrownBy(() -> factory.createBindingsFor(ClassTypeInformation.from(ModelAndView.class)))// .isThrownBy(() -> factory.createBindingsFor(TypeInformation.of(ModelAndView.class)))//
.withMessageContaining(QuerydslPredicate.class.getSimpleName())// .withMessageContaining(QuerydslPredicate.class.getSimpleName())//
.withMessageContaining("root"); .withMessageContaining("root");

11
src/test/java/org/springframework/data/querydsl/binding/QuerydslBindingsUnitTests.java

@ -21,7 +21,6 @@ import java.util.Optional;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.querydsl.Address; import org.springframework.data.querydsl.Address;
import org.springframework.data.querydsl.QAddress; import org.springframework.data.querydsl.QAddress;
@ -29,7 +28,7 @@ import org.springframework.data.querydsl.QSpecialUser;
import org.springframework.data.querydsl.QUser; import org.springframework.data.querydsl.QUser;
import org.springframework.data.querydsl.SimpleEntityPathResolver; import org.springframework.data.querydsl.SimpleEntityPathResolver;
import org.springframework.data.querydsl.User; import org.springframework.data.querydsl.User;
import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation;
import com.querydsl.core.types.Path; import com.querydsl.core.types.Path;
import com.querydsl.core.types.Predicate; import com.querydsl.core.types.Predicate;
@ -230,7 +229,7 @@ class QuerydslBindingsUnitTests {
bindings.bind(QUser.user.address.city).as("city").first(CONTAINS_BINDING); bindings.bind(QUser.user.address.city).as("city").first(CONTAINS_BINDING);
var path = bindings.getPropertyPath("city", ClassTypeInformation.from(User.class)); var path = bindings.getPropertyPath("city", TypeInformation.of(User.class));
assertThat(path).isNotNull(); assertThat(path).isNotNull();
assertThat(bindings.isPathAvailable("city", User.class)).isTrue(); assertThat(bindings.isPathAvailable("city", User.class)).isTrue();
@ -245,14 +244,14 @@ class QuerydslBindingsUnitTests {
bindings.including(QUser.user.address.city); bindings.including(QUser.user.address.city);
bindings.bind(QUser.user.address.city).as("city").first(CONTAINS_BINDING); bindings.bind(QUser.user.address.city).as("city").first(CONTAINS_BINDING);
var path = bindings.getPropertyPath("city", ClassTypeInformation.from(User.class)); var path = bindings.getPropertyPath("city", TypeInformation.of(User.class));
assertThat(path).isNotNull(); assertThat(path).isNotNull();
assertThat(bindings.isPathAvailable("city", User.class)).isTrue(); assertThat(bindings.isPathAvailable("city", User.class)).isTrue();
assertThat(bindings.isPathAvailable("address.city", User.class)).isTrue(); assertThat(bindings.isPathAvailable("address.city", User.class)).isTrue();
var propertyPath = bindings.getPropertyPath("address.city", ClassTypeInformation.from(User.class)); var propertyPath = bindings.getPropertyPath("address.city", TypeInformation.of(User.class));
assertThat(propertyPath).isNotNull(); assertThat(propertyPath).isNotNull();
assertAdapterWithTargetBinding(bindings.getBindingForPath(propertyPath), CONTAINS_BINDING); assertAdapterWithTargetBinding(bindings.getBindingForPath(propertyPath), CONTAINS_BINDING);
@ -263,7 +262,7 @@ class QuerydslBindingsUnitTests {
bindings.bind(QUser.user.address.city).as("city").withDefaultBinding(); bindings.bind(QUser.user.address.city).as("city").withDefaultBinding();
var path = bindings.getPropertyPath("city", ClassTypeInformation.from(User.class)); var path = bindings.getPropertyPath("city", TypeInformation.of(User.class));
assertThat(path).isNotNull(); assertThat(path).isNotNull();
assertThat(bindings.getBindingForPath(path)).isNotPresent(); assertThat(bindings.getBindingForPath(path)).isNotPresent();

17
src/test/java/org/springframework/data/querydsl/binding/QuerydslPredicateBuilderUnitTests.java

@ -23,7 +23,6 @@ import java.util.List;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.data.querydsl.Address; import org.springframework.data.querydsl.Address;
import org.springframework.data.querydsl.QSpecialUser; import org.springframework.data.querydsl.QSpecialUser;
import org.springframework.data.querydsl.QUser; import org.springframework.data.querydsl.QUser;
@ -32,7 +31,8 @@ import org.springframework.data.querydsl.SimpleEntityPathResolver;
import org.springframework.data.querydsl.User; import org.springframework.data.querydsl.User;
import org.springframework.data.querydsl.UserWrapper; import org.springframework.data.querydsl.UserWrapper;
import org.springframework.data.querydsl.Users; import org.springframework.data.querydsl.Users;
import org.springframework.data.util.ClassTypeInformation; // import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
import org.springframework.data.util.Version; import org.springframework.data.util.Version;
import org.springframework.format.support.DefaultFormattingConversionService; import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
@ -51,7 +51,7 @@ import com.querydsl.core.types.dsl.StringPath;
*/ */
class QuerydslPredicateBuilderUnitTests { class QuerydslPredicateBuilderUnitTests {
static final ClassTypeInformation<User> USER_TYPE = ClassTypeInformation.from(User.class); static final TypeInformation<User> USER_TYPE = TypeInformation.of(User.class);
static final QuerydslBindings DEFAULT_BINDINGS = new QuerydslBindings(); static final QuerydslBindings DEFAULT_BINDINGS = new QuerydslBindings();
static final SingleValueBinding<StringPath, String> CONTAINS_BINDING = (path, value) -> path.contains(value); static final SingleValueBinding<StringPath, String> CONTAINS_BINDING = (path, value) -> path.contains(value);
@ -79,8 +79,9 @@ class QuerydslPredicateBuilderUnitTests {
@Test // DATACMNS-669, DATACMNS-1168 @Test // DATACMNS-669, DATACMNS-1168
void getPredicateShouldReturnEmptyWhenPropertiesAreEmpty() { void getPredicateShouldReturnEmptyWhenPropertiesAreEmpty() {
assertThat( assertThat(
QuerydslPredicateBuilder.isEmpty(builder.getPredicate(ClassTypeInformation.OBJECT, values, DEFAULT_BINDINGS))) QuerydslPredicateBuilder
.isTrue(); .isEmpty(builder.getPredicate(TypeInformation.of(Object.class), values, DEFAULT_BINDINGS)))
.isTrue();
} }
@Test // GH-2418 @Test // GH-2418
@ -89,11 +90,11 @@ class QuerydslPredicateBuilderUnitTests {
DEFAULT_BINDINGS.bind(QUser.user.description).first(CONTAINS_BINDING); DEFAULT_BINDINGS.bind(QUser.user.description).first(CONTAINS_BINDING);
values.add("description", "Linz"); values.add("description", "Linz");
var predicate = this.builder.getPredicate(ClassTypeInformation.from(User.class), values, DEFAULT_BINDINGS); var predicate = this.builder.getPredicate(TypeInformation.of(User.class), values, DEFAULT_BINDINGS);
assertThat(predicate).hasToString("contains(user.description,Linz)"); assertThat(predicate).hasToString("contains(user.description,Linz)");
predicate = this.builder.getPredicate(ClassTypeInformation.from(Address.class), values, DEFAULT_BINDINGS); predicate = this.builder.getPredicate(TypeInformation.of(Address.class), values, DEFAULT_BINDINGS);
assertThat(predicate).hasToString("address.description = Linz"); assertThat(predicate).hasToString("address.description = Linz");
} }
@ -214,7 +215,7 @@ class QuerydslPredicateBuilderUnitTests {
bindings.bind(wrapper.user.as(QSpecialUser.class).specialProperty)// bindings.bind(wrapper.user.as(QSpecialUser.class).specialProperty)//
.first(QuerydslBindingsUnitTests.ContainsBinding.INSTANCE); .first(QuerydslBindingsUnitTests.ContainsBinding.INSTANCE);
assertThat(builder.getPredicate(ClassTypeInformation.from(UserWrapper.class), values, bindings))// assertThat(builder.getPredicate(TypeInformation.of(UserWrapper.class), values, bindings))//
.isEqualTo(wrapper.user.as(QSpecialUser.class).specialProperty.contains("VALUE")); .isEqualTo(wrapper.user.as(QSpecialUser.class).specialProperty.contains("VALUE"));
} }

4
src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryMetadataUnitTests.java

@ -22,14 +22,12 @@ import java.util.Collection;
import java.util.Optional; import java.util.Optional;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.Repository; import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.util.ClassUtils; import org.springframework.data.repository.util.ClassUtils;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
/** /**
@ -84,7 +82,7 @@ class DefaultRepositoryMetadataUnitTests {
RepositoryMetadata metadata = new DefaultRepositoryMetadata(GenericEntityRepository.class); RepositoryMetadata metadata = new DefaultRepositoryMetadata(GenericEntityRepository.class);
TypeInformation<?> domainType = metadata.getDomainTypeInformation(); TypeInformation<?> domainType = metadata.getDomainTypeInformation();
assertThat(domainType.getType()).isEqualTo(GenericEntity.class); assertThat(domainType.getType()).isEqualTo(GenericEntity.class);
assertThat(domainType.getTypeArguments()).containsExactly(ClassTypeInformation.from(String.class)); assertThat(domainType.getTypeArguments()).containsExactly(TypeInformation.of(String.class));
} }
@Test @Test

5
src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java

@ -19,7 +19,6 @@ import static java.util.Collections.*;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*; import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import static org.springframework.data.repository.core.support.DummyRepositoryFactory.*;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -40,25 +39,23 @@ import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness; import org.mockito.quality.Strictness;
import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.querydsl.QuerydslPredicateExecutor; import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.Repository; import org.springframework.data.repository.Repository;
import org.springframework.data.repository.RepositoryDefinition; import org.springframework.data.repository.RepositoryDefinition;
import org.springframework.data.repository.core.EntityInformation; import org.springframework.data.repository.core.EntityInformation;
import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.core.NamedQueries;
import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.DummyRepositoryFactory.MyRepositoryQuery;
import org.springframework.data.repository.core.support.RepositoryComposition.RepositoryFragments; import org.springframework.data.repository.core.support.RepositoryComposition.RepositoryFragments;
import org.springframework.data.repository.core.support.RepositoryMethodInvocationListener.RepositoryMethodInvocation; import org.springframework.data.repository.core.support.RepositoryMethodInvocationListener.RepositoryMethodInvocation;
import org.springframework.data.repository.core.support.RepositoryMethodInvocationListener.RepositoryMethodInvocationResult.State; import org.springframework.data.repository.core.support.RepositoryMethodInvocationListener.RepositoryMethodInvocationResult.State;

7
src/test/java/org/springframework/data/repository/support/DomainClassConverterIntegrationTests.java

@ -24,7 +24,6 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl; import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor; import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
@ -37,7 +36,7 @@ import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
import org.springframework.data.repository.core.support.RepositoryFactoryInformation; import org.springframework.data.repository.core.support.RepositoryFactoryInformation;
import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation;
/** /**
* Integration test for {@link DomainClassConverter}. * Integration test for {@link DomainClassConverter}.
@ -66,8 +65,8 @@ class DomainClassConverterIntegrationTests {
beanFactory.registerBeanDefinition("postProcessor", new RootBeanDefinition(PredictingProcessor.class)); beanFactory.registerBeanDefinition("postProcessor", new RootBeanDefinition(PredictingProcessor.class));
beanFactory.registerBeanDefinition("repoFactory", new RootBeanDefinition(RepositoryFactoryBeanSupport.class)); beanFactory.registerBeanDefinition("repoFactory", new RootBeanDefinition(RepositoryFactoryBeanSupport.class));
doReturn(ClassTypeInformation.from(Person.class)).when(information).getDomainTypeInformation(); doReturn(TypeInformation.of(Person.class)).when(information).getDomainTypeInformation();
doReturn(ClassTypeInformation.from(Serializable.class)).when(information).getIdTypeInformation(); doReturn(TypeInformation.of(Serializable.class)).when(information).getIdTypeInformation();
doCallRealMethod().when(information).getDomainType(); doCallRealMethod().when(information).getDomainType();
doReturn(PersonRepository.class).when(factory).getObjectType(); doReturn(PersonRepository.class).when(factory).getObjectType();
doReturn(information).when(factory).getRepositoryInformation(); doReturn(information).when(factory).getRepositoryInformation();

14
src/test/java/org/springframework/data/repository/util/QueryExecutionConvertersUnitTests.java

@ -33,20 +33,18 @@ import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.reactivestreams.Publisher; import org.reactivestreams.Publisher;
import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Slice; import org.springframework.data.domain.Slice;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.NullableWrapper; import org.springframework.data.util.NullableWrapper;
import org.springframework.data.util.Streamable; import org.springframework.data.util.Streamable;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.concurrent.ListenableFuture;
import com.google.common.base.Optional; import com.google.common.base.Optional;
@ -185,7 +183,7 @@ class QueryExecutionConvertersUnitTests {
void unwrapsPages() throws Exception { void unwrapsPages() throws Exception {
var method = Sample.class.getMethod("pages"); var method = Sample.class.getMethod("pages");
var returnType = ClassTypeInformation.fromReturnTypeOf(method); var returnType = TypeInformation.fromReturnTypeOf(method);
assertThat(QueryExecutionConverters.unwrapWrapperTypes(returnType).getType()) assertThat(QueryExecutionConverters.unwrapWrapperTypes(returnType).getType())
.isEqualTo(String.class); .isEqualTo(String.class);
@ -207,9 +205,7 @@ class QueryExecutionConvertersUnitTests {
for (var methodName : Arrays.asList("tryMethod", "tryForSeqMethod")) { for (var methodName : Arrays.asList("tryMethod", "tryForSeqMethod")) {
var method = Sample.class.getMethod(methodName); var method = Sample.class.getMethod(methodName);
var type = QueryExecutionConverters.unwrapWrapperTypes(TypeInformation.fromReturnTypeOf(method));
var type = QueryExecutionConverters
.unwrapWrapperTypes(ClassTypeInformation.fromReturnTypeOf(method));
assertThat(type.getType()).isEqualTo(Sample.class); assertThat(type.getType()).isEqualTo(Sample.class);
} }
@ -231,9 +227,7 @@ class QueryExecutionConvertersUnitTests {
for (var methodName : Arrays.asList("tryMethod", "tryForSeqMethod")) { for (var methodName : Arrays.asList("tryMethod", "tryForSeqMethod")) {
var method = Sample.class.getMethod(methodName); var method = Sample.class.getMethod(methodName);
var type = QueryExecutionConverters.unwrapWrapperTypes(TypeInformation.fromReturnTypeOf(method));
var type = QueryExecutionConverters
.unwrapWrapperTypes(ClassTypeInformation.fromReturnTypeOf(method));
assertThat(type.getType()).isEqualTo(Sample.class); assertThat(type.getType()).isEqualTo(Sample.class);
} }

144
src/test/java/org/springframework/data/util/ClassTypeInformationUnitTests.java

@ -16,7 +16,8 @@
package org.springframework.data.util; package org.springframework.data.util;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.util.ClassTypeInformation.from; import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertThat;
import io.vavr.collection.Traversable; import io.vavr.collection.Traversable;
@ -34,7 +35,7 @@ import org.springframework.aop.SpringProxy;
import org.springframework.aop.TargetSource; import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.Advised; import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.AopConfigException; import org.springframework.aop.framework.AopConfigException;
import org.springframework.core.ResolvableType;
import org.springframework.data.mapping.Person; import org.springframework.data.mapping.Person;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
@ -49,7 +50,7 @@ public class ClassTypeInformationUnitTests {
@Test @Test
public void discoversTypeForSimpleGenericField() { public void discoversTypeForSimpleGenericField() {
TypeInformation<ConcreteType> discoverer = from(ConcreteType.class); TypeInformation<ConcreteType> discoverer = TypeInformation.of(ConcreteType.class);
assertThat(discoverer.getType()).isEqualTo(ConcreteType.class); assertThat(discoverer.getType()).isEqualTo(ConcreteType.class);
@ -63,7 +64,7 @@ public class ClassTypeInformationUnitTests {
@Test @Test
public void discoversTypeForNestedGenericField() { public void discoversTypeForNestedGenericField() {
TypeInformation<ConcreteWrapper> discoverer = from(ConcreteWrapper.class); TypeInformation<ConcreteWrapper> discoverer = TypeInformation.of(ConcreteWrapper.class);
assertThat(discoverer.getType()).isEqualTo(ConcreteWrapper.class); assertThat(discoverer.getType()).isEqualTo(ConcreteWrapper.class);
assertThat(discoverer.getProperty("wrapped")).satisfies(it -> { assertThat(discoverer.getProperty("wrapped")).satisfies(it -> {
@ -79,14 +80,14 @@ public class ClassTypeInformationUnitTests {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public void discoversBoundType() { public void discoversBoundType() {
TypeInformation<GenericTypeWithBound> information = from(GenericTypeWithBound.class); TypeInformation<GenericTypeWithBound> information = TypeInformation.of(GenericTypeWithBound.class);
assertThat(information.getProperty("person")).satisfies(it -> assertThat(it.getType()).isEqualTo(Person.class)); assertThat(information.getProperty("person")).satisfies(it -> assertThat(it.getType()).isEqualTo(Person.class));
} }
@Test @Test
public void discoversBoundTypeForSpecialization() { public void discoversBoundTypeForSpecialization() {
TypeInformation<SpecialGenericTypeWithBound> information = from(SpecialGenericTypeWithBound.class); TypeInformation<SpecialGenericTypeWithBound> information = TypeInformation.of(SpecialGenericTypeWithBound.class);
assertThat(information.getProperty("person")) assertThat(information.getProperty("person"))
.satisfies(it -> assertThat(it.getType()).isEqualTo(SpecialPerson.class)); .satisfies(it -> assertThat(it.getType()).isEqualTo(SpecialPerson.class));
} }
@ -95,7 +96,7 @@ public class ClassTypeInformationUnitTests {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public void discoversBoundTypeForNested() { public void discoversBoundTypeForNested() {
TypeInformation<AnotherGenericType> information = from(AnotherGenericType.class); TypeInformation<AnotherGenericType> information = TypeInformation.of(AnotherGenericType.class);
assertThat(information.getProperty("nested")) assertThat(information.getProperty("nested"))
.satisfies(it -> assertThat(it.getType()).isEqualTo(GenericTypeWithBound.class)); .satisfies(it -> assertThat(it.getType()).isEqualTo(GenericTypeWithBound.class));
@ -106,7 +107,7 @@ public class ClassTypeInformationUnitTests {
@Test @Test
public void discoversArraysAndCollections() { public void discoversArraysAndCollections() {
TypeInformation<StringCollectionContainer> information = from(StringCollectionContainer.class); TypeInformation<StringCollectionContainer> information = TypeInformation.of(StringCollectionContainer.class);
var array = information.getProperty("array"); var array = information.getProperty("array");
@ -132,7 +133,7 @@ public class ClassTypeInformationUnitTests {
@Test @Test
public void discoversMapValueType() { public void discoversMapValueType() {
TypeInformation<StringMapContainer> information = from(StringMapContainer.class); TypeInformation<StringMapContainer> information = TypeInformation.of(StringMapContainer.class);
var genericMap = information.getProperty("genericMap"); var genericMap = information.getProperty("genericMap");
@ -148,8 +149,8 @@ public class ClassTypeInformationUnitTests {
@Test @Test
public void typeInfoDoesNotEqualForGenericTypesWithDifferentParent() { public void typeInfoDoesNotEqualForGenericTypesWithDifferentParent() {
TypeInformation<ConcreteWrapper> first = from(ConcreteWrapper.class); TypeInformation<ConcreteWrapper> first = TypeInformation.of(ConcreteWrapper.class);
TypeInformation<AnotherConcreteWrapper> second = from(AnotherConcreteWrapper.class); TypeInformation<AnotherConcreteWrapper> second = TypeInformation.of(AnotherConcreteWrapper.class);
assertThat(first.getProperty("wrapped").equals(second.getProperty("wrapped"))).isFalse(); assertThat(first.getProperty("wrapped").equals(second.getProperty("wrapped"))).isFalse();
} }
@ -157,7 +158,7 @@ public class ClassTypeInformationUnitTests {
@Test @Test
public void handlesPropertyFieldMismatchCorrectly() { public void handlesPropertyFieldMismatchCorrectly() {
TypeInformation<PropertyGetter> from = from(PropertyGetter.class); TypeInformation<PropertyGetter> from = TypeInformation.of(PropertyGetter.class);
assertThat(from.getProperty("_name")).satisfies(it -> assertThat(it.getType()).isEqualTo(String.class)); assertThat(from.getProperty("_name")).satisfies(it -> assertThat(it.getType()).isEqualTo(String.class));
assertThat(from.getProperty("name")).satisfies(it -> assertThat(it.getType()).isEqualTo(byte[].class)); assertThat(from.getProperty("name")).satisfies(it -> assertThat(it.getType()).isEqualTo(byte[].class));
@ -166,14 +167,14 @@ public class ClassTypeInformationUnitTests {
@Test // DATACMNS-77 @Test // DATACMNS-77
public void returnsSameInstanceForCachedClass() { public void returnsSameInstanceForCachedClass() {
TypeInformation<PropertyGetter> info = from(PropertyGetter.class); TypeInformation<PropertyGetter> info = TypeInformation.of(PropertyGetter.class);
assertThat(from(PropertyGetter.class)).isSameAs(info); assertThat(TypeInformation.of(PropertyGetter.class)).isSameAs(info);
} }
@Test // DATACMNS-39 @Test // DATACMNS-39
public void resolvesWildCardTypeCorrectly() { public void resolvesWildCardTypeCorrectly() {
TypeInformation<ClassWithWildCardBound> information = from(ClassWithWildCardBound.class); TypeInformation<ClassWithWildCardBound> information = TypeInformation.of(ClassWithWildCardBound.class);
var wildcard = information.getProperty("wildcard"); var wildcard = information.getProperty("wildcard");
@ -192,7 +193,7 @@ public class ClassTypeInformationUnitTests {
@Test @Test
public void resolvesTypeParametersCorrectly() { public void resolvesTypeParametersCorrectly() {
TypeInformation<ConcreteType> information = from(ConcreteType.class); TypeInformation<ConcreteType> information = TypeInformation.of(ConcreteType.class);
var superTypeInformation = information.getSuperTypeInformation(GenericType.class); var superTypeInformation = information.getSuperTypeInformation(GenericType.class);
var parameters = superTypeInformation.getTypeArguments(); var parameters = superTypeInformation.getTypeArguments();
@ -204,7 +205,7 @@ public class ClassTypeInformationUnitTests {
@Test @Test
public void resolvesNestedInheritedTypeParameters() { public void resolvesNestedInheritedTypeParameters() {
TypeInformation<SecondExtension> information = from(SecondExtension.class); TypeInformation<SecondExtension> information = TypeInformation.of(SecondExtension.class);
var superTypeInformation = information.getSuperTypeInformation(Base.class); var superTypeInformation = information.getSuperTypeInformation(Base.class);
var parameters = superTypeInformation.getTypeArguments(); var parameters = superTypeInformation.getTypeArguments();
@ -215,7 +216,7 @@ public class ClassTypeInformationUnitTests {
@Test @Test
public void discoveresMethodParameterTypesCorrectly() throws Exception { public void discoveresMethodParameterTypesCorrectly() throws Exception {
TypeInformation<SecondExtension> information = from(SecondExtension.class); TypeInformation<SecondExtension> information = TypeInformation.of(SecondExtension.class);
var method = SecondExtension.class.getMethod("foo", Base.class); var method = SecondExtension.class.getMethod("foo", Base.class);
var informations = information.getParameterTypes(method); var informations = information.getParameterTypes(method);
var returnTypeInformation = information.getReturnType(method); var returnTypeInformation = information.getReturnType(method);
@ -228,51 +229,54 @@ public class ClassTypeInformationUnitTests {
@Test @Test
public void discoversImplementationBindingCorrectlyForString() throws Exception { public void discoversImplementationBindingCorrectlyForString() throws Exception {
TypeInformation<TypedClient> information = from(TypedClient.class); TypeInformation<TypedClient> information = TypeInformation.of(TypedClient.class);
var method = TypedClient.class.getMethod("stringMethod", GenericInterface.class); var method = TypedClient.class.getMethod("stringMethod", GenericInterface.class);
var parameterType = information.getParameterTypes(method).get(0); var parameterType = information.getParameterTypes(method).get(0);
TypeInformation<StringImplementation> stringInfo = from(StringImplementation.class); TypeInformation<StringImplementation> stringInfo = TypeInformation.of(StringImplementation.class);
assertThat(parameterType.isAssignableFrom(stringInfo)).isTrue(); assertThat(parameterType.isAssignableFrom(stringInfo)).isTrue();
assertThat(stringInfo.getSuperTypeInformation(GenericInterface.class)).isEqualTo(parameterType); assertThat(stringInfo.getSuperTypeInformation(GenericInterface.class)).isEqualTo(parameterType);
assertThat(parameterType.isAssignableFrom(from(LongImplementation.class))).isFalse(); assertThat(parameterType.isAssignableFrom(TypeInformation.of(LongImplementation.class))).isFalse();
assertThat(parameterType assertThat(parameterType
.isAssignableFrom(from(StringImplementation.class).getSuperTypeInformation(GenericInterface.class))).isTrue(); .isAssignableFrom(
TypeInformation.of(StringImplementation.class).getSuperTypeInformation(GenericInterface.class))).isTrue();
} }
@Test @Test
public void discoversImplementationBindingCorrectlyForLong() throws Exception { public void discoversImplementationBindingCorrectlyForLong() throws Exception {
TypeInformation<TypedClient> information = from(TypedClient.class); TypeInformation<TypedClient> information = TypeInformation.of(TypedClient.class);
var method = TypedClient.class.getMethod("longMethod", GenericInterface.class); var method = TypedClient.class.getMethod("longMethod", GenericInterface.class);
var parameterType = information.getParameterTypes(method).get(0); var parameterType = information.getParameterTypes(method).get(0);
assertThat(parameterType.isAssignableFrom(from(StringImplementation.class))).isFalse(); assertThat(parameterType.isAssignableFrom(TypeInformation.of(StringImplementation.class))).isFalse();
assertThat(parameterType.isAssignableFrom(from(LongImplementation.class))).isTrue(); assertThat(parameterType.isAssignableFrom(TypeInformation.of(LongImplementation.class))).isTrue();
assertThat(parameterType assertThat(parameterType
.isAssignableFrom(from(StringImplementation.class).getSuperTypeInformation(GenericInterface.class))).isFalse(); .isAssignableFrom(
TypeInformation.of(StringImplementation.class).getSuperTypeInformation(GenericInterface.class))).isFalse();
} }
@Test @Test
public void discoversImplementationBindingCorrectlyForNumber() throws Exception { public void discoversImplementationBindingCorrectlyForNumber() throws Exception {
TypeInformation<TypedClient> information = from(TypedClient.class); TypeInformation<TypedClient> information = TypeInformation.of(TypedClient.class);
var method = TypedClient.class.getMethod("boundToNumberMethod", GenericInterface.class); var method = TypedClient.class.getMethod("boundToNumberMethod", GenericInterface.class);
var parameterType = information.getParameterTypes(method).get(0); var parameterType = information.getParameterTypes(method).get(0);
assertThat(parameterType.isAssignableFrom(from(StringImplementation.class))).isFalse(); assertThat(parameterType.isAssignableFrom(TypeInformation.of(StringImplementation.class))).isFalse();
assertThat(parameterType.isAssignableFrom(from(LongImplementation.class))).isTrue(); assertThat(parameterType.isAssignableFrom(TypeInformation.of(LongImplementation.class))).isTrue();
assertThat(parameterType assertThat(parameterType
.isAssignableFrom(from(StringImplementation.class).getSuperTypeInformation(GenericInterface.class))).isFalse(); .isAssignableFrom(
TypeInformation.of(StringImplementation.class).getSuperTypeInformation(GenericInterface.class))).isFalse();
} }
@Test @Test
public void returnsComponentTypeForMultiDimensionalArrayCorrectly() { public void returnsComponentTypeForMultiDimensionalArrayCorrectly() {
TypeInformation<?> information = from(String[][].class); TypeInformation<?> information = TypeInformation.of(String[][].class);
assertThat(information.getType()).isEqualTo(String[][].class); assertThat(information.getType()).isEqualTo(String[][].class);
assertThat(information.getComponentType()).satisfies(it -> assertThat(it.getType()).isEqualTo(String[].class)); assertThat(information.getComponentType()).satisfies(it -> assertThat(it.getType()).isEqualTo(String[].class));
@ -282,27 +286,32 @@ public class ClassTypeInformationUnitTests {
@Test // DATACMNS-309 @Test // DATACMNS-309
public void findsGetterOnInterface() { public void findsGetterOnInterface() {
TypeInformation<Product> information = from(Product.class); TypeInformation<Product> information = TypeInformation.of(Product.class);
assertThat(information.getProperty("category.id")).isEqualTo(from(Long.class)); assertThat(information.getProperty("category.id")).isEqualTo(TypeInformation.of(Long.class));
} }
@Test // DATACMNS-387 @Test // DATACMNS-387
public void rejectsNullClass() { public void rejectsNullClass() {
assertThatIllegalArgumentException().isThrownBy(() -> ClassTypeInformation.from(null)); assertThatIllegalArgumentException().isThrownBy(() -> TypeInformation.of((Class<?>) null));
}
@Test // DATACMNS-387
public void rejectsNullResolvableType() {
assertThatIllegalArgumentException().isThrownBy(() -> TypeInformation.of((ResolvableType) null));
} }
@Test // DATACMNS-422 @Test // DATACMNS-422
public void returnsEmptyOptionalForRawTypesOnly() { public void returnsEmptyOptionalForRawTypesOnly() {
assertThat(from(MyRawIterable.class).getComponentType()).isNull(); assertThat(TypeInformation.of(MyRawIterable.class).getComponentType()).isNull();
assertThat(from(MyIterable.class).getComponentType()).isNotNull(); assertThat(TypeInformation.of(MyIterable.class).getComponentType()).isNotNull();
} }
@Test // DATACMNS-440 @Test // DATACMNS-440
public void detectsSpecialMapAsMapValueType() { public void detectsSpecialMapAsMapValueType() {
var seriously = from(SuperGenerics.class).getProperty("seriously"); var seriously = TypeInformation.of(SuperGenerics.class).getProperty("seriously");
// Type // Type
assertThat(seriously.getType()).isEqualTo(SortedMap.class); assertThat(seriously.getType()).isEqualTo(SortedMap.class);
@ -321,14 +330,14 @@ public class ClassTypeInformationUnitTests {
@Test // DATACMNS-446 @Test // DATACMNS-446
public void createsToStringRepresentation() { public void createsToStringRepresentation() {
assertThat(from(SpecialPerson.class).toString()) assertThat(TypeInformation.of(SpecialPerson.class).toString())
.isEqualTo("org.springframework.data.util.ClassTypeInformationUnitTests$SpecialPerson"); .isEqualTo("org.springframework.data.util.ClassTypeInformationUnitTests$SpecialPerson");
} }
@Test // DATACMNS-590 @Test // DATACMNS-590
public void resolvesNestedGenericsToConcreteType() { public void resolvesNestedGenericsToConcreteType() {
var rootType = from(ConcreteRoot.class); var rootType = TypeInformation.of(ConcreteRoot.class);
assertThat(rootType.getProperty("subs").getActualType().getProperty("subSub").getType())// assertThat(rootType.getProperty("subs").getActualType().getProperty("subSub").getType())//
.isEqualTo(ConcreteSubSub.class); .isEqualTo(ConcreteSubSub.class);
@ -337,7 +346,7 @@ public class ClassTypeInformationUnitTests {
@Test // DATACMNS-594 @Test // DATACMNS-594
public void considersGenericsOfTypeBounds() { public void considersGenericsOfTypeBounds() {
assertThat(from(ConcreteRootIntermediate.class) assertThat(TypeInformation.of(ConcreteRootIntermediate.class)
.getProperty("intermediate.content.intermediate.content").getType())// .getProperty("intermediate.content.intermediate.content").getType())//
.isEqualTo(Leaf.class); .isEqualTo(Leaf.class);
} }
@ -345,21 +354,21 @@ public class ClassTypeInformationUnitTests {
@Test // DATACMNS-783, DATACMNS-853 @Test // DATACMNS-783, DATACMNS-853
public void specializesTypeUsingTypeVariableContext() { public void specializesTypeUsingTypeVariableContext() {
var root = from(Foo.class); var root = TypeInformation.of(Foo.class);
assertThat(root.getProperty("abstractBar").specialize(from(Bar.class)))// assertThat(root.getProperty("abstractBar").specialize(TypeInformation.of(Bar.class)))//
.satisfies(it -> { .satisfies(it -> {
assertThat(it.getType()).isEqualTo(Bar.class); assertThat(it.getType()).isEqualTo(Bar.class);
assertThat(it.getProperty("field").getType()).isEqualTo(Character.class); assertThat(it.getProperty("field").getType()).isEqualTo(Character.class);
assertThat(it.getProperty("anotherField").getType()).isEqualTo(Integer.class); assertThat(it.getProperty("anotherField").getType()).isEqualTo(Integer.class);
}); });
} }
@Test // DATACMNS-783 @Test // DATACMNS-783
public void usesTargetTypeDirectlyIfNoGenericsAreInvolved() { public void usesTargetTypeDirectlyIfNoGenericsAreInvolved() {
var root = ClassTypeInformation.from(Foo.class); var root = TypeInformation.of(Foo.class);
ClassTypeInformation<?> from = ClassTypeInformation.from(Bar.class); TypeInformation<?> from = TypeInformation.of(Bar.class);
assertThat(root.getProperty("object").specialize(from)).isEqualTo(from); assertThat(root.getProperty("object").specialize(from)).isEqualTo(from);
} }
@ -367,12 +376,12 @@ public class ClassTypeInformationUnitTests {
@Test // DATACMNS-855 @Test // DATACMNS-855
public void specializedTypeEqualsAndHashCode() { public void specializedTypeEqualsAndHashCode() {
var root = ClassTypeInformation.from(Foo.class); var root = TypeInformation.of(Foo.class);
var abstractBar = root.getProperty("abstractBar"); var abstractBar = root.getProperty("abstractBar");
assertThat(Pair.of(abstractBar.specialize(ClassTypeInformation.from(Bar.class)), assertThat(Pair.of(abstractBar.specialize(TypeInformation.of(Bar.class)),
abstractBar.specialize(ClassTypeInformation.from(Bar.class)))).satisfies(pair -> { abstractBar.specialize(TypeInformation.of(Bar.class)))).satisfies(pair -> {
assertThat(pair.getFirst()).isEqualTo(pair.getSecond()); assertThat(pair.getFirst()).isEqualTo(pair.getSecond());
assertThat(pair.getSecond()).isEqualTo(pair.getFirst()); assertThat(pair.getSecond()).isEqualTo(pair.getFirst());
assertThat(pair.getFirst().hashCode()).isEqualTo(pair.getSecond().hashCode()); assertThat(pair.getFirst().hashCode()).isEqualTo(pair.getSecond().hashCode());
@ -382,7 +391,7 @@ public class ClassTypeInformationUnitTests {
@Test // DATACMNS-896 @Test // DATACMNS-896
public void prefersLocalTypeMappingOverNestedWithSameGenericType() { public void prefersLocalTypeMappingOverNestedWithSameGenericType() {
var information = from(Concrete.class); var information = TypeInformation.of(Concrete.class);
assertThat(information.getProperty("field").getType()).isEqualTo(Nested.class); assertThat(information.getProperty("field").getType()).isEqualTo(Nested.class);
} }
@ -390,7 +399,7 @@ public class ClassTypeInformationUnitTests {
@Test // DATACMNS-940 @Test // DATACMNS-940
public void detectsVavrTraversableComponentType() { public void detectsVavrTraversableComponentType() {
var information = from(SampleTraversable.class); var information = TypeInformation.of(SampleTraversable.class);
assertThat(information.getComponentType().getType()).isAssignableFrom(Integer.class); assertThat(information.getComponentType().getType()).isAssignableFrom(Integer.class);
} }
@ -398,7 +407,7 @@ public class ClassTypeInformationUnitTests {
@Test // DATACMNS-940 @Test // DATACMNS-940
public void detectsVavrMapComponentAndValueType() { public void detectsVavrMapComponentAndValueType() {
var information = from(SampleMap.class); var information = TypeInformation.of(SampleMap.class);
assertThat(information.getComponentType().getType()).isAssignableFrom(String.class); assertThat(information.getComponentType().getType()).isAssignableFrom(String.class);
@ -408,8 +417,8 @@ public class ClassTypeInformationUnitTests {
@Test // DATACMNS-1138 @Test // DATACMNS-1138
public void usesTargetTypeForWildcardedBaseOnSpecialization() { public void usesTargetTypeForWildcardedBaseOnSpecialization() {
var wrapper = from(WildcardedWrapper.class); var wrapper = TypeInformation.of(WildcardedWrapper.class);
var concrete = from(SomeConcrete.class); var concrete = TypeInformation.of(SomeConcrete.class);
var property = wrapper.getRequiredProperty("wildcarded"); var property = wrapper.getRequiredProperty("wildcarded");
@ -419,14 +428,14 @@ public class ClassTypeInformationUnitTests {
@Test // DATACMNS-1571 @Test // DATACMNS-1571
public void considersGenericsOfTypeToSpecializeToIfFullyResolved() { public void considersGenericsOfTypeToSpecializeToIfFullyResolved() {
TypeInformation<StoredEvent> storeEvent = ClassTypeInformation.from(StoredEvent.class); TypeInformation<StoredEvent> storeEvent = TypeInformation.of(StoredEvent.class);
assertThat(storeEvent.getType()).isEqualTo(StoredEvent.class); assertThat(storeEvent.getType()).isEqualTo(StoredEvent.class);
var domainEvent = (TypeInformation<DomainEvent>) storeEvent.getProperty("event"); var domainEvent = (TypeInformation<DomainEvent>) storeEvent.getProperty("event");
assertThat(domainEvent.getType()).isEqualTo(DomainEvent.class); assertThat(domainEvent.getType()).isEqualTo(DomainEvent.class);
var specialized = domainEvent var specialized = domainEvent
.specialize(ClassTypeInformation.from(OfferCreated.class)); .specialize(TypeInformation.of(OfferCreated.class));
assertThat(specialized.getType()).isEqualTo(OfferCreated.class); assertThat(specialized.getType()).isEqualTo(OfferCreated.class);
assertThat(specialized.getProperty("aggregateId").getType()).isEqualTo(Long.class); assertThat(specialized.getProperty("aggregateId").getType()).isEqualTo(Long.class);
@ -436,14 +445,14 @@ public class ClassTypeInformationUnitTests {
@Test // DATACMNS-1571 @Test // DATACMNS-1571
public void mergesGenericsFromContextAndProvidedDefaultOnSpecialization() { public void mergesGenericsFromContextAndProvidedDefaultOnSpecialization() {
TypeInformation<StoredEvent> storeEvent = ClassTypeInformation.from(StoredEvent.class); TypeInformation<StoredEvent> storeEvent = TypeInformation.of(StoredEvent.class);
assertThat(storeEvent.getType()).isEqualTo(StoredEvent.class); assertThat(storeEvent.getType()).isEqualTo(StoredEvent.class);
var domainEvent = (TypeInformation<DomainEvent>) storeEvent.getProperty("event"); var domainEvent = (TypeInformation<DomainEvent>) storeEvent.getProperty("event");
assertThat(domainEvent.getType()).isEqualTo(DomainEvent.class); assertThat(domainEvent.getType()).isEqualTo(DomainEvent.class);
var specialized = domainEvent var specialized = domainEvent
.specialize(ClassTypeInformation.from(GenericEvent.class)); .specialize(TypeInformation.of(GenericEvent.class));
assertThat(specialized.getType()).isEqualTo(GenericEvent.class); assertThat(specialized.getType()).isEqualTo(GenericEvent.class);
assertThat(specialized.getProperty("aggregateId").getType()).isEqualTo(Long.class); assertThat(specialized.getProperty("aggregateId").getType()).isEqualTo(Long.class);
@ -453,7 +462,7 @@ public class ClassTypeInformationUnitTests {
@Test // DATACMNS-1828 @Test // DATACMNS-1828
void discoversMapKeyAndValueTypeFromTypedMap() { void discoversMapKeyAndValueTypeFromTypedMap() {
TypeInformation<TypeWithTypedMap> information = from(TypeWithTypedMap.class); TypeInformation<TypeWithTypedMap> information = TypeInformation.of(TypeWithTypedMap.class);
var typedMap = information.getProperty("typedMap"); var typedMap = information.getProperty("typedMap");
@ -477,20 +486,21 @@ public class ClassTypeInformationUnitTests {
} }
@Test // GH-2485 @Test // GH-2485
public void proxyTypeInformationShouldNotEqualUserClassTypeInfo () { public void proxyTypeInformationShouldNotEqualUserClassTypeInfo() {
ClassTypeInformation<Leaf> typeInfoLeaf = from(Leaf.class); var typeInfoLeaf = TypeInformation.of(Leaf.class);
ClassTypeInformation<Leaf$$SpringProxy$873fa2e> typeInformationLeafProxy = from(Leaf$$SpringProxy$873fa2e.class); var typeInformationLeafProxy = TypeInformation
.of(Leaf$$SpringProxy$873fa2e.class);
assertThat(typeInfoLeaf).isNotEqualTo(typeInformationLeafProxy); assertThat(typeInfoLeaf).isNotEqualTo(typeInformationLeafProxy);
} }
@Test // GH-2312 @Test // GH-2312
void typeInfoShouldPreserveGenericParameter() { void typeInfoShouldPreserveGenericParameter() {
TypeInformation<Wrapper> wrapperTypeInfo = ClassTypeInformation.from(Wrapper.class); var wrapperTypeInfo = TypeInformation.of(Wrapper.class);
TypeInformation<?> fieldTypeInfo = wrapperTypeInfo.getProperty("field"); var fieldTypeInfo = wrapperTypeInfo.getProperty("field");
TypeInformation<?> valueTypeInfo = fieldTypeInfo.getProperty("value"); var valueTypeInfo = fieldTypeInfo.getProperty("value");
assertThat(valueTypeInfo.getType()).isEqualTo(Leaf.class); assertThat(valueTypeInfo.getType()).isEqualTo(Leaf.class);
} }
@ -706,7 +716,7 @@ public class ClassTypeInformationUnitTests {
static class SomeConcrete extends SomeGeneric<String> {} static class SomeConcrete extends SomeGeneric<String> {}
static class GenericExtendingSomeGeneric<T> extends SomeGeneric<T> { } static class GenericExtendingSomeGeneric<T> extends SomeGeneric<T> {}
static class Wrapper { static class Wrapper {
GenericExtendingSomeGeneric<Leaf> field; GenericExtendingSomeGeneric<Leaf> field;

2
src/test/java/org/springframework/data/util/DataCmns511Tests.java

@ -33,7 +33,7 @@ public class DataCmns511Tests {
@Test // DATACMNS-511 @Test // DATACMNS-511
public void detectsEqualTypeVariableTypeInformationInstances() { public void detectsEqualTypeVariableTypeInformationInstances() {
var createdBy = ClassTypeInformation.from(AbstractRole.class).getProperty("createdBy"); var createdBy = TypeInformation.of(AbstractRole.class).getProperty("createdBy");
assertThat(createdBy.getProperty("roles").getActualType().getProperty("createdBy"))// assertThat(createdBy.getProperty("roles").getActualType().getProperty("createdBy"))//
.satisfies(second -> { .satisfies(second -> {

190
src/test/java/org/springframework/data/util/TypeDiscovererUnitTests.java

@ -16,13 +16,10 @@
package org.springframework.data.util; package org.springframework.data.util;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.util.ClassTypeInformation.from;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.EnumMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -31,8 +28,8 @@ import java.util.Set;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.core.ResolvableType; import org.springframework.core.ResolvableType;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
@ -45,11 +42,6 @@ import org.springframework.util.ReflectionUtils;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
public class TypeDiscovererUnitTests { public class TypeDiscovererUnitTests {
private static final Map<TypeVariable<?>, Type> EMPTY_MAP = Collections.emptyMap();
@Mock Map<TypeVariable<?>, Type> firstMap;
@Mock Map<TypeVariable<?>, Type> secondMap;
@Test @Test
void rejectsNullType() { void rejectsNullType() {
assertThatIllegalArgumentException().isThrownBy(() -> new TypeDiscoverer<>((ResolvableType) null)); assertThatIllegalArgumentException().isThrownBy(() -> new TypeDiscoverer<>((ResolvableType) null));
@ -58,27 +50,17 @@ public class TypeDiscovererUnitTests {
@Test @Test
void isNotEqualIfTypesDiffer() { void isNotEqualIfTypesDiffer() {
var objectTypeInfo = new TypeDiscoverer<Object>(Object.class); var objectTypeInfo = TypeInformation.of(Object.class);
var stringTypeInfo = new TypeDiscoverer<String>(String.class); var stringTypeInfo = TypeInformation.of(String.class);
assertThat(objectTypeInfo.equals(stringTypeInfo)).isFalse(); assertThat(objectTypeInfo.equals(stringTypeInfo)).isFalse();
} }
// @Test
// void isNotEqualIfTypeVariableMapsDiffer() {
//
// assertThat(firstMap.equals(secondMap)).isFalse();
//
// var first = new TypeDiscoverer<Object>(Object.class);
// var second = new TypeDiscoverer<Object>(Object.class);
//
// assertThat(first.equals(second)).isFalse();
// }
@Test @Test
void dealsWithTypesReferencingThemselves() { void dealsWithTypesReferencingThemselves() {
TypeInformation<SelfReferencing> information = from(SelfReferencing.class); var information = TypeInformation.of(SelfReferencing.class);
var first = information.getProperty("parent").getMapValueType(); var first = information.getProperty("parent").getMapValueType();
var second = first.getProperty("map").getMapValueType(); var second = first.getProperty("map").getMapValueType();
@ -88,7 +70,7 @@ public class TypeDiscovererUnitTests {
@Test @Test
void dealsWithTypesReferencingThemselvesInAMap() { void dealsWithTypesReferencingThemselvesInAMap() {
TypeInformation<SelfReferencingMap> information = from(SelfReferencingMap.class); var information = TypeInformation.of(SelfReferencingMap.class);
var property = information.getProperty("map"); var property = information.getProperty("map");
assertThat(property.getMapValueType()).isEqualTo(information); assertThat(property.getMapValueType()).isEqualTo(information);
@ -97,7 +79,7 @@ public class TypeDiscovererUnitTests {
@Test @Test
void returnsComponentAndValueTypesForMapExtensions() { void returnsComponentAndValueTypesForMapExtensions() {
TypeInformation<?> discoverer = new TypeDiscoverer<>(CustomMap.class); TypeInformation<?> discoverer = TypeInformation.of(CustomMap.class);
assertThat(discoverer.getMapValueType().getType()).isEqualTo(Locale.class); assertThat(discoverer.getMapValueType().getType()).isEqualTo(Locale.class);
assertThat(discoverer.getComponentType().getType()).isEqualTo(String.class); assertThat(discoverer.getComponentType().getType()).isEqualTo(String.class);
@ -106,7 +88,7 @@ public class TypeDiscovererUnitTests {
@Test @Test
void returnsComponentTypeForCollectionExtension() { void returnsComponentTypeForCollectionExtension() {
var discoverer = new TypeDiscoverer<CustomCollection>(CustomCollection.class); var discoverer = TypeInformation.of(CustomCollection.class);
assertThat(discoverer.getComponentType().getType()).isEqualTo(String.class); assertThat(discoverer.getComponentType().getType()).isEqualTo(String.class);
} }
@ -114,7 +96,7 @@ public class TypeDiscovererUnitTests {
@Test @Test
void returnsComponentTypeForArrays() { void returnsComponentTypeForArrays() {
var discoverer = new TypeDiscoverer<String[]>(String[].class); var discoverer = TypeInformation.of(String[].class);
assertThat(discoverer.getComponentType().getType()).isEqualTo(String.class); assertThat(discoverer.getComponentType().getType()).isEqualTo(String.class);
} }
@ -122,7 +104,7 @@ public class TypeDiscovererUnitTests {
@Test // DATACMNS-57 @Test // DATACMNS-57
void discoveresConstructorParameterTypesCorrectly() throws NoSuchMethodException, SecurityException { void discoveresConstructorParameterTypesCorrectly() throws NoSuchMethodException, SecurityException {
var discoverer = new TypeDiscoverer<GenericConstructors>(GenericConstructors.class); var discoverer = TypeInformation.of(GenericConstructors.class);
var constructor = GenericConstructors.class.getConstructor(List.class, Locale.class); var constructor = GenericConstructors.class.getConstructor(List.class, Locale.class);
var types = discoverer.getParameterTypes(constructor); var types = discoverer.getParameterTypes(constructor);
@ -135,7 +117,7 @@ public class TypeDiscovererUnitTests {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
void returnsNullForComponentAndValueTypesForRawMaps() { void returnsNullForComponentAndValueTypesForRawMaps() {
var discoverer = new TypeDiscoverer<Map>(Map.class); var discoverer = TypeInformation.of(Map.class);
assertThat(discoverer.getComponentType()).isNotNull(); assertThat(discoverer.getComponentType()).isNotNull();
assertThat(discoverer.getMapValueType()).isNotNull(); assertThat(discoverer.getMapValueType()).isNotNull();
@ -145,8 +127,8 @@ public class TypeDiscovererUnitTests {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
void doesNotConsiderTypeImplementingIterableACollection() { void doesNotConsiderTypeImplementingIterableACollection() {
var discoverer = new TypeDiscoverer<Person>(Person.class); var discoverer = TypeInformation.of(Person.class);
TypeInformation reference = from(Address.class); TypeInformation reference = TypeInformation.of(Address.class);
var addresses = discoverer.getProperty("addresses"); var addresses = discoverer.getProperty("addresses");
@ -166,7 +148,7 @@ public class TypeDiscovererUnitTests {
@Test // DATACMNS-1342, DATACMNS-1430 @Test // DATACMNS-1342, DATACMNS-1430
void considersStreamableToBeCollectionLike() { void considersStreamableToBeCollectionLike() {
TypeInformation<SomeStreamable> type = from(SomeStreamable.class); TypeInformation<SomeStreamable> type = TypeInformation.of(SomeStreamable.class);
assertThat(type.isCollectionLike()).isTrue(); assertThat(type.isCollectionLike()).isTrue();
assertThat(type.getRequiredProperty("streamable").isCollectionLike()).isTrue(); assertThat(type.getRequiredProperty("streamable").isCollectionLike()).isTrue();
@ -175,7 +157,7 @@ public class TypeDiscovererUnitTests {
@Test // DATACMNS-1419 @Test // DATACMNS-1419
void detectsSubTypes() { void detectsSubTypes() {
var type = from(Set.class); var type = TypeInformation.of(Set.class);
assertThat(type.isSubTypeOf(Collection.class)).isTrue(); assertThat(type.isSubTypeOf(Collection.class)).isTrue();
assertThat(type.isSubTypeOf(Set.class)).isFalse(); assertThat(type.isSubTypeOf(Set.class)).isFalse();
@ -196,124 +178,115 @@ public class TypeDiscovererUnitTests {
} }
@Test @Test // GH-2312
// GH-2312
void sameFieldNoGenericsInfoShouldBeEqual() { void sameFieldNoGenericsInfoShouldBeEqual() {
Field addresses = ReflectionUtils.findField(Person.class, "addresses"); var addresses = ReflectionUtils.findField(Person.class, "addresses");
TypeDiscoverer<Object> discoverer1 = new TypeDiscoverer<>(ResolvableType.forField(addresses, Person.class)); var discoverer1 = TypeInformation.of(ResolvableType.forField(addresses, Person.class));
TypeDiscoverer<Object> discoverer2 = new TypeDiscoverer<>(ResolvableType.forField(addresses, Person.class)); var discoverer2 = TypeInformation.of(ResolvableType.forField(addresses, Person.class));
assertThat(discoverer1).isEqualTo(discoverer2); assertThat(discoverer1).isEqualTo(discoverer2);
assertThat(discoverer1.hashCode()).isEqualTo(discoverer2.hashCode()); assertThat(discoverer1.hashCode()).isEqualTo(discoverer2.hashCode());
} }
@Test @Test // GH-2312
// GH-2312
void sameFieldNoGenericsWhenInherited() { void sameFieldNoGenericsWhenInherited() {
Field addresses = ReflectionUtils.findField(Person.class, "addresses"); var addresses = ReflectionUtils.findField(Person.class, "addresses");
TypeDiscoverer<Object> discoverer1 = new TypeDiscoverer<>(ResolvableType.forField(addresses, Person.class));
TypeDiscoverer<Object> discoverer2 = new TypeDiscoverer<>(ResolvableType.forField(addresses, TypeExtendingPerson.class)); var discoverer1 = TypeInformation.of(ResolvableType.forField(addresses, Person.class));
var discoverer2 = TypeInformation.of(ResolvableType.forField(addresses, TypeExtendingPerson.class));
assertThat(discoverer1).isEqualTo(discoverer2); assertThat(discoverer1).isEqualTo(discoverer2);
assertThat(discoverer1.hashCode()).isEqualTo(discoverer2.hashCode()); assertThat(discoverer1.hashCode()).isEqualTo(discoverer2.hashCode());
} }
@Test @Test // GH-2312
// GH-2312
void sameFieldNoGenericsOnDifferentTypes() { void sameFieldNoGenericsOnDifferentTypes() {
Field addresses1 = ReflectionUtils.findField(Person.class, "addresses"); var addresses1 = ReflectionUtils.findField(Person.class, "addresses");
TypeDiscoverer<Object> discoverer1 = new TypeDiscoverer<>(ResolvableType.forField(addresses1, Person.class)); var discoverer1 = TypeInformation.of(ResolvableType.forField(addresses1, Person.class));
Field addresses2 = ReflectionUtils.findField(OtherPerson.class, "addresses"); var addresses2 = ReflectionUtils.findField(OtherPerson.class, "addresses");
TypeDiscoverer<Object> discoverer2 = new TypeDiscoverer<>(ResolvableType.forField(addresses2, OtherPerson.class)); var discoverer2 = TypeInformation.of(ResolvableType.forField(addresses2, OtherPerson.class));
assertThat(discoverer1).isEqualTo(discoverer2); assertThat(discoverer1).isEqualTo(discoverer2);
assertThat(discoverer1.hashCode()).isEqualTo(discoverer2.hashCode()); assertThat(discoverer1.hashCode()).isEqualTo(discoverer2.hashCode());
} }
@Test @Test // GH-2312
// GH-2312
void sameFieldWithGenerics() { void sameFieldWithGenerics() {
Field field1 = ReflectionUtils.findField(GenericPerson.class, "value"); var field1 = ReflectionUtils.findField(GenericPerson.class, "value");
TypeDiscoverer<Object> discoverer1 = new TypeDiscoverer<>(ResolvableType.forField(field1, GenericPerson.class)); var discoverer1 = TypeInformation.of(ResolvableType.forField(field1, GenericPerson.class));
Field field2 = ReflectionUtils.findField(GenericPerson.class, "value"); var field2 = ReflectionUtils.findField(GenericPerson.class, "value");
TypeDiscoverer<Object> discoverer2 = new TypeDiscoverer<>(ResolvableType.forField(field2, GenericPerson.class)); var discoverer2 = TypeInformation.of(ResolvableType.forField(field2, GenericPerson.class));
assertThat(discoverer1).isEqualTo(discoverer2); assertThat(discoverer1).isEqualTo(discoverer2);
assertThat(discoverer1.hashCode()).isEqualTo(discoverer2.hashCode()); assertThat(discoverer1.hashCode()).isEqualTo(discoverer2.hashCode());
} }
@Test @Test // GH-2312
// GH-2312
void sameFieldWithGenericsSet() { void sameFieldWithGenericsSet() {
Field field1 = ReflectionUtils.findField(GenericPerson.class, "value"); var field1 = ReflectionUtils.findField(GenericPerson.class, "value");
TypeDiscoverer<Object> discoverer1 = new TypeDiscoverer<>(ResolvableType.forField(field1, TypeExtendingGenericPersonWithObject.class)); var discoverer1 = TypeInformation.of(ResolvableType.forField(field1, TypeExtendingGenericPersonWithObject.class));
Field field2 = ReflectionUtils.findField(GenericPerson.class, "value"); var field2 = ReflectionUtils.findField(GenericPerson.class, "value");
TypeDiscoverer<Object> discoverer2 = new TypeDiscoverer<>(ResolvableType.forField(field2, TypeExtendingGenericPersonWithObject.class)); var discoverer2 = TypeInformation.of(ResolvableType.forField(field2, TypeExtendingGenericPersonWithObject.class));
assertThat(discoverer1).isEqualTo(discoverer2); assertThat(discoverer1).isEqualTo(discoverer2);
assertThat(discoverer1.hashCode()).isEqualTo(discoverer2.hashCode()); assertThat(discoverer1.hashCode()).isEqualTo(discoverer2.hashCode());
} }
@Test @Test // GH-2312
// GH-2312
void sameFieldWithDifferentGenericsSet() { void sameFieldWithDifferentGenericsSet() {
Field field1 = ReflectionUtils.findField(GenericPerson.class, "value"); var field1 = ReflectionUtils.findField(GenericPerson.class, "value");
TypeDiscoverer<Object> discoverer1 = new TypeDiscoverer<>(ResolvableType.forField(field1, TypeExtendingGenericPersonWithObject.class)); var discoverer1 = TypeInformation.of(ResolvableType.forField(field1, TypeExtendingGenericPersonWithObject.class));
Field field2 = ReflectionUtils.findField(GenericPerson.class, "value"); var field2 = ReflectionUtils.findField(GenericPerson.class, "value");
TypeDiscoverer<Object> discoverer2 = new TypeDiscoverer<>(ResolvableType.forField(field2, TypeExtendingGenericPersonWithAddress.class)); var discoverer2 = TypeInformation.of(ResolvableType.forField(field2, TypeExtendingGenericPersonWithAddress.class));
assertThat(discoverer1).isNotEqualTo(discoverer2); assertThat(discoverer1).isNotEqualTo(discoverer2);
assertThat(discoverer1.hashCode()).isNotEqualTo(discoverer2.hashCode()); assertThat(discoverer1.hashCode()).isNotEqualTo(discoverer2.hashCode());
} }
@Test @Test // GH-2312
// GH-2312
void sameFieldWithDifferentNoGenericsAndObjectOneSet() { void sameFieldWithDifferentNoGenericsAndObjectOneSet() {
Field field1 = ReflectionUtils.findField(GenericPerson.class, "value"); var field1 = ReflectionUtils.findField(GenericPerson.class, "value");
TypeDiscoverer<Object> discoverer1 = new TypeDiscoverer<>(ResolvableType.forField(field1, GenericPerson.class)); var discoverer1 = TypeInformation.of(ResolvableType.forField(field1, GenericPerson.class));
Field field2 = ReflectionUtils.findField(GenericPerson.class, "value"); var field2 = ReflectionUtils.findField(GenericPerson.class, "value");
TypeDiscoverer<Object> discoverer2 = new TypeDiscoverer<>(ResolvableType.forField(field2, TypeExtendingGenericPersonWithObject.class)); var discoverer2 = TypeInformation.of(ResolvableType.forField(field2, TypeExtendingGenericPersonWithObject.class));
assertThat(discoverer1).isEqualTo(discoverer2); // TODO: notEquals assertThat(discoverer1).isEqualTo(discoverer2); // TODO: notEquals
assertThat(discoverer1.hashCode()).isEqualTo(discoverer2.hashCode()); assertThat(discoverer1.hashCode()).isEqualTo(discoverer2.hashCode());
} }
@Test @Test // GH-2312
// GH-2312
void genericFieldOfType() { void genericFieldOfType() {
Field field = ReflectionUtils.findField(GenericPerson.class, "value"); var field = ReflectionUtils.findField(GenericPerson.class, "value");
TypeDiscoverer<Object> discoverer = new TypeDiscoverer<>(ResolvableType.forField(field, TypeExtendingGenericPersonWithAddress.class)); var discoverer = TypeInformation.of(ResolvableType.forField(field, TypeExtendingGenericPersonWithAddress.class));
assertThat(discoverer).isEqualTo(ClassTypeInformation.from(Address.class)); assertThat(discoverer).isEqualTo(TypeInformation.of(Address.class));
assertThat(discoverer.hashCode()).isEqualTo(ClassTypeInformation.from(Address.class).hashCode()); assertThat(discoverer.hashCode()).isEqualTo(TypeInformation.of(Address.class).hashCode());
} }
@Test // #2511 @Test // #2511
void considerVavrMapToBeAMap() { void considerVavrMapToBeAMap() {
var type = from(io.vavr.collection.Map.class); assertThat(TypeInformation.of(io.vavr.collection.Map.class).isMap()).isTrue();
assertThat(type.isMap()).isTrue();
} }
@Test // #2517 @Test // #2517
void returnsComponentAndValueTypesForVavrMapExtensions() { void returnsComponentAndValueTypesForVavrMapExtensions() {
var discoverer = new TypeDiscoverer<>(CustomVavrMap.class); var discoverer = TypeInformation.of(CustomVavrMap.class);
assertThat(discoverer.getMapValueType().getType()).isEqualTo(Locale.class); assertThat(discoverer.getMapValueType().getType()).isEqualTo(Locale.class);
assertThat(discoverer.getComponentType().getType()).isEqualTo(String.class); assertThat(discoverer.getComponentType().getType()).isEqualTo(String.class);
@ -321,26 +294,36 @@ public class TypeDiscovererUnitTests {
@Test // #2511 @Test // #2511
void considerVavrSetToBeCollectionLike() { void considerVavrSetToBeCollectionLike() {
assertThat(TypeInformation.of(io.vavr.collection.Set.class).isCollectionLike()).isTrue();
var type = from(io.vavr.collection.Set.class);
assertThat(type.isCollectionLike()).isTrue();
} }
@Test // #2511 @Test // #2511
void considerVavrSeqToBeCollectionLike() { void considerVavrSeqToBeCollectionLike() {
assertThat(TypeInformation.of(io.vavr.collection.Seq.class).isCollectionLike()).isTrue();
var type = from(io.vavr.collection.Seq.class);
assertThat(type.isCollectionLike()).isTrue();
} }
@Test // #2511 @Test // #2511
void considerVavrListToBeCollectionLike() { void considerVavrListToBeCollectionLike() {
assertThat(TypeInformation.of(io.vavr.collection.List.class).isCollectionLike()).isTrue();
}
var type = from(io.vavr.collection.List.class); @Test
void typeInfoShouldPreserveGenericParameter() {
assertThat(type.isCollectionLike()).isTrue(); TypeInformation<Wrapper> wrapperTypeInfo = TypeInformation.of(Wrapper.class);
TypeInformation<?> fieldTypeInfo = wrapperTypeInfo.getProperty("field");
TypeInformation<?> valueTypeInfo = fieldTypeInfo.getProperty("value");
assertThat(valueTypeInfo.getType()).isEqualTo(Leaf.class);
}
@Test
void detectsMapKeyAndValueOnEnumMaps() {
TypeInformation<?> map = TypeInformation.of(EnumMapWrapper.class).getProperty("map");
assertThat(map.getComponentType().getType()).isEqualTo(Autowire.class);
assertThat(map.getMapValueType().getType()).isEqualTo(String.class);
} }
class Person { class Person {
@ -369,7 +352,6 @@ public class TypeDiscovererUnitTests {
} }
abstract class Addresses implements Iterable<Address> { abstract class Addresses implements Iterable<Address> {
} }
@ -415,4 +397,22 @@ public class TypeDiscovererUnitTests {
} }
interface CustomVavrMap extends io.vavr.collection.Map<String, Locale> {} interface CustomVavrMap extends io.vavr.collection.Map<String, Locale> {}
// #2312
class SomeGeneric<T> {
T value;
}
class GenericExtendingSomeGeneric<T> extends SomeGeneric<T> {}
class Wrapper {
GenericExtendingSomeGeneric<Leaf> field;
}
class Leaf {}
class EnumMapWrapper {
EnumMap<Autowire, String> map;
}
} }

10
src/test/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolverUnitTests.java

@ -16,7 +16,7 @@
package org.springframework.data.web.querydsl; package org.springframework.data.web.querydsl;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.web.querydsl.QuerydslPredicateArgumentResolver.*; import static org.springframework.data.web.querydsl.QuerydslPredicateArgumentResolverSupport.*;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
@ -26,7 +26,6 @@ import java.util.Optional;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AliasFor; import org.springframework.core.annotation.AliasFor;
import org.springframework.core.annotation.MergedAnnotation; import org.springframework.core.annotation.MergedAnnotation;
@ -39,7 +38,6 @@ import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer;
import org.springframework.data.querydsl.binding.QuerydslBindings; import org.springframework.data.querydsl.binding.QuerydslBindings;
import org.springframework.data.querydsl.binding.QuerydslBindingsFactory; import org.springframework.data.querydsl.binding.QuerydslBindingsFactory;
import org.springframework.data.querydsl.binding.QuerydslPredicate; import org.springframework.data.querydsl.binding.QuerydslPredicate;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.EntityModel;
import org.springframework.http.HttpEntity; import org.springframework.http.HttpEntity;
@ -210,15 +208,15 @@ class QuerydslPredicateArgumentResolverUnitTests {
TypeInformation<?> type = ReflectionTestUtils.invokeMethod(resolver, "extractTypeInfo", TypeInformation<?> type = ReflectionTestUtils.invokeMethod(resolver, "extractTypeInfo",
getMethodParameterFor("predicateWithoutAnnotation", Predicate.class), MergedAnnotation.missing()); getMethodParameterFor("predicateWithoutAnnotation", Predicate.class), MergedAnnotation.missing());
assertThat(type).isEqualTo(ClassTypeInformation.from(User.class)); assertThat(type).isEqualTo(TypeInformation.of(User.class));
} }
@Test // DATACMNS-669 @Test // DATACMNS-669
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
void detectsDomainTypesCorrectly() { void detectsDomainTypesCorrectly() {
TypeInformation USER_TYPE = ClassTypeInformation.from(User.class); TypeInformation USER_TYPE = TypeInformation.of(User.class);
TypeInformation MODELA_AND_VIEW_TYPE = ClassTypeInformation.from(ModelAndView.class); TypeInformation MODELA_AND_VIEW_TYPE = TypeInformation.of(ModelAndView.class);
assertThat(extractTypeInfo(getMethodParameterFor("forEntity"), MergedAnnotation.missing())).isEqualTo(USER_TYPE); assertThat(extractTypeInfo(getMethodParameterFor("forEntity"), MergedAnnotation.missing())).isEqualTo(USER_TYPE);
assertThat(extractTypeInfo(getMethodParameterFor("forResourceOfUser"), MergedAnnotation.missing())) assertThat(extractTypeInfo(getMethodParameterFor("forResourceOfUser"), MergedAnnotation.missing()))

Loading…
Cancel
Save