diff --git a/pom.xml b/pom.xml index 6ebe5c9ea..358355750 100644 --- a/pom.xml +++ b/pom.xml @@ -18,6 +18,7 @@ 2.0.4 2.11.7 + 2.1.0-RC.1 1.4.8 diff --git a/src/main/java/org/springframework/data/auditing/AnnotationAuditingMetadata.java b/src/main/java/org/springframework/data/auditing/AnnotationAuditingMetadata.java index db97bdd93..0bd469e04 100644 --- a/src/main/java/org/springframework/data/auditing/AnnotationAuditingMetadata.java +++ b/src/main/java/org/springframework/data/auditing/AnnotationAuditingMetadata.java @@ -60,7 +60,7 @@ final class AnnotationAuditingMetadata { static { - List types = new ArrayList(5); + List types = new ArrayList<>(5); types.add("org.joda.time.DateTime"); types.add("org.joda.time.LocalDateTime"); types.add(Date.class.getName()); diff --git a/src/main/java/org/springframework/data/auditing/MappingAuditableBeanWrapperFactory.java b/src/main/java/org/springframework/data/auditing/MappingAuditableBeanWrapperFactory.java index a04740a82..280ea4997 100644 --- a/src/main/java/org/springframework/data/auditing/MappingAuditableBeanWrapperFactory.java +++ b/src/main/java/org/springframework/data/auditing/MappingAuditableBeanWrapperFactory.java @@ -73,17 +73,16 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap } Class type = it.getClass(); - PersistentEntity entity = entities.getPersistentEntity(type); - if (entity == null) { - return super.getBeanWrapperFor(source); - } + return entities.getPersistentEntity(type).map(entity -> { + + MappingAuditingMetadata metadata = metadataCache.computeIfAbsent(type, + key -> new MappingAuditingMetadata(entity)); - MappingAuditingMetadata metadata = metadataCache.computeIfAbsent(type, - foo -> new MappingAuditingMetadata(entity)); + return Optional.ofNullable(metadata.isAuditable() + ? new MappingMetadataAuditableBeanWrapper(entity.getPropertyAccessor(it), metadata) : null); - return Optional.ofNullable(metadata.isAuditable() - ? new MappingMetadataAuditableBeanWrapper(entity.getPropertyAccessor(it), metadata) : null); + }).orElseGet(() -> super.getBeanWrapperFor(source)); }); } diff --git a/src/main/java/org/springframework/data/config/TypeFilterParser.java b/src/main/java/org/springframework/data/config/TypeFilterParser.java index c7a06ff77..301cb67e8 100644 --- a/src/main/java/org/springframework/data/config/TypeFilterParser.java +++ b/src/main/java/org/springframework/data/config/TypeFilterParser.java @@ -85,7 +85,7 @@ public class TypeFilterParser { public Collection parseTypeFilters(Element element, Type type) { NodeList nodeList = element.getChildNodes(); - Collection filters = new HashSet(); + Collection filters = new HashSet<>(); for (int i = 0; i < nodeList.getLength(); i++) { diff --git a/src/main/java/org/springframework/data/convert/ClassGeneratingEntityInstantiator.java b/src/main/java/org/springframework/data/convert/ClassGeneratingEntityInstantiator.java index f0ff9a3e2..1ad9f278d 100644 --- a/src/main/java/org/springframework/data/convert/ClassGeneratingEntityInstantiator.java +++ b/src/main/java/org/springframework/data/convert/ClassGeneratingEntityInstantiator.java @@ -284,11 +284,8 @@ public class ClassGeneratingEntityInstantiator implements EntityInstantiator { private ObjectInstantiatorClassGenerator() { - this.classLoader = AccessController.doPrivileged(new PrivilegedAction() { - public ByteArrayClassLoader run() { - return new ByteArrayClassLoader(ClassUtils.getDefaultClassLoader()); - } - }); + this.classLoader = AccessController.doPrivileged( + (PrivilegedAction) () -> new ByteArrayClassLoader(ClassUtils.getDefaultClassLoader())); } /** diff --git a/src/main/java/org/springframework/data/convert/ConfigurableTypeInformationMapper.java b/src/main/java/org/springframework/data/convert/ConfigurableTypeInformationMapper.java index df3c13150..5de207612 100644 --- a/src/main/java/org/springframework/data/convert/ConfigurableTypeInformationMapper.java +++ b/src/main/java/org/springframework/data/convert/ConfigurableTypeInformationMapper.java @@ -18,7 +18,9 @@ package org.springframework.data.convert; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; +import org.springframework.data.mapping.Alias; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.util.ClassTypeInformation; @@ -34,7 +36,8 @@ import org.springframework.util.Assert; */ public class ConfigurableTypeInformationMapper implements TypeInformationMapper { - private final Map, Object> typeMap; + private final Map, Alias> typeToAlias; + private final Map> aliasToType; /** * Creates a new {@link ConfigurableTypeInformationMapper} for the given type map. @@ -44,18 +47,22 @@ public class ConfigurableTypeInformationMapper implements TypeInformationMapper public ConfigurableTypeInformationMapper(Map, String> sourceTypeMap) { Assert.notNull(sourceTypeMap, "SourceTypeMap must not be null!"); - this.typeMap = new HashMap, Object>(sourceTypeMap.size()); + + this.typeToAlias = new HashMap<>(sourceTypeMap.size()); + this.aliasToType = new HashMap<>(sourceTypeMap.size()); for (Entry, String> entry : sourceTypeMap.entrySet()) { - ClassTypeInformation key = ClassTypeInformation.from(entry.getKey()); - String value = entry.getValue(); - if (typeMap.containsValue(value)) { - throw new IllegalArgumentException(String.format( - "Detected mapping ambiguity! String %s cannot be mapped to more than one type!", value)); + ClassTypeInformation type = ClassTypeInformation.from(entry.getKey()); + Alias alias = Alias.of(entry.getValue()); + + if (typeToAlias.containsValue(alias)) { + throw new IllegalArgumentException( + String.format("Detected mapping ambiguity! String %s cannot be mapped to more than one type!", alias)); } - this.typeMap.put(key, value); + this.typeToAlias.put(type, alias); + this.aliasToType.put(alias, type); } } @@ -63,26 +70,16 @@ public class ConfigurableTypeInformationMapper implements TypeInformationMapper * (non-Javadoc) * @see org.springframework.data.convert.TypeInformationMapper#createAliasFor(org.springframework.data.util.TypeInformation) */ - public Object createAliasFor(TypeInformation type) { - return typeMap.get(type); + public Alias createAliasFor(TypeInformation type) { + return typeToAlias.getOrDefault(type, Alias.NONE); } /* * (non-Javadoc) - * @see org.springframework.data.convert.TypeInformationMapper#resolveTypeFrom(java.lang.Object) + * @see org.springframework.data.convert.TypeInformationMapper#resolveTypeFrom(org.springframework.data.mapping.Alias) */ - public ClassTypeInformation resolveTypeFrom(Object alias) { - - if (alias == null) { - return null; - } - - for (Entry, Object> entry : typeMap.entrySet()) { - if (entry.getValue().equals(alias)) { - return entry.getKey(); - } - } - - return null; + @Override + public Optional> resolveTypeFrom(Alias alias) { + return Optional.ofNullable(aliasToType.get(alias)); } } diff --git a/src/main/java/org/springframework/data/convert/DefaultTypeMapper.java b/src/main/java/org/springframework/data/convert/DefaultTypeMapper.java index 9e191073d..f5e8a2434 100644 --- a/src/main/java/org/springframework/data/convert/DefaultTypeMapper.java +++ b/src/main/java/org/springframework/data/convert/DefaultTypeMapper.java @@ -20,11 +20,14 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import org.springframework.data.mapping.Alias; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.util.ClassTypeInformation; +import org.springframework.data.util.Optionals; import org.springframework.data.util.TypeInformation; import org.springframework.util.Assert; @@ -41,7 +44,7 @@ public class DefaultTypeMapper implements TypeMapper { private final TypeAliasAccessor accessor; private final List mappers; - private final Map> typeCache; + private final Map>> typeCache; /** * Creates a new {@link DefaultTypeMapper} using the given {@link TypeAliasAccessor}. It will use a @@ -80,7 +83,7 @@ public class DefaultTypeMapper implements TypeMapper { Assert.notNull(accessor, "Accessor must not be null!"); Assert.notNull(additionalMappers, "AdditionalMappers must not be null!"); - List mappers = new ArrayList(additionalMappers.size() + 1); + List mappers = new ArrayList<>(additionalMappers.size() + 1); if (mappingContext != null) { mappers.add(new MappingContextTypeInformationMapper(mappingContext)); } @@ -88,19 +91,18 @@ public class DefaultTypeMapper implements TypeMapper { this.mappers = Collections.unmodifiableList(mappers); this.accessor = accessor; - this.typeCache = new ConcurrentHashMap>(); + this.typeCache = new ConcurrentHashMap<>(); } /* * (non-Javadoc) * @see org.springframework.data.convert.TypeMapper#readType(java.lang.Object) */ - public TypeInformation readType(S source) { + public Optional> readType(S source) { Assert.notNull(source, "Source object must not be null!"); - Object alias = accessor.readAliasFrom(source); - return alias == null ? null : getFromCacheOrCreate(alias); + return getFromCacheOrCreate(accessor.readAliasFrom(source)); } /** @@ -110,53 +112,41 @@ public class DefaultTypeMapper implements TypeMapper { * @param alias * @return */ - private TypeInformation getFromCacheOrCreate(Object alias) { - - TypeInformation typeInformation = typeCache.get(alias); - - if (typeInformation != null) { - return typeInformation; - } - - for (TypeInformationMapper mapper : mappers) { - - typeInformation = mapper.resolveTypeFrom(alias); - - if (typeInformation != null) { - typeCache.put(alias, typeInformation); - return typeInformation; - } - } - - return typeInformation; + private Optional> getFromCacheOrCreate(Alias alias) { + return typeCache.computeIfAbsent(alias, key -> Optionals.firstNonEmpty(mappers, it -> it.resolveTypeFrom(alias))); } /* * (non-Javadoc) * @see org.springframework.data.convert.TypeMapper#readType(java.lang.Object, org.springframework.data.util.TypeInformation) */ - @SuppressWarnings("unchecked") public TypeInformation readType(S source, TypeInformation basicType) { - Assert.notNull(source, "Source object must not be null!"); - Class documentsTargetType = getDefaultedTypeToBeUsed(source); + Assert.notNull(source, "Source must not be null!"); + Assert.notNull(basicType, "Basic type must not be null!"); - if (documentsTargetType == null) { - return basicType; - } + Optional> calculated = getDefaultedTypeToBeUsed(source)// + .map(it -> foo(it, basicType)); - Class rawType = basicType == null ? null : basicType.getType(); + return calculated.orElse(basicType); + } - boolean isMoreConcreteCustomType = rawType == null ? true - : rawType.isAssignableFrom(documentsTargetType) && !rawType.equals(documentsTargetType); + // @SuppressWarnings("unchecked") + private static TypeInformation foo(Class sourceType, TypeInformation type) { - if (!isMoreConcreteCustomType) { - return basicType; - } + return specializeOrDefault(sourceType, type); + + // return type// + // .>map(it -> specializeOrDefault(sourceType, it)) + // .orElseGet(() -> (TypeInformation) ClassTypeInformation.from(sourceType)); + } + + private static TypeInformation specializeOrDefault(Class it, TypeInformation type) { - ClassTypeInformation targetType = ClassTypeInformation.from(documentsTargetType); + ClassTypeInformation targetType = ClassTypeInformation.from(it); + Class rawType = type.getType(); - return (TypeInformation) (basicType != null ? basicType.specialize(targetType) : targetType); + return rawType.isAssignableFrom(it) && !rawType.equals(it) ? type.specialize(targetType) : type; } /** @@ -166,12 +156,9 @@ public class DefaultTypeMapper implements TypeMapper { * @param source * @return */ - private Class getDefaultedTypeToBeUsed(S source) { - - TypeInformation documentsTargetTypeInformation = readType(source); - documentsTargetTypeInformation = documentsTargetTypeInformation == null ? getFallbackTypeFor(source) - : documentsTargetTypeInformation; - return documentsTargetTypeInformation == null ? null : documentsTargetTypeInformation.getType(); + private Optional> getDefaultedTypeToBeUsed(S source) { + return readType(source).map(it -> readType(source)).orElseGet(() -> getFallbackTypeFor(source)) + .map(it -> it.getType()); } /** @@ -180,8 +167,8 @@ public class DefaultTypeMapper implements TypeMapper { * @param source will never be {@literal null}. * @return */ - protected TypeInformation getFallbackTypeFor(S source) { - return null; + protected Optional> getFallbackTypeFor(S source) { + return Optional.empty(); } /* @@ -200,10 +187,7 @@ public class DefaultTypeMapper implements TypeMapper { Assert.notNull(info, "TypeInformation must not be null!"); - Object alias = getAliasFor(info); - if (alias != null) { - accessor.writeTypeTo(sink, alias); - } + getAliasFor(info).getValue().ifPresent(it -> accessor.writeTypeTo(sink, it)); } /** @@ -213,17 +197,10 @@ public class DefaultTypeMapper implements TypeMapper { * @return the alias for the given {@link TypeInformation} or {@literal null} of none was found or all mappers * returned {@literal null}. */ - protected final Object getAliasFor(TypeInformation info) { + protected final Alias getAliasFor(TypeInformation info) { Assert.notNull(info, "TypeInformation must not be null!"); - for (TypeInformationMapper mapper : mappers) { - Object alias = mapper.createAliasFor(info); - if (alias != null) { - return alias; - } - } - - return null; + return Optionals.firstNonEmpty(mappers, it -> it.createAliasFor(info), Alias.NONE); } } diff --git a/src/main/java/org/springframework/data/convert/MappingContextTypeInformationMapper.java b/src/main/java/org/springframework/data/convert/MappingContextTypeInformationMapper.java index 1e7f4e86b..c62987ad1 100644 --- a/src/main/java/org/springframework/data/convert/MappingContextTypeInformationMapper.java +++ b/src/main/java/org/springframework/data/convert/MappingContextTypeInformationMapper.java @@ -17,11 +17,12 @@ package org.springframework.data.convert; import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import org.springframework.data.mapping.Alias; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.util.CacheValue; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; import org.springframework.util.Assert; @@ -35,7 +36,7 @@ import org.springframework.util.Assert; */ public class MappingContextTypeInformationMapper implements TypeInformationMapper { - private final Map, CacheValue> typeMap; + private final Map, Alias> typeMap; private final MappingContext, ?> mappingContext; /** @@ -48,11 +49,11 @@ public class MappingContextTypeInformationMapper implements TypeInformationMappe Assert.notNull(mappingContext, "MappingContext must not be null!"); - this.typeMap = new ConcurrentHashMap, CacheValue>(); + this.typeMap = new ConcurrentHashMap<>(); this.mappingContext = mappingContext; for (PersistentEntity entity : mappingContext.getPersistentEntities()) { - safelyAddToCache(entity.getTypeInformation().getRawTypeInformation(), entity.getTypeAlias()); + verify(entity.getTypeInformation().getRawTypeInformation(), entity.getTypeAlias()); } } @@ -60,24 +61,11 @@ public class MappingContextTypeInformationMapper implements TypeInformationMappe * (non-Javadoc) * @see org.springframework.data.convert.TypeInformationMapper#createAliasFor(org.springframework.data.util.TypeInformation) */ - public Object createAliasFor(TypeInformation type) { + public Alias createAliasFor(TypeInformation type) { - CacheValue key = typeMap.get(type); - - if (key != null) { - return key.getValue(); - } - - PersistentEntity entity = mappingContext.getPersistentEntity(type); - - if (entity == null) { - return null; - } - - Object alias = entity.getTypeAlias(); - safelyAddToCache(type.getRawTypeInformation(), alias); - - return alias; + return typeMap.computeIfAbsent(type.getRawTypeInformation(), key -> { + return verify(key, mappingContext.getPersistentEntity(key).map(it -> it.getTypeAlias()).orElse(Alias.NONE)); + }); } /** @@ -86,73 +74,59 @@ public class MappingContextTypeInformationMapper implements TypeInformationMappe * @param key must not be {@literal null}. * @param alias can be {@literal null}. */ - private void safelyAddToCache(ClassTypeInformation key, Object alias) { - - CacheValue aliasToBeCached = CacheValue.ofNullable(alias); + private Alias verify(ClassTypeInformation key, Alias alias) { - if (alias == null && !typeMap.containsKey(key)) { - typeMap.put(key, aliasToBeCached); - return; - } + // Reject second alias for same type - CacheValue alreadyCachedAlias = typeMap.get(key); + Alias existingAlias = typeMap.getOrDefault(key, Alias.NONE); - // Reject second alias for same type + if (existingAlias.isPresentButDifferent(alias)) { - if (alreadyCachedAlias != null && alreadyCachedAlias.isPresent() && !alreadyCachedAlias.hasValue(alias)) { - throw new IllegalArgumentException(String.format( - "Trying to register alias '%s', but found already registered alias '%s' for type %s!", alias, - alreadyCachedAlias, key)); + throw new IllegalArgumentException( + String.format("Trying to register alias '%s', but found already registered alias '%s' for type %s!", alias, + existingAlias, key)); } // Reject second type for same alias - if (typeMap.containsValue(aliasToBeCached)) { - - for (Entry, CacheValue> entry : typeMap.entrySet()) { + if (typeMap.containsValue(alias)) { - CacheValue value = entry.getValue(); - - if (!value.isPresent()) { - continue; - } + typeMap.entrySet().stream()// + .filter(it -> it.getValue().hasSamePresentValueAs(alias) && !it.getKey().equals(key))// + .findFirst().ifPresent(it -> { - if (value.hasValue(alias) && !entry.getKey().equals(key)) { - throw new IllegalArgumentException(String.format( - "Detected existing type mapping of %s to alias '%s' but attempted to bind the same alias to %s!", key, - alias, entry.getKey())); - } - } + throw new IllegalArgumentException(String.format( + "Detected existing type mapping of %s to alias '%s' but attempted to bind the same alias to %s!", key, + alias, it.getKey())); + }); } - typeMap.put(key, aliasToBeCached); + return alias; } - /* + /* * (non-Javadoc) - * @see org.springframework.data.convert.TypeInformationMapper#resolveTypeFrom(java.lang.Object) + * @see org.springframework.data.convert.TypeInformationMapper#resolveTypeFrom(java.util.Optional) */ - public ClassTypeInformation resolveTypeFrom(Object alias) { - - if (alias == null) { - return null; - } - - for (Entry, CacheValue> entry : typeMap.entrySet()) { + @Override + public Optional> resolveTypeFrom(Alias alias) { - CacheValue cachedAlias = entry.getValue(); + return alias.getValue().map(it -> { - if (cachedAlias.hasValue(alias)) { - return entry.getKey(); + for (Entry, Alias> entry : typeMap.entrySet()) { + if (entry.getValue().hasValue(it)) { + return entry.getKey(); + } } - } - for (PersistentEntity entity : mappingContext.getPersistentEntities()) { - if (alias.equals(entity.getTypeAlias())) { - return entity.getTypeInformation().getRawTypeInformation(); + for (PersistentEntity entity : mappingContext.getPersistentEntities()) { + + if (entity.getTypeAlias().hasValue(it)) { + return entity.getTypeInformation().getRawTypeInformation(); + } } - } - return null; + return null; + }); } } diff --git a/src/main/java/org/springframework/data/convert/ReflectionEntityInstantiator.java b/src/main/java/org/springframework/data/convert/ReflectionEntityInstantiator.java index 34a9b6d42..199ac9251 100644 --- a/src/main/java/org/springframework/data/convert/ReflectionEntityInstantiator.java +++ b/src/main/java/org/springframework/data/convert/ReflectionEntityInstantiator.java @@ -49,7 +49,7 @@ public enum ReflectionEntityInstantiator implements EntityInstantiator { .map(it -> constructor.getParameters().stream()// .map(parameter -> it.getParameterValue(parameter).orElse(null))// .collect(Collectors.toList()))// - .orElse(Collections.emptyList()); + .orElseGet(() -> Collections.emptyList()); try { return (T) BeanUtils.instantiateClass(constructor.getConstructor(), params.toArray()); diff --git a/src/main/java/org/springframework/data/convert/SimpleTypeInformationMapper.java b/src/main/java/org/springframework/data/convert/SimpleTypeInformationMapper.java index 52ee2de64..b3bfbb186 100644 --- a/src/main/java/org/springframework/data/convert/SimpleTypeInformationMapper.java +++ b/src/main/java/org/springframework/data/convert/SimpleTypeInformationMapper.java @@ -16,12 +16,13 @@ package org.springframework.data.convert; import java.util.Map; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import org.springframework.data.mapping.Alias; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; /** * Basic {@link TypeInformationMapper} implementation that interprets the alias handles as fully qualified class name @@ -32,7 +33,7 @@ import org.springframework.util.StringUtils; */ public class SimpleTypeInformationMapper implements TypeInformationMapper { - private final Map> CACHE = new ConcurrentHashMap>(); + private final Map>> CACHE = new ConcurrentHashMap<>(); /** * Returns the {@link TypeInformation} that shall be used when the given {@link String} value is found as type hint. @@ -43,35 +44,11 @@ public class SimpleTypeInformationMapper implements TypeInformationMapper { * @return the type to be used for the given {@link String} representation or {@literal null} if nothing found or the * class cannot be loaded. */ - public ClassTypeInformation resolveTypeFrom(Object alias) { + @Override + public Optional> resolveTypeFrom(Alias alias) { - if (!(alias instanceof String)) { - return null; - } - - String value = (String) alias; - - if (!StringUtils.hasText(value)) { - return null; - } - - ClassTypeInformation information = CACHE.get(value); - - if (information != null) { - return information; - } - - try { - information = ClassTypeInformation.from(ClassUtils.forName(value, null)); - } catch (ClassNotFoundException e) { - return null; - } - - if (information != null) { - CACHE.put(value, information); - } - - return information; + return alias.mapTyped(String.class)// + .flatMap(it -> CACHE.computeIfAbsent(it, SimpleTypeInformationMapper::loadClass).map(type -> type)); } /** @@ -81,7 +58,16 @@ public class SimpleTypeInformationMapper implements TypeInformationMapper { * @param typeInformation must not be {@literal null}. * @return the String representation to be stored or {@literal null} if no type information shall be stored. */ - public String createAliasFor(TypeInformation type) { - return type.getType().getName(); + public Alias createAliasFor(TypeInformation type) { + return Alias.of(type.getType().getName()); + } + + private static Optional> loadClass(String typeName) { + + try { + return Optional.of(ClassTypeInformation.from(ClassUtils.forName(typeName, null))); + } catch (ClassNotFoundException e) { + return Optional.empty(); + } } } diff --git a/src/main/java/org/springframework/data/convert/TypeAliasAccessor.java b/src/main/java/org/springframework/data/convert/TypeAliasAccessor.java index 7da305e25..fc0c2ee1b 100644 --- a/src/main/java/org/springframework/data/convert/TypeAliasAccessor.java +++ b/src/main/java/org/springframework/data/convert/TypeAliasAccessor.java @@ -15,6 +15,8 @@ */ package org.springframework.data.convert; +import org.springframework.data.mapping.Alias; + /** * Interface to abstract implementations of how to access a type alias from a given source or sink. * @@ -28,7 +30,7 @@ public interface TypeAliasAccessor { * @param source * @return can be {@literal null} in case no alias was found. */ - Object readAliasFrom(S source); + Alias readAliasFrom(S source); /** * Writes the given type alias to the given sink. diff --git a/src/main/java/org/springframework/data/convert/TypeInformationMapper.java b/src/main/java/org/springframework/data/convert/TypeInformationMapper.java index 0246d4f52..b6374bb76 100644 --- a/src/main/java/org/springframework/data/convert/TypeInformationMapper.java +++ b/src/main/java/org/springframework/data/convert/TypeInformationMapper.java @@ -15,6 +15,9 @@ */ package org.springframework.data.convert; +import java.util.Optional; + +import org.springframework.data.mapping.Alias; import org.springframework.data.util.TypeInformation; /** @@ -30,7 +33,7 @@ public interface TypeInformationMapper { * @param alias can be {@literal null}. * @return */ - TypeInformation resolveTypeFrom(Object alias); + Optional> resolveTypeFrom(Alias alias); /** * Returns the alias to be used for the given {@link TypeInformation}. @@ -38,5 +41,5 @@ public interface TypeInformationMapper { * @param type * @return */ - Object createAliasFor(TypeInformation type); + Alias createAliasFor(TypeInformation type); } diff --git a/src/main/java/org/springframework/data/convert/TypeMapper.java b/src/main/java/org/springframework/data/convert/TypeMapper.java index 360cb3809..557d6be9f 100644 --- a/src/main/java/org/springframework/data/convert/TypeMapper.java +++ b/src/main/java/org/springframework/data/convert/TypeMapper.java @@ -15,6 +15,8 @@ */ package org.springframework.data.convert; +import java.util.Optional; + import org.springframework.data.util.TypeInformation; /** @@ -30,7 +32,7 @@ public interface TypeMapper { * @param source must not be {@literal null}. * @return */ - TypeInformation readType(S source); + Optional> readType(S source); /** * Returns the {@link TypeInformation} from the given source if it is a more concrete type than the given default one. diff --git a/src/main/java/org/springframework/data/domain/AbstractPageRequest.java b/src/main/java/org/springframework/data/domain/AbstractPageRequest.java index e5469d170..5cba51c0d 100644 --- a/src/main/java/org/springframework/data/domain/AbstractPageRequest.java +++ b/src/main/java/org/springframework/data/domain/AbstractPageRequest.java @@ -71,7 +71,7 @@ public abstract class AbstractPageRequest implements Pageable, Serializable { * (non-Javadoc) * @see org.springframework.data.domain.Pageable#getOffset() */ - public int getOffset() { + public long getOffset() { return page * size; } diff --git a/src/main/java/org/springframework/data/domain/Chunk.java b/src/main/java/org/springframework/data/domain/Chunk.java index bd0f6bec4..4cbc1c36c 100644 --- a/src/main/java/org/springframework/data/domain/Chunk.java +++ b/src/main/java/org/springframework/data/domain/Chunk.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.stream.Collectors; import org.springframework.core.convert.converter.Converter; import org.springframework.util.Assert; @@ -34,14 +35,14 @@ abstract class Chunk implements Slice, Serializable { private static final long serialVersionUID = 867755909294344406L; - private final List content = new ArrayList(); + private final List content = new ArrayList<>(); private final Pageable pageable; /** * Creates a new {@link Chunk} with the given content and the given governing {@link Pageable}. * * @param content must not be {@literal null}. - * @param pageable can be {@literal null}. + * @param pageable must not be {@literal null}. */ public Chunk(List content, Pageable pageable) { @@ -56,7 +57,7 @@ abstract class Chunk implements Slice, Serializable { * @see org.springframework.data.domain.Slice#getNumber() */ public int getNumber() { - return pageable == null ? 0 : pageable.getPageNumber(); + return pageable == Pageable.NONE ? 0 : pageable.getPageNumber(); } /* @@ -64,7 +65,7 @@ abstract class Chunk implements Slice, Serializable { * @see org.springframework.data.domain.Slice#getSize() */ public int getSize() { - return pageable == null ? 0 : pageable.getPageSize(); + return pageable == Pageable.NONE ? 0 : pageable.getPageSize(); } /* @@ -104,7 +105,7 @@ abstract class Chunk implements Slice, Serializable { * @see org.springframework.data.domain.Slice#nextPageable() */ public Pageable nextPageable() { - return hasNext() ? pageable.next() : null; + return hasNext() ? pageable.next() : Pageable.NONE; } /* @@ -112,12 +113,7 @@ abstract class Chunk implements Slice, Serializable { * @see org.springframework.data.domain.Slice#previousPageable() */ public Pageable previousPageable() { - - if (hasPrevious()) { - return pageable.previousOrFirst(); - } - - return null; + return hasPrevious() ? pageable.previousOrFirst() : Pageable.NONE; } /* @@ -140,8 +136,9 @@ abstract class Chunk implements Slice, Serializable { * (non-Javadoc) * @see org.springframework.data.domain.Slice#getSort() */ + @Override public Sort getSort() { - return pageable == null ? null : pageable.getSort(); + return pageable.getSort(); } /* @@ -158,17 +155,11 @@ abstract class Chunk implements Slice, Serializable { * @param converter must not be {@literal null}. * @return */ - protected List getConvertedContent(Converter converter) { + protected List getConvertedContent(Converter converter) { Assert.notNull(converter, "Converter must not be null!"); - List result = new ArrayList(content.size()); - - for (T element : this) { - result.add(converter.convert(element)); - } - - return result; + return this.stream().map(it -> converter.convert(it)).collect(Collectors.toList()); } /* @@ -189,7 +180,7 @@ abstract class Chunk implements Slice, Serializable { Chunk that = (Chunk) obj; boolean contentEqual = this.content.equals(that.content); - boolean pageableEqual = this.pageable == null ? that.pageable == null : this.pageable.equals(that.pageable); + boolean pageableEqual = this.pageable.equals(that.pageable); return contentEqual && pageableEqual; } @@ -203,7 +194,7 @@ abstract class Chunk implements Slice, Serializable { int result = 17; - result += 31 * (pageable == null ? 0 : pageable.hashCode()); + result += 31 * pageable.hashCode(); result += 31 * content.hashCode(); return result; diff --git a/src/main/java/org/springframework/data/domain/Example.java b/src/main/java/org/springframework/data/domain/Example.java index d419768a0..589730011 100644 --- a/src/main/java/org/springframework/data/domain/Example.java +++ b/src/main/java/org/springframework/data/domain/Example.java @@ -48,7 +48,7 @@ public class Example { * @return */ public static Example of(T probe) { - return new Example(probe, ExampleMatcher.matching()); + return new Example<>(probe, ExampleMatcher.matching()); } /** @@ -59,7 +59,7 @@ public class Example { * @return */ public static Example of(T probe, ExampleMatcher matcher) { - return new Example(probe, matcher); + return new Example<>(probe, matcher); } /** diff --git a/src/main/java/org/springframework/data/domain/ExampleMatcher.java b/src/main/java/org/springframework/data/domain/ExampleMatcher.java index 2788fb616..ffea0c87a 100644 --- a/src/main/java/org/springframework/data/domain/ExampleMatcher.java +++ b/src/main/java/org/springframework/data/domain/ExampleMatcher.java @@ -112,7 +112,7 @@ public class ExampleMatcher { Assert.notEmpty(ignoredPaths, "IgnoredPaths must not be empty!"); Assert.noNullElements(ignoredPaths, "IgnoredPaths must not contain null elements!"); - Set newIgnoredPaths = new LinkedHashSet(this.ignoredPaths); + Set newIgnoredPaths = new LinkedHashSet<>(this.ignoredPaths); newIgnoredPaths.addAll(Arrays.asList(ignoredPaths)); return new ExampleMatcher(nullHandler, defaultStringMatcher, propertySpecifiers, newIgnoredPaths, defaultIgnoreCase, diff --git a/src/main/java/org/springframework/data/domain/Page.java b/src/main/java/org/springframework/data/domain/Page.java index 5ef3e3a17..0254c1706 100644 --- a/src/main/java/org/springframework/data/domain/Page.java +++ b/src/main/java/org/springframework/data/domain/Page.java @@ -47,5 +47,5 @@ public interface Page extends Slice { * @return a new {@link Page} with the content of the current one mapped by the given {@link Converter}. * @since 1.10 */ - Page map(Converter converter); + Page map(Converter converter); } diff --git a/src/main/java/org/springframework/data/domain/PageImpl.java b/src/main/java/org/springframework/data/domain/PageImpl.java index d3e9db177..e752c2974 100644 --- a/src/main/java/org/springframework/data/domain/PageImpl.java +++ b/src/main/java/org/springframework/data/domain/PageImpl.java @@ -16,6 +16,7 @@ package org.springframework.data.domain; import java.util.List; +import java.util.Optional; import org.springframework.core.convert.converter.Converter; @@ -45,8 +46,13 @@ public class PageImpl extends Chunk implements Page { super(content, pageable); this.pageable = pageable; - this.total = !content.isEmpty() && pageable != null && pageable.getOffset() + pageable.getPageSize() > total - ? pageable.getOffset() + content.size() : total; + + Optional foo = Pageable.NONE == pageable ? Optional.empty() : Optional.of(pageable); + + this.total = foo.filter(it -> !content.isEmpty())// + .filter(it -> it.getOffset() + it.getPageSize() > total)// + .map(it -> it.getOffset() + content.size())// + .orElse(total); } /** @@ -56,7 +62,7 @@ public class PageImpl extends Chunk implements Page { * @param content must not be {@literal null}. */ public PageImpl(List content) { - this(content, null, null == content ? 0 : content.size()); + this(content, Pageable.NONE, null == content ? 0 : content.size()); } /* @@ -100,8 +106,8 @@ public class PageImpl extends Chunk implements Page { * @see org.springframework.data.domain.Slice#transform(org.springframework.core.convert.converter.Converter) */ @Override - public Page map(Converter converter) { - return new PageImpl(getConvertedContent(converter), pageable, total); + public Page map(Converter converter) { + return new PageImpl<>(getConvertedContent(converter), pageable, total); } /* diff --git a/src/main/java/org/springframework/data/domain/PageRequest.java b/src/main/java/org/springframework/data/domain/PageRequest.java index e9cd18e63..3baca7dd1 100644 --- a/src/main/java/org/springframework/data/domain/PageRequest.java +++ b/src/main/java/org/springframework/data/domain/PageRequest.java @@ -15,6 +15,8 @@ */ package org.springframework.data.domain; +import java.util.Optional; + import org.springframework.data.domain.Sort.Direction; /** @@ -35,9 +37,11 @@ public class PageRequest extends AbstractPageRequest { * * @param page zero-based page index. * @param size the size of the page to be returned. + * @deprecated use {@link #of(int, int)} instead. */ + @Deprecated public PageRequest(int page, int size) { - this(page, size, null); + this(page, size, Sort.unsorted()); } /** @@ -47,7 +51,9 @@ public class PageRequest extends AbstractPageRequest { * @param size the size of the page to be returned. * @param direction the direction of the {@link Sort} to be specified, can be {@literal null}. * @param properties the properties to sort by, must not be {@literal null} or empty. + * @deprecated use {@link #of(int, int, Direction, String...)} instead. */ + @Deprecated public PageRequest(int page, int size, Direction direction, String... properties) { this(page, size, new Sort(direction, properties)); } @@ -58,12 +64,28 @@ public class PageRequest extends AbstractPageRequest { * @param page zero-based page index. * @param size the size of the page to be returned. * @param sort can be {@literal null}. + * @deprecated use {@link #of(int, int, Optional)} instead. */ + @Deprecated public PageRequest(int page, int size, Sort sort) { + super(page, size); + this.sort = sort; } + public static PageRequest of(int page, int site) { + return of(page, site, Sort.unsorted()); + } + + public static PageRequest of(int page, int site, Sort sort) { + return new PageRequest(page, site, sort); + } + + public static PageRequest of(int page, int size, Direction direction, String... properties) { + return of(page, size, new Sort(direction, properties)); + } + /* * (non-Javadoc) * @see org.springframework.data.domain.Pageable#getSort() @@ -113,9 +135,7 @@ public class PageRequest extends AbstractPageRequest { PageRequest that = (PageRequest) obj; - boolean sortEqual = this.sort == null ? that.sort == null : this.sort.equals(that.sort); - - return super.equals(that) && sortEqual; + return super.equals(that) && this.sort.equals(that.sort); } /* @@ -124,7 +144,7 @@ public class PageRequest extends AbstractPageRequest { */ @Override public int hashCode() { - return 31 * super.hashCode() + (null == sort ? 0 : sort.hashCode()); + return 31 * super.hashCode() + sort.hashCode(); } /* @@ -133,7 +153,6 @@ public class PageRequest extends AbstractPageRequest { */ @Override public String toString() { - return String.format("Page request [number: %d, size %d, sort: %s]", getPageNumber(), getPageSize(), - sort == null ? null : sort.toString()); + return String.format("Page request [number: %d, size %d, sort: %s]", getPageNumber(), getPageSize(), sort); } } diff --git a/src/main/java/org/springframework/data/domain/Pageable.java b/src/main/java/org/springframework/data/domain/Pageable.java index acdd1e40c..bf0fb3152 100644 --- a/src/main/java/org/springframework/data/domain/Pageable.java +++ b/src/main/java/org/springframework/data/domain/Pageable.java @@ -41,7 +41,7 @@ public interface Pageable { * * @return the offset to be taken */ - int getOffset(); + long getOffset(); /** * Returns the sorting parameters. @@ -50,6 +50,10 @@ public interface Pageable { */ Sort getSort(); + default Sort getSortOr(Sort sort) { + return getSort().isSorted() ? getSort() : sort; + } + /** * Returns the {@link Pageable} requesting the next {@link Page}. * @@ -78,4 +82,47 @@ public interface Pageable { * @return */ boolean hasPrevious(); + + public static Pageable NONE = new Pageable() { + + @Override + public Pageable previousOrFirst() { + return this; + } + + @Override + public Pageable next() { + return this; + } + + @Override + public boolean hasPrevious() { + return false; + } + + @Override + public Sort getSort() { + return Sort.unsorted(); + } + + @Override + public int getPageSize() { + throw new UnsupportedOperationException(); + } + + @Override + public int getPageNumber() { + throw new UnsupportedOperationException(); + } + + @Override + public long getOffset() { + throw new UnsupportedOperationException(); + } + + @Override + public Pageable first() { + return this; + } + }; } diff --git a/src/main/java/org/springframework/data/domain/Slice.java b/src/main/java/org/springframework/data/domain/Slice.java index e3169fc7f..04268e600 100644 --- a/src/main/java/org/springframework/data/domain/Slice.java +++ b/src/main/java/org/springframework/data/domain/Slice.java @@ -18,6 +18,7 @@ package org.springframework.data.domain; import java.util.List; import org.springframework.core.convert.converter.Converter; +import org.springframework.data.util.Streamable; /** * A slice of data that indicates whether there's a next or previous slice available. Allows to obtain a @@ -26,7 +27,7 @@ import org.springframework.core.convert.converter.Converter; * @author Oliver Gierke * @since 1.8 */ -public interface Slice extends Iterable { +public interface Slice extends Streamable { /** * Returns the number of the current {@link Slice}. Is always non-negative. @@ -123,5 +124,5 @@ public interface Slice extends Iterable { * @return a new {@link Slice} with the content of the current one mapped by the given {@link Converter}. * @since 1.10 */ - Slice map(Converter converter); + Slice map(Converter converter); } diff --git a/src/main/java/org/springframework/data/domain/SliceImpl.java b/src/main/java/org/springframework/data/domain/SliceImpl.java index ac620af19..a2f0c3e3b 100644 --- a/src/main/java/org/springframework/data/domain/SliceImpl.java +++ b/src/main/java/org/springframework/data/domain/SliceImpl.java @@ -42,6 +42,7 @@ public class SliceImpl extends Chunk { public SliceImpl(List content, Pageable pageable, boolean hasNext) { super(content, pageable); + this.hasNext = hasNext; this.pageable = pageable; } @@ -69,8 +70,8 @@ public class SliceImpl extends Chunk { * @see org.springframework.data.domain.Slice#transform(org.springframework.core.convert.converter.Converter) */ @Override - public Slice map(Converter converter) { - return new SliceImpl(getConvertedContent(converter), pageable, hasNext); + public Slice map(Converter converter) { + return new SliceImpl<>(getConvertedContent(converter), pageable, hasNext); } /* diff --git a/src/main/java/org/springframework/data/domain/Sort.java b/src/main/java/org/springframework/data/domain/Sort.java index 8da3ab9b9..80a487cee 100644 --- a/src/main/java/org/springframework/data/domain/Sort.java +++ b/src/main/java/org/springframework/data/domain/Sort.java @@ -18,10 +18,14 @@ package org.springframework.data.domain; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.Optional; +import java.util.stream.Collectors; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** @@ -34,6 +38,9 @@ import org.springframework.util.StringUtils; public class Sort implements Iterable, Serializable { private static final long serialVersionUID = 5737186511678863905L; + + private static final Sort UNSORTED = new Sort(new Order[0]); + public static final Direction DEFAULT_DIRECTION = Direction.ASC; private final List orders; @@ -43,6 +50,7 @@ public class Sort implements Iterable orders) { - if (null == orders || orders.isEmpty()) { - throw new IllegalArgumentException("You have to provide at least one sort property to sort by!"); - } + Assert.notNull(orders, "Orders must not be null!"); - this.orders = orders; + this.orders = Collections.unmodifiableList(orders); } /** * Creates a new {@link Sort} instance. Order defaults to {@value Direction#ASC}. * * @param properties must not be {@literal null} or contain {@literal null} or empty strings + * @deprecated use {@link Sort#by(String...)} */ + @Deprecated public Sort(String... properties) { this(DEFAULT_DIRECTION, properties); } @@ -77,7 +87,7 @@ public class Sort implements Iterable() : Arrays.asList(properties)); + this(direction, properties == null ? new ArrayList<>() : Arrays.asList(properties)); } /** @@ -92,13 +102,45 @@ public class Sort implements Iterable(properties.size()); + this.orders = new ArrayList<>(properties.size()); for (String property : properties) { this.orders.add(new Order(direction, property)); } } + public static Sort by(String... properties) { + return properties.length == 0 ? Sort.unsorted() : new Sort(properties); + } + + public static Sort by(List orders) { + return orders.isEmpty() ? Sort.unsorted() : new Sort(orders); + } + + public static Sort by(Order... orders) { + return new Sort(orders); + } + + public static Sort unsorted() { + return UNSORTED; + } + + public Sort descending() { + return withDirection(Direction.DESC); + } + + public Sort ascending() { + return withDirection(Direction.ASC); + } + + private Sort withDirection(Direction direction) { + return new Sort(orders.stream().map(it -> new Order(direction, it.getProperty())).collect(Collectors.toList())); + } + + public boolean isSorted() { + return !orders.isEmpty(); + } + /** * Returns a new {@link Sort} consisting of the {@link Order}s of the current {@link Sort} combined with the given * ones. @@ -112,7 +154,7 @@ public class Sort implements Iterable these = new ArrayList(this.orders); + ArrayList these = new ArrayList<>(this.orders); for (Order order : sort) { these.add(order); @@ -184,7 +226,7 @@ public class Sort implements Iterable fromOptionalString(String value) { try { - return fromString(value); + return Optional.of(fromString(value)); } catch (IllegalArgumentException e) { - return null; + return Optional.empty(); } } } diff --git a/src/main/java/org/springframework/data/domain/jaxb/PageableAdapter.java b/src/main/java/org/springframework/data/domain/jaxb/PageableAdapter.java index 9b3491b68..681a07e98 100644 --- a/src/main/java/org/springframework/data/domain/jaxb/PageableAdapter.java +++ b/src/main/java/org/springframework/data/domain/jaxb/PageableAdapter.java @@ -21,7 +21,6 @@ import javax.xml.bind.annotation.adapters.XmlAdapter; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; import org.springframework.data.domain.jaxb.SpringDataJaxb.OrderDto; import org.springframework.data.domain.jaxb.SpringDataJaxb.PageRequestDto; import org.springframework.data.domain.jaxb.SpringDataJaxb.SortDto; @@ -43,7 +42,7 @@ class PageableAdapter extends XmlAdapter { SortDto sortDto = SortAdapter.INSTANCE.marshal(request.getSort()); PageRequestDto dto = new PageRequestDto(); - dto.orders = sortDto == null ? Collections. emptyList() : sortDto.orders; + dto.orders = sortDto == null ? Collections.emptyList() : sortDto.orders; dto.page = request.getPageNumber(); dto.size = request.getPageSize(); @@ -58,13 +57,12 @@ class PageableAdapter extends XmlAdapter { public Pageable unmarshal(PageRequestDto v) { if (v.orders.isEmpty()) { - return new PageRequest(v.page, v.size); + return PageRequest.of(v.page, v.size); } SortDto sortDto = new SortDto(); sortDto.orders = v.orders; - Sort sort = SortAdapter.INSTANCE.unmarshal(sortDto); - return new PageRequest(v.page, v.size, sort); + return PageRequest.of(v.page, v.size, SortAdapter.INSTANCE.unmarshal(sortDto)); } } diff --git a/src/main/java/org/springframework/data/domain/jaxb/SortAdapter.java b/src/main/java/org/springframework/data/domain/jaxb/SortAdapter.java index 9d00eb296..b3ed72218 100644 --- a/src/main/java/org/springframework/data/domain/jaxb/SortAdapter.java +++ b/src/main/java/org/springframework/data/domain/jaxb/SortAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,6 +52,6 @@ public class SortAdapter extends XmlAdapter { */ @Override public Sort unmarshal(SortDto source) { - return source == null ? null : new Sort(SpringDataJaxb.unmarshal(source.orders, OrderAdapter.INSTANCE)); + return source == null ? Sort.unsorted() : Sort.by(SpringDataJaxb.unmarshal(source.orders, OrderAdapter.INSTANCE)); } } diff --git a/src/main/java/org/springframework/data/domain/jaxb/SpringDataJaxb.java b/src/main/java/org/springframework/data/domain/jaxb/SpringDataJaxb.java index 87f807ef1..cb07360c6 100644 --- a/src/main/java/org/springframework/data/domain/jaxb/SpringDataJaxb.java +++ b/src/main/java/org/springframework/data/domain/jaxb/SpringDataJaxb.java @@ -60,7 +60,7 @@ public abstract class SpringDataJaxb { public static class PageRequestDto { @XmlAttribute int page, size; - @XmlElement(name = "order", namespace = NAMESPACE) List orders = new ArrayList(); + @XmlElement(name = "order", namespace = NAMESPACE) List orders = new ArrayList<>(); } /** @@ -72,7 +72,7 @@ public abstract class SpringDataJaxb { @XmlAccessorType(XmlAccessType.FIELD) public static class SortDto { - @XmlElement(name = "order", namespace = SpringDataJaxb.NAMESPACE) List orders = new ArrayList(); + @XmlElement(name = "order", namespace = SpringDataJaxb.NAMESPACE) List orders = new ArrayList<>(); } /** @@ -116,7 +116,7 @@ public abstract class SpringDataJaxb { return Collections.emptyList(); } - List result = new ArrayList(source.size()); + List result = new ArrayList<>(source.size()); for (S element : source) { try { @@ -144,7 +144,7 @@ public abstract class SpringDataJaxb { return Collections.emptyList(); } - List result = new ArrayList(); + List result = new ArrayList<>(); for (T element : source) { try { diff --git a/src/main/java/org/springframework/data/geo/Distance.java b/src/main/java/org/springframework/data/geo/Distance.java index fdbed6bae..b0d7dbc53 100644 --- a/src/main/java/org/springframework/data/geo/Distance.java +++ b/src/main/java/org/springframework/data/geo/Distance.java @@ -63,7 +63,7 @@ public class Distance implements Serializable, Comparable { * @return will never be {@literal null}. */ public static Range between(Distance min, Distance max) { - return new Range(min, max); + return new Range<>(min, max); } /** diff --git a/src/main/java/org/springframework/data/geo/Polygon.java b/src/main/java/org/springframework/data/geo/Polygon.java index e6e798a5e..65244d003 100644 --- a/src/main/java/org/springframework/data/geo/Polygon.java +++ b/src/main/java/org/springframework/data/geo/Polygon.java @@ -53,7 +53,7 @@ public class Polygon implements Iterable, Shape { Assert.notNull(z, "Z coordinate must not be null!"); Assert.notNull(others, "Others must not be null!"); - List points = new ArrayList(3 + others.length); + List points = new ArrayList<>(3 + others.length); points.addAll(Arrays.asList(x, y, z)); points.addAll(Arrays.asList(others)); @@ -70,7 +70,7 @@ public class Polygon implements Iterable, Shape { Assert.notNull(points, "Points must not be null!"); - List pointsToSet = new ArrayList(points.size()); + List pointsToSet = new ArrayList<>(points.size()); for (Point point : points) { diff --git a/src/main/java/org/springframework/data/mapping/Alias.java b/src/main/java/org/springframework/data/mapping/Alias.java new file mode 100644 index 000000000..7d393b8bc --- /dev/null +++ b/src/main/java/org/springframework/data/mapping/Alias.java @@ -0,0 +1,66 @@ +/* + * Copyright 2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.mapping; + +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import lombok.Value; + +import java.util.Optional; + +/** + * @author Oliver Gierke + */ +@Value +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +public class Alias { + + public static Alias NONE = new Alias(Optional.empty()); + + Optional value; + + public static Alias of(Object alias) { + return ofOptional(Optional.of(alias)); + } + + public static Alias ofOptional(Optional optional) { + return optional.isPresent() ? new Alias(optional) : NONE; + } + + public boolean isPresentButDifferent(Alias other) { + return isPresent() && !hasValue(other.value); + } + + public boolean hasValue(Object that) { + return value.filter(it -> it.equals(that)).isPresent(); + } + + public boolean hasSamePresentValueAs(Alias other) { + return isPresent() && hasValue(other.value); + } + + public boolean isPresent() { + return value.isPresent(); + } + + public Optional mapTyped(Class type) { + return value.filter(it -> type.isInstance(it)).map(it -> type.cast(it)); + } + + public String toString() { + return value.map(Object::toString).orElse("NONE"); + } +} diff --git a/src/main/java/org/springframework/data/mapping/IdentifierAccessor.java b/src/main/java/org/springframework/data/mapping/IdentifierAccessor.java index 09cca3287..29c7da8b9 100644 --- a/src/main/java/org/springframework/data/mapping/IdentifierAccessor.java +++ b/src/main/java/org/springframework/data/mapping/IdentifierAccessor.java @@ -29,5 +29,5 @@ public interface IdentifierAccessor { * * @return */ - Optional getIdentifier(); + Optional getIdentifier(); } diff --git a/src/main/java/org/springframework/data/mapping/PersistentEntity.java b/src/main/java/org/springframework/data/mapping/PersistentEntity.java index 1d6ec65cd..f8d2e75ee 100644 --- a/src/main/java/org/springframework/data/mapping/PersistentEntity.java +++ b/src/main/java/org/springframework/data/mapping/PersistentEntity.java @@ -135,7 +135,7 @@ public interface PersistentEntity> { * * @return */ - Optional getTypeAlias(); + Alias getTypeAlias(); /** * Returns the {@link TypeInformation} backing this {@link PersistentEntity}. diff --git a/src/main/java/org/springframework/data/mapping/PersistentProperty.java b/src/main/java/org/springframework/data/mapping/PersistentProperty.java index cf3e1c4bd..666854baa 100644 --- a/src/main/java/org/springframework/data/mapping/PersistentProperty.java +++ b/src/main/java/org/springframework/data/mapping/PersistentProperty.java @@ -89,7 +89,7 @@ public interface PersistentProperty

> { Optional getSpelExpression(); - Association

getAssociation(); + Optional> getAssociation(); /** * Returns whether the type of the {@link PersistentProperty} is actually to be regarded as {@link PersistentEntity} @@ -199,7 +199,7 @@ public interface PersistentProperty

> { * potentially backing field and traverse accessor methods to potentially available super types. * * @param annotationType the annotation to look up, must not be {@literal null}. - * @return the annotation of the given type if present or {@literal null} otherwise. + * @return the annotation of the given type. * @see AnnotationUtils#findAnnotation(Method, Class) */ Optional findAnnotation(Class annotationType); diff --git a/src/main/java/org/springframework/data/mapping/PersistentPropertyAccessor.java b/src/main/java/org/springframework/data/mapping/PersistentPropertyAccessor.java index 0bb74ef1b..265998fa5 100644 --- a/src/main/java/org/springframework/data/mapping/PersistentPropertyAccessor.java +++ b/src/main/java/org/springframework/data/mapping/PersistentPropertyAccessor.java @@ -49,7 +49,7 @@ public interface PersistentPropertyAccessor { * @param property must not be {@literal null}. * @return can be {@literal null}. */ - Optional getProperty(PersistentProperty property); + Optional getProperty(PersistentProperty property); /** * Returns the underlying bean. diff --git a/src/main/java/org/springframework/data/mapping/PreferredConstructor.java b/src/main/java/org/springframework/data/mapping/PreferredConstructor.java index 666e0c608..58bb708d8 100644 --- a/src/main/java/org/springframework/data/mapping/PreferredConstructor.java +++ b/src/main/java/org/springframework/data/mapping/PreferredConstructor.java @@ -226,9 +226,11 @@ public class PreferredConstructor> { } private static Optional getValue(Annotation[] annotations) { - return Arrays.stream(annotations).// - filter(it -> it.annotationType() == Value.class).// - findFirst().map(it -> ((Value) it).value()); + + return Arrays.stream(annotations)// + .filter(it -> it.annotationType() == Value.class)// + .findFirst().map(it -> ((Value) it).value())// + .filter(it -> StringUtils.hasText(it)); } /** diff --git a/src/main/java/org/springframework/data/mapping/PropertyPath.java b/src/main/java/org/springframework/data/mapping/PropertyPath.java index 872350aec..bc95d9aae 100644 --- a/src/main/java/org/springframework/data/mapping/PropertyPath.java +++ b/src/main/java/org/springframework/data/mapping/PropertyPath.java @@ -16,6 +16,7 @@ package org.springframework.data.mapping; import lombok.EqualsAndHashCode; +import lombok.Getter; import java.util.ArrayList; import java.util.Collections; @@ -45,7 +46,8 @@ public class PropertyPath implements Streamable { private final TypeInformation owningType; private final String name; - private final TypeInformation type; + private final @Getter TypeInformation typeInformation; + private final TypeInformation actualTypeInformation; private final boolean isCollection; private PropertyPath next; @@ -57,7 +59,7 @@ public class PropertyPath implements Streamable { * @param owningType must not be {@literal null}. */ PropertyPath(String name, Class owningType) { - this(name, ClassTypeInformation.from(owningType), Collections. emptyList()); + this(name, ClassTypeInformation.from(owningType), Collections.emptyList()); } /** @@ -74,15 +76,13 @@ public class PropertyPath implements Streamable { Assert.notNull(base, "Perviously found properties must not be null!"); String propertyName = name.matches(ALL_UPPERCASE) ? name : StringUtils.uncapitalize(name); - TypeInformation propertyType = owningType.getProperty(propertyName); - - if (propertyType == null) { - throw new PropertyReferenceException(propertyName, owningType, base); - } + TypeInformation propertyType = owningType.getProperty(propertyName) + .orElseThrow(() -> new PropertyReferenceException(propertyName, owningType, base)); this.owningType = owningType; + this.typeInformation = propertyType; this.isCollection = propertyType.isCollectionLike(); - this.type = propertyType.getActualType(); + this.actualTypeInformation = propertyType.getActualType(); this.name = propertyName; } @@ -127,7 +127,7 @@ public class PropertyPath implements Streamable { * @return */ public Class getType() { - return this.type.getType(); + return this.actualTypeInformation.getType(); } /** @@ -221,7 +221,7 @@ public class PropertyPath implements Streamable { Assert.hasText(source, "Source must not be null or empty!"); Assert.notNull(type, "TypeInformation must not be null or empty!"); - List iteratorSource = new ArrayList(); + List iteratorSource = new ArrayList<>(); Matcher matcher = SPLITTER.matcher("_" + source); while (matcher.find()) { @@ -231,7 +231,7 @@ public class PropertyPath implements Streamable { Iterator parts = iteratorSource.iterator(); PropertyPath result = null; - Stack current = new Stack(); + Stack current = new Stack<>(); while (parts.hasNext()) { if (result == null) { @@ -256,7 +256,7 @@ public class PropertyPath implements Streamable { PropertyPath previous = base.peek(); - PropertyPath propertyPath = create(source, previous.type, base); + PropertyPath propertyPath = create(source, previous.typeInformation.getActualType(), base); previous.next = propertyPath; return propertyPath; } @@ -298,11 +298,11 @@ public class PropertyPath implements Streamable { base.get(base.size() - 1).next = current; } - List newBase = new ArrayList(base); + List newBase = new ArrayList<>(base); newBase.add(current); if (StringUtils.hasText(addTail)) { - current.next = create(addTail, current.type, newBase); + current.next = create(addTail, current.actualTypeInformation, newBase); } return current; diff --git a/src/main/java/org/springframework/data/mapping/PropertyReferenceException.java b/src/main/java/org/springframework/data/mapping/PropertyReferenceException.java index 830b45225..7970fc3f7 100644 --- a/src/main/java/org/springframework/data/mapping/PropertyReferenceException.java +++ b/src/main/java/org/springframework/data/mapping/PropertyReferenceException.java @@ -142,7 +142,7 @@ public class PropertyReferenceException extends RuntimeException { */ private static Set detectPotentialMatches(String propertyName, Class type) { - Set result = new HashSet(); + Set result = new HashSet<>(); result.addAll(Arrays.asList(PropertyMatches.forField(propertyName, type).getPossibleMatches())); result.addAll(Arrays.asList(PropertyMatches.forProperty(propertyName, type).getPossibleMatches())); diff --git a/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java b/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java index 85d68fe17..d04e26714 100644 --- a/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java +++ b/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java @@ -29,6 +29,7 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.stream.Collectors; import org.springframework.beans.BeanUtils; import org.springframework.beans.BeansException; @@ -42,8 +43,10 @@ import org.springframework.data.mapping.model.ClassGeneratingPropertyAccessorFac import org.springframework.data.mapping.model.MappingException; import org.springframework.data.mapping.model.MutablePersistentEntity; import org.springframework.data.mapping.model.PersistentPropertyAccessorFactory; +import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.ClassTypeInformation; +import org.springframework.data.util.Optionals; import org.springframework.data.util.Pair; import org.springframework.data.util.TypeInformation; import org.springframework.util.Assert; @@ -72,7 +75,8 @@ import org.springframework.util.StringUtils; public abstract class AbstractMappingContext, P extends PersistentProperty

> implements MappingContext, ApplicationEventPublisherAware, InitializingBean { - private final Map, E> persistentEntities = new HashMap, E>(); + private final Optional NONE = Optional.empty(); + private final Map, Optional> persistentEntities = new HashMap<>(); private final PersistentPropertyAccessorFactory persistentPropertyAccessorFactory = new ClassGeneratingPropertyAccessorFactory(); private ApplicationEventPublisher applicationEventPublisher; @@ -132,8 +136,13 @@ public abstract class AbstractMappingContext getPersistentEntities() { try { + read.lock(); - return Collections.unmodifiableSet(new HashSet(persistentEntities.values())); + + return persistentEntities.values().stream()// + .flatMap(it -> Optionals.toStream(it))// + .collect(Collectors.toSet()); + } finally { read.unlock(); } @@ -143,10 +152,21 @@ public abstract class AbstractMappingContext type) { + public Optional getPersistentEntity(Class type) { return getPersistentEntity(ClassTypeInformation.from(type)); } + /* + * (non-Javadoc) + * @see org.springframework.data.mapping.context.MappingContext#getRequiredPersistentEntity(java.lang.Class) + */ + @Override + public E getRequiredPersistentEntity(Class type) { + + return getPersistentEntity(type).orElseThrow( + () -> new IllegalArgumentException(String.format("Couldn't find PersistentEntity for type %s!", type))); + } + /* * (non-Javadoc) * @see org.springframework.data.mapping.context.MappingContext#hasPersistentEntityFor(java.lang.Class) @@ -160,13 +180,15 @@ public abstract class AbstractMappingContext type) { + public Optional getPersistentEntity(TypeInformation type) { Assert.notNull(type, "Type must not be null!"); try { + read.lock(); - E entity = persistentEntities.get(type); + + Optional entity = persistentEntities.get(type); if (entity != null) { return entity; @@ -177,7 +199,15 @@ public abstract class AbstractMappingContext type) { + + return getPersistentEntity(type) + .orElseThrow(() -> new MappingException(String.format("Couldn't find PersistentEntity for type %s!", type))); + } + /* * (non-Javadoc) * @see org.springframework.data.mapping.context.MappingContext#getPersistentEntity(org.springframework.data.mapping.PersistentProperty) */ - public E getPersistentEntity(P persistentProperty) { + public Optional getPersistentEntity(P persistentProperty) { - if (persistentProperty == null) { - return null; - } + Assert.notNull(persistentProperty, "PersistentProperty must not be null!"); TypeInformation typeInfo = persistentProperty.getTypeInformation(); return getPersistentEntity(typeInfo.getActualType()); } + /* + * (non-Javadoc) + * @see org.springframework.data.mapping.context.MappingContext#getRequiredPersistentEntity(org.springframework.data.mapping.PersistentProperty) + */ + @Override + public E getRequiredPersistentEntity(P persistentProperty) { + + return getPersistentEntity(persistentProperty).orElseThrow(() -> new IllegalArgumentException( + String.format("Couldn't find PersistentEntity for type %s!", persistentProperty))); + } + /* * (non-Javadoc) * @see org.springframework.data.mapping.context.MappingContext#getPersistentPropertyPath(java.lang.Class, java.lang.String) @@ -248,7 +298,7 @@ public abstract class AbstractMappingContext path = DefaultPersistentPropertyPath.empty(); Iterator iterator = parts.iterator(); - E current = getPersistentEntity(type); + E current = getRequiredPersistentEntity(type); while (iterator.hasNext()) { @@ -277,8 +327,11 @@ public abstract class AbstractMappingContext persistentProperty = entity.getPersistentProperty(segment); - return persistentProperty.map(it -> Pair.of(path.append(it), - iterator.hasNext() ? getPersistentEntity(it.getTypeInformation().getActualType()) : entity)); + return persistentProperty.map(it -> { + + TypeInformation type = it.getTypeInformation().getActualType(); + return Pair.of(path.append(it), iterator.hasNext() ? getRequiredPersistentEntity(type) : entity); + }); } /** @@ -287,7 +340,7 @@ public abstract class AbstractMappingContext type) { + protected Optional addPersistentEntity(Class type) { return addPersistentEntity(ClassTypeInformation.from(type)); } @@ -297,7 +350,7 @@ public abstract class AbstractMappingContext typeInformation) { + protected Optional addPersistentEntity(TypeInformation typeInformation) { Assert.notNull(typeInformation, "TypeInformation must not be null!"); @@ -305,11 +358,12 @@ public abstract class AbstractMappingContext persistentEntity = persistentEntities.get(typeInformation); if (persistentEntity != null) { return persistentEntity; } + } finally { read.unlock(); } @@ -323,7 +377,7 @@ public abstract class AbstractMappingContext(this, entity)); } - return entity; + return Optional.of(entity); } catch (BeansException e) { throw new MappingException(e.getMessage(), e); @@ -398,8 +452,7 @@ public abstract class AbstractMappingContext field, PropertyDescriptor descriptor, E owner, - SimpleTypeHolder simpleTypeHolder); + protected abstract P createPersistentProperty(Property property, E owner, SimpleTypeHolder simpleTypeHolder); /* * (non-Javadoc) @@ -471,7 +524,7 @@ public abstract class AbstractMappingContext field, PropertyDescriptor descriptor) { + private void createAndRegisterProperty(Property input) { - P property = createPersistentProperty(field, descriptor, entity, simpleTypeHolder); + P property = createPersistentProperty(input, entity, simpleTypeHolder); if (property.isTransient()) { return; } - if (field == null && !property.usePropertyAccess()) { + if (!input.isFieldBacked() && !property.usePropertyAccess()) { return; } entity.addPersistentProperty(property); - - if (property.isAssociation()) { - entity.addAssociation(property.getAssociation()); - } + property.getAssociation().ifPresent(it -> entity.addAssociation(it)); if (entity.getType().equals(property.getRawType())) { return; @@ -533,7 +583,7 @@ public abstract class AbstractMappingContext matches = new HashSet(); + Set matches = new HashSet<>(); matches.add(new PropertyMatch("class", null)); matches.add(new PropertyMatch("this\\$.*", null)); matches.add(new PropertyMatch("metaClass", "groovy.lang.MetaClass")); diff --git a/src/main/java/org/springframework/data/mapping/context/DefaultPersistentPropertyPath.java b/src/main/java/org/springframework/data/mapping/context/DefaultPersistentPropertyPath.java index 819c9eb16..4f2496207 100644 --- a/src/main/java/org/springframework/data/mapping/context/DefaultPersistentPropertyPath.java +++ b/src/main/java/org/springframework/data/mapping/context/DefaultPersistentPropertyPath.java @@ -62,7 +62,7 @@ class DefaultPersistentPropertyPath> implements * @return */ public static > DefaultPersistentPropertyPath empty() { - return new DefaultPersistentPropertyPath(Collections. emptyList()); + return new DefaultPersistentPropertyPath<>(Collections. emptyList()); } /** @@ -77,17 +77,17 @@ class DefaultPersistentPropertyPath> implements Assert.notNull(property, "Property must not be null!"); if (isEmpty()) { - return new DefaultPersistentPropertyPath(Arrays.asList(property)); + return new DefaultPersistentPropertyPath<>(Arrays.asList(property)); } Class leafPropertyType = getLeafProperty().getActualType(); Assert.isTrue(property.getOwner().getType().equals(leafPropertyType), String.format("Cannot append property %s to type %s!", property.getName(), leafPropertyType.getName())); - List properties = new ArrayList(this.properties); + List properties = new ArrayList<>(this.properties); properties.add(property); - return new DefaultPersistentPropertyPath(properties); + return new DefaultPersistentPropertyPath<>(properties); } /* @@ -125,7 +125,7 @@ class DefaultPersistentPropertyPath> implements ? PropertyNameConverter.INSTANCE : converter); String delimiterToUse = delimiter == null ? "." : delimiter; - List result = new ArrayList(); + List result = new ArrayList<>(); for (T property : properties) { @@ -193,7 +193,7 @@ class DefaultPersistentPropertyPath> implements return this; } - List result = new ArrayList(); + List result = new ArrayList<>(); Iterator iterator = iterator(); for (int i = 0; i < base.getLength(); i++) { @@ -204,7 +204,7 @@ class DefaultPersistentPropertyPath> implements result.add(iterator.next()); } - return new DefaultPersistentPropertyPath(result); + return new DefaultPersistentPropertyPath<>(result); } /* @@ -216,7 +216,7 @@ class DefaultPersistentPropertyPath> implements if (size <= 1) { return this; } - return new DefaultPersistentPropertyPath(properties.subList(0, size - 1)); + return new DefaultPersistentPropertyPath<>(properties.subList(0, size - 1)); } /* diff --git a/src/main/java/org/springframework/data/mapping/context/MappingContext.java b/src/main/java/org/springframework/data/mapping/context/MappingContext.java index 9b918252c..3e1a6273b 100644 --- a/src/main/java/org/springframework/data/mapping/context/MappingContext.java +++ b/src/main/java/org/springframework/data/mapping/context/MappingContext.java @@ -16,6 +16,7 @@ package org.springframework.data.mapping.context; import java.util.Collection; +import java.util.Optional; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; @@ -48,7 +49,9 @@ public interface MappingContext, P extends Pers * @param type must not be {@literal null}. * @return */ - E getPersistentEntity(Class type); + Optional getPersistentEntity(Class type); + + E getRequiredPersistentEntity(Class type); /** * Returns whether the {@link MappingContext} currently contains a {@link PersistentEntity} for the type. @@ -67,25 +70,30 @@ public interface MappingContext, P extends Pers * @param type must not be {@literal null}. * @return */ - E getPersistentEntity(TypeInformation type); + Optional getPersistentEntity(TypeInformation type); + + E getRequiredPersistentEntity(TypeInformation type); /** * Returns the {@link PersistentEntity} mapped by the given {@link PersistentProperty}. * - * @param persistentProperty + * @param persistentProperty must not be {@literal null}. * @return the {@link PersistentEntity} mapped by the given {@link PersistentProperty} or null if no * {@link PersistentEntity} exists for it or the {@link PersistentProperty} does not refer to an entity (the * type of the property is considered simple see * {@link org.springframework.data.mapping.model.SimpleTypeHolder#isSimpleType(Class)}). */ - E getPersistentEntity(P persistentProperty); + Optional getPersistentEntity(P persistentProperty); + + E getRequiredPersistentEntity(P persistentProperty); /** * Returns all {@link PersistentProperty}s for the given path expression based on the given {@link PropertyPath}. * * @param propertyPath must not be {@literal null}. * @return the {@link PersistentPropertyPath} representing the given {@link PropertyPath}. - * @throws InvalidPersistentPropertyPath in case not all of the segments of the given {@link PropertyPath} can be resolved. + * @throws InvalidPersistentPropertyPath in case not all of the segments of the given {@link PropertyPath} can be + * resolved. */ PersistentPropertyPath

getPersistentPropertyPath(PropertyPath propertyPath); @@ -100,10 +108,12 @@ public interface MappingContext, P extends Pers PersistentPropertyPath

getPersistentPropertyPath(String propertyPath, Class type); /** - * Returns the {@link PersistentPropertyPath} for the resolvable part of the given {@link InvalidPersistentPropertyPath}. + * Returns the {@link PersistentPropertyPath} for the resolvable part of the given + * {@link InvalidPersistentPropertyPath}. * * @param invalidPath must not be {@literal null}. - * @return the {@link PersistentPropertyPath} for the resolvable part of the given {@link InvalidPersistentPropertyPath}. + * @return the {@link PersistentPropertyPath} for the resolvable part of the given + * {@link InvalidPersistentPropertyPath}. * @since 1.11 */ PersistentPropertyPath

getPersistentPropertyPath(InvalidPersistentPropertyPath invalidPath); diff --git a/src/main/java/org/springframework/data/mapping/context/MappingContextIsNewStrategyFactory.java b/src/main/java/org/springframework/data/mapping/context/MappingContextIsNewStrategyFactory.java index bc0da8bdf..d199f1b4b 100644 --- a/src/main/java/org/springframework/data/mapping/context/MappingContextIsNewStrategyFactory.java +++ b/src/main/java/org/springframework/data/mapping/context/MappingContextIsNewStrategyFactory.java @@ -15,12 +15,15 @@ */ package org.springframework.data.mapping.context; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + import java.util.Arrays; import java.util.Optional; +import java.util.function.Function; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.model.MappingException; import org.springframework.data.support.IsNewStrategy; import org.springframework.data.support.IsNewStrategyFactory; @@ -69,19 +72,25 @@ public class MappingContextIsNewStrategyFactory extends IsNewStrategyFactorySupp @Override protected IsNewStrategy doGetIsNewStrategy(Class type) { - PersistentEntity entity = context.getPersistentEntity(type); + return context.getPersistentEntity(type)// + .flatMap(it -> foo(it))// + .orElseThrow(() -> new MappingException(String.format("Cannot determine IsNewStrategy for type %s!", type))); + } - if (entity == null) { - return null; - } + private static Optional foo(PersistentEntity entity) { if (entity.hasVersionProperty()) { - return new PropertyIsNullOrZeroNumberIsNewStrategy(entity.getVersionProperty().get()); + + return entity.getVersionProperty().map(it -> PersistentPropertyInspectingIsNewStrategy.of(it, + MappingContextIsNewStrategyFactory::propertyIsNullOrZeroNumber)); + } else if (entity.hasIdProperty()) { - return new PropertyIsNullIsNewStrategy(entity.getIdProperty().get()); - } else { - throw new MappingException(String.format("Cannot determine IsNewStrategy for type %s!", type)); + + return entity.getIdProperty().map( + it -> PersistentPropertyInspectingIsNewStrategy.of(it, MappingContextIsNewStrategyFactory::propertyIsNull)); } + + return Optional.empty(); } /** @@ -90,19 +99,11 @@ public class MappingContextIsNewStrategyFactory extends IsNewStrategyFactorySupp * * @author Oliver Gierke */ - static abstract class PersistentPropertyInspectingIsNewStrategy implements IsNewStrategy { - - private final PersistentProperty property; + @RequiredArgsConstructor(staticName = "of") + static class PersistentPropertyInspectingIsNewStrategy implements IsNewStrategy { - /** - * Creates a new {@link PersistentPropertyInspectingIsNewStrategy} using the given {@link PersistentProperty}. - * - * @param property must not be {@literal null}. - */ - public PersistentPropertyInspectingIsNewStrategy(PersistentProperty property) { - Assert.notNull(property, "PersistentProperty must not be null!"); - this.property = property; - } + private final @NonNull PersistentProperty property; + private final @NonNull Function, Boolean> isNew; /* * (non-Javadoc) @@ -111,80 +112,26 @@ public class MappingContextIsNewStrategyFactory extends IsNewStrategyFactorySupp @Override public boolean isNew(Optional entity) { - return entity.map(it -> { - - PersistentPropertyAccessor accessor = property.getOwner().getPropertyAccessor(it); - Object propertyValue = accessor.getProperty(property); - - return decideIsNew(propertyValue); - - }).orElse(false); + return entity// + .map(it -> isNew.apply(property.getOwner().getPropertyAccessor(it).getProperty(property)))// + .orElse(false); } - - protected abstract boolean decideIsNew(Object property); } - /** - * {@link IsNewStrategy} that does a check against {@literal null} for the given value and considers the object new if - * the value given is {@literal null}. - * - * @author Oliver Gierke - */ - static class PropertyIsNullIsNewStrategy extends PersistentPropertyInspectingIsNewStrategy { - - /** - * Creates a new {@link PropertyIsNullIsNewStrategy} using the given {@link PersistentProperty}. - * - * @param property must not be {@literal null}. - */ - public PropertyIsNullIsNewStrategy(PersistentProperty property) { - super(property); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.mapping.model.MappingContextIsNewStrategyFactory.PersistentPropertyInspectingIsNewStrategy#decideIsNew(java.lang.Object) - */ - @Override - protected boolean decideIsNew(Object property) { - return property == null; - } + private static boolean propertyIsNull(Optional it) { + return !it.isPresent(); } - /** - * {@link IsNewStrategy} that considers property values of {@literal null} or 0 (in case of a {@link Number}) - * implementation as indicators for the new state. - * - * @author Oliver Gierke - */ - static class PropertyIsNullOrZeroNumberIsNewStrategy extends PersistentPropertyInspectingIsNewStrategy { - - /** - * Creates a new {@link PropertyIsNullOrZeroNumberIsNewStrategy} instance using the given {@link PersistentProperty} - * . - * - * @param property must not be {@literal null}. - */ - public PropertyIsNullOrZeroNumberIsNewStrategy(PersistentProperty property) { - super(property); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.mapping.model.MappingContextIsNewStrategyFactory.PersistentPropertyInspectingIsNewStrategy#decideIsNew(java.lang.Object) - */ - @Override - protected boolean decideIsNew(Object property) { + private static boolean propertyIsNullOrZeroNumber(Optional it) { - if (property == null) { - return true; - } + return it.map(value -> { - if (!(property instanceof Number)) { + if (!(value instanceof Number)) { return false; } - return ((Number) property).longValue() == 0; - } + return ((Number) value).longValue() == 0; + + }).orElse(true); } } diff --git a/src/main/java/org/springframework/data/mapping/context/PersistentEntities.java b/src/main/java/org/springframework/data/mapping/context/PersistentEntities.java index e63a12d45..245f9751b 100644 --- a/src/main/java/org/springframework/data/mapping/context/PersistentEntities.java +++ b/src/main/java/org/springframework/data/mapping/context/PersistentEntities.java @@ -15,14 +15,12 @@ */ package org.springframework.data.mapping.context; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; import java.util.Iterator; -import java.util.List; -import java.util.Set; +import java.util.Optional; +import java.util.stream.Collectors; import org.springframework.data.mapping.PersistentEntity; +import org.springframework.data.util.Streamable; import org.springframework.data.util.TypeInformation; import org.springframework.util.Assert; @@ -32,9 +30,9 @@ import org.springframework.util.Assert; * @author Oliver Gierke * @since 1.8 */ -public class PersistentEntities implements Iterable> { +public class PersistentEntities implements Streamable> { - private final Iterable> contexts; + private final Streamable> contexts; /** * Creates a new {@link PersistentEntities} for the given {@link MappingContext}s. @@ -44,7 +42,7 @@ public class PersistentEntities implements Iterable> { public PersistentEntities(Iterable> contexts) { Assert.notNull(contexts, "MappingContexts must not be null!"); - this.contexts = contexts; + this.contexts = Streamable.of(contexts); } /** @@ -55,16 +53,11 @@ public class PersistentEntities implements Iterable> { * @param type can be {@literal null}. * @return */ - public PersistentEntity getPersistentEntity(Class type) { + public Optional> getPersistentEntity(Class type) { - for (MappingContext context : contexts) { - - if (context.hasPersistentEntityFor(type)) { - return context.getPersistentEntity(type); - } - } - - return null; + return contexts.stream()// + .filter(it -> it.hasPersistentEntityFor(type))// + .findFirst().map(it -> it.getRequiredPersistentEntity(type)); } /** @@ -72,15 +65,11 @@ public class PersistentEntities implements Iterable> { * * @return */ - public Iterable> getManagedTypes() { - - Set> informations = new HashSet>(); + public Streamable> getManagedTypes() { - for (MappingContext context : contexts) { - informations.addAll(context.getManagedTypes()); - } - - return Collections.unmodifiableSet(informations); + return Streamable.of(contexts.stream()// + .flatMap(it -> it.getManagedTypes().stream())// + .collect(Collectors.toSet())); } /* @@ -90,12 +79,7 @@ public class PersistentEntities implements Iterable> { @Override public Iterator> iterator() { - List> entities = new ArrayList>(); - - for (MappingContext context : contexts) { - entities.addAll(context.getPersistentEntities()); - } - - return entities.iterator(); + return contexts.stream().>flatMap(it -> it.getPersistentEntities().stream()) + .collect(Collectors.toList()).iterator(); } } diff --git a/src/main/java/org/springframework/data/mapping/model/AbstractPersistentProperty.java b/src/main/java/org/springframework/data/mapping/model/AbstractPersistentProperty.java index 256970da1..8e10c7033 100644 --- a/src/main/java/org/springframework/data/mapping/model/AbstractPersistentProperty.java +++ b/src/main/java/org/springframework/data/mapping/model/AbstractPersistentProperty.java @@ -15,7 +15,9 @@ */ package org.springframework.data.mapping.model; -import java.beans.PropertyDescriptor; +import lombok.AccessLevel; +import lombok.Getter; + import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Collections; @@ -26,6 +28,8 @@ import org.springframework.data.annotation.Reference; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; +import org.springframework.data.mapping.PropertyPath; +import org.springframework.data.util.Lazy; import org.springframework.data.util.TypeInformation; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; @@ -46,43 +50,33 @@ public abstract class AbstractPersistentProperty

} protected final String name; - protected final Optional propertyDescriptor; protected final TypeInformation information; protected final Class rawType; - protected final Optional field; - protected final Association

association; - protected final PersistentEntity owner; + protected final Optional> association; + private final @Getter PersistentEntity owner; + private final @Getter(AccessLevel.PROTECTED) Property property; private final SimpleTypeHolder simpleTypeHolder; - private final int hashCode; + private final Lazy hashCode; - public AbstractPersistentProperty(Optional field, PropertyDescriptor propertyDescriptor, - PersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { + public AbstractPersistentProperty(Property property, PersistentEntity owner, + SimpleTypeHolder simpleTypeHolder) { Assert.notNull(simpleTypeHolder, "SimpleTypeHolder must not be null!"); Assert.notNull(owner, "Owner entity must not be null!"); - this.name = field.map(Field::getName).orElseGet(() -> propertyDescriptor.getName()); - this.rawType = field.> map(Field::getType).orElseGet(() -> propertyDescriptor.getPropertyType()); - this.information = owner.getTypeInformation().getProperty(this.name); - this.propertyDescriptor = Optional.ofNullable(propertyDescriptor); - this.field = field; - this.association = isAssociation() ? createAssociation() : null; + this.name = property.getName(); + this.rawType = property.getRawType(); + + this.information = PropertyPath.from(property.getName(), owner.getTypeInformation()).getTypeInformation(); + this.property = property; + this.association = isAssociation() ? Optional.of(createAssociation()) : Optional.empty(); this.owner = owner; this.simpleTypeHolder = simpleTypeHolder; - this.hashCode = this.field == null ? this.propertyDescriptor.hashCode() : this.field.hashCode(); + this.hashCode = Lazy.of(() -> property.hashCode()); } protected abstract Association

createAssociation(); - /* - * (non-Javadoc) - * @see org.springframework.data.mapping.PersistentProperty#getOwner() - */ - @Override - public PersistentEntity getOwner() { - return owner; - } - /* * (non-Javadoc) * @see org.springframework.data.mapping.PersistentProperty#getName() @@ -131,7 +125,7 @@ public abstract class AbstractPersistentProperty

} TypeInformation candidate = getTypeInformationIfEntityCandidate(); - return candidate != null ? Collections.singleton(candidate) : Collections.> emptySet(); + return candidate != null ? Collections.singleton(candidate) : Collections.>emptySet(); } private TypeInformation getTypeInformationIfEntityCandidate() { @@ -151,8 +145,7 @@ public abstract class AbstractPersistentProperty

*/ @Override public Optional getGetter() { - return propertyDescriptor.map(it -> it.getReadMethod())// - .filter(it -> rawType.isAssignableFrom(it.getReturnType())); + return property.getGetter(); } /* @@ -161,8 +154,7 @@ public abstract class AbstractPersistentProperty

*/ @Override public Optional getSetter() { - return propertyDescriptor.map(it -> it.getWriteMethod())// - .filter(it -> it.getParameterTypes()[0].isAssignableFrom(rawType)); + return property.getSetter(); } /* @@ -171,7 +163,7 @@ public abstract class AbstractPersistentProperty

*/ @Override public Optional getField() { - return field; + return property.getField(); } /* @@ -215,7 +207,7 @@ public abstract class AbstractPersistentProperty

* @see org.springframework.data.mapping.PersistentProperty#getAssociation() */ @Override - public Association

getAssociation() { + public Optional> getAssociation() { return association; } @@ -266,8 +258,7 @@ public abstract class AbstractPersistentProperty

return null; } - TypeInformation componentType = information.getComponentType(); - return componentType == null ? null : componentType.getType(); + return information.getRequiredComponentType().getType(); } /* @@ -276,7 +267,7 @@ public abstract class AbstractPersistentProperty

*/ @Override public Class getMapValueType() { - return isMap() ? information.getMapValueType().getType() : null; + return isMap() ? information.getMapValueType().map(it -> it.getType()).orElse(null) : null; } /* @@ -293,7 +284,7 @@ public abstract class AbstractPersistentProperty

* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#usePropertyAccess() */ public boolean usePropertyAccess() { - return owner.getType().isInterface() || CAUSE_FIELD.equals(getField()); + return owner.getType().isInterface() || getField().map(it -> it.equals(CAUSE_FIELD)).orElse(false); } /* @@ -313,7 +304,7 @@ public abstract class AbstractPersistentProperty

AbstractPersistentProperty that = (AbstractPersistentProperty) obj; - return this.field == null ? this.propertyDescriptor.equals(that.propertyDescriptor) : this.field.equals(that.field); + return this.property.equals(that.property); } /* @@ -322,7 +313,7 @@ public abstract class AbstractPersistentProperty

*/ @Override public int hashCode() { - return this.hashCode; + return this.hashCode.get(); } /* @@ -331,8 +322,6 @@ public abstract class AbstractPersistentProperty

*/ @Override public String toString() { - return field.map(Object::toString)// - .orElseGet(() -> propertyDescriptor.map(Object::toString)// - .orElseThrow(() -> new IllegalStateException("Either Field or PropertyDescriptor has to be present!"))); + return property.toString(); } } diff --git a/src/main/java/org/springframework/data/mapping/model/AnnotationBasedPersistentProperty.java b/src/main/java/org/springframework/data/mapping/model/AnnotationBasedPersistentProperty.java index 5cf83bef4..6777ee5cd 100644 --- a/src/main/java/org/springframework/data/mapping/model/AnnotationBasedPersistentProperty.java +++ b/src/main/java/org/springframework/data/mapping/model/AnnotationBasedPersistentProperty.java @@ -15,10 +15,8 @@ */ package org.springframework.data.mapping.model; -import java.beans.PropertyDescriptor; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Field; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -63,15 +61,15 @@ public abstract class AnnotationBasedPersistentProperty

field, PropertyDescriptor propertyDescriptor, - PersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { + public AnnotationBasedPersistentProperty(Property property, PersistentEntity owner, + SimpleTypeHolder simpleTypeHolder) { - super(field, propertyDescriptor, owner, simpleTypeHolder); + super(property, owner, simpleTypeHolder); - populateAnnotationCache(field); + populateAnnotationCache(property); this.usePropertyAccess = findPropertyOrOwnerAnnotation(AccessType.class).map(it -> Type.PROPERTY.equals(it.value())) .orElse(false); @@ -85,9 +83,9 @@ public abstract class AnnotationBasedPersistentProperty

field) { + private final void populateAnnotationCache(Property property) { - Optionals.toStream(getGetter(), getSetter()).forEach(it -> { + Optionals.toStream(property.getGetter(), property.getSetter()).forEach(it -> { for (Annotation annotation : it.getAnnotations()) { @@ -102,7 +100,7 @@ public abstract class AnnotationBasedPersistentProperty

{ + property.getField().ifPresent(it -> { for (Annotation annotation : it.getAnnotations()) { @@ -218,10 +216,11 @@ public abstract class AnnotationBasedPersistentProperty

) annotationCache.get(annotationType); } - return cacheAndReturn(annotationType, getAccessors()// - .map(it -> it.map(inner -> AnnotatedElementUtils.findMergedAnnotation(inner, annotationType)))// - .flatMap(it -> Optionals.toStream(it))// - .findFirst()); + return cacheAndReturn(annotationType, + getAccessors()// + .map(it -> it.map(inner -> AnnotatedElementUtils.findMergedAnnotation(inner, annotationType)))// + .flatMap(it -> Optionals.toStream(it))// + .findFirst()); } /* @@ -232,7 +231,7 @@ public abstract class AnnotationBasedPersistentProperty

Optional findPropertyOrOwnerAnnotation(Class annotationType) { Optional annotation = findAnnotation(annotationType); - return annotation.isPresent() ? annotation : owner.findAnnotation(annotationType); + return annotation.isPresent() ? annotation : getOwner().findAnnotation(annotationType); } /** @@ -277,7 +276,7 @@ public abstract class AnnotationBasedPersistentProperty

> getAccessors() { - return Arrays.> asList(getGetter(), getSetter(), getField()).stream(); + return Arrays.>asList(getGetter(), getSetter(), getField()).stream(); } } diff --git a/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java b/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java index c0f705e5a..4b2568e7e 100644 --- a/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java +++ b/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java @@ -35,6 +35,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.data.annotation.TypeAlias; +import org.springframework.data.mapping.Alias; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.AssociationHandler; import org.springframework.data.mapping.IdentifierAccessor; @@ -79,7 +80,7 @@ public class BasicPersistentEntity> implement private Optional

versionProperty = Optional.empty(); private PersistentPropertyAccessorFactory propertyAccessorFactory; - private final Lazy> typeAlias; + private final Lazy typeAlias; /** * Creates a new {@link BasicPersistentEntity} from the given {@link TypeInformation}. @@ -106,16 +107,17 @@ public class BasicPersistentEntity> implement this.properties = new ArrayList<>(); this.comparator = comparator; this.constructor = new PreferredConstructorDiscoverer<>(this).getConstructor(); - this.associations = comparator.>> map(it -> new TreeSet<>(new AssociationComparator<>(it))) - .orElse(new HashSet<>()); + this.associations = comparator.>>map(it -> new TreeSet<>(new AssociationComparator<>(it))) + .orElseGet(() -> new HashSet<>()); this.propertyCache = new HashMap<>(); this.annotationCache = new HashMap<>(); this.propertyAccessorFactory = BeanWrapperPropertyAccessorFactory.INSTANCE; - this.typeAlias = Lazy - .of(() -> Optional.ofNullable(AnnotatedElementUtils.findMergedAnnotation(getType(), TypeAlias.class))// - .map(TypeAlias::value).filter(it -> StringUtils.hasText(it))); + this.typeAlias = Lazy.of(() -> Alias + .ofOptional(Optional.ofNullable(AnnotatedElementUtils.findMergedAnnotation(getType(), TypeAlias.class))// + .map(TypeAlias::value)// + .filter(it -> StringUtils.hasText(it)))); } /* @@ -304,7 +306,7 @@ public class BasicPersistentEntity> implement * (non-Javadoc) * @see org.springframework.data.mapping.PersistentEntity#getTypeAlias() */ - public Optional getTypeAlias() { + public Alias getTypeAlias() { return typeAlias.get(); } @@ -441,7 +443,7 @@ public class BasicPersistentEntity> implement * @see org.springframework.data.mapping.IdentifierAccessor#getIdentifier() */ @Override - public Optional getIdentifier() { + public Optional getIdentifier() { return Optional.empty(); } } diff --git a/src/main/java/org/springframework/data/mapping/model/BeanWrapper.java b/src/main/java/org/springframework/data/mapping/model/BeanWrapper.java index 482a1511a..b00767956 100644 --- a/src/main/java/org/springframework/data/mapping/model/BeanWrapper.java +++ b/src/main/java/org/springframework/data/mapping/model/BeanWrapper.java @@ -80,7 +80,7 @@ class BeanWrapper implements PersistentPropertyAccessor { * (non-Javadoc) * @see org.springframework.data.mapping.PersistentPropertyAccessor#getProperty(org.springframework.data.mapping.PersistentProperty) */ - public Optional getProperty(PersistentProperty property) { + public Optional getProperty(PersistentProperty property) { return getProperty(property, property.getType()); } diff --git a/src/main/java/org/springframework/data/mapping/model/BeanWrapperPropertyAccessorFactory.java b/src/main/java/org/springframework/data/mapping/model/BeanWrapperPropertyAccessorFactory.java index aa311bfc6..494a10a84 100644 --- a/src/main/java/org/springframework/data/mapping/model/BeanWrapperPropertyAccessorFactory.java +++ b/src/main/java/org/springframework/data/mapping/model/BeanWrapperPropertyAccessorFactory.java @@ -33,7 +33,7 @@ enum BeanWrapperPropertyAccessorFactory implements PersistentPropertyAccessorFac */ @Override public PersistentPropertyAccessor getPropertyAccessor(PersistentEntity entity, Object bean) { - return new BeanWrapper(bean); + return new BeanWrapper<>(bean); } /* diff --git a/src/main/java/org/springframework/data/mapping/model/CamelCaseSplittingFieldNamingStrategy.java b/src/main/java/org/springframework/data/mapping/model/CamelCaseSplittingFieldNamingStrategy.java index fef66ed84..4392298c7 100644 --- a/src/main/java/org/springframework/data/mapping/model/CamelCaseSplittingFieldNamingStrategy.java +++ b/src/main/java/org/springframework/data/mapping/model/CamelCaseSplittingFieldNamingStrategy.java @@ -53,7 +53,7 @@ public class CamelCaseSplittingFieldNamingStrategy implements FieldNamingStrateg public String getFieldName(PersistentProperty property) { List parts = ParsingUtils.splitCamelCaseToLower(property.getName()); - List result = new ArrayList(); + List result = new ArrayList<>(); for (String part : parts) { diff --git a/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java b/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java index cbba64bba..f5d9ddbc7 100644 --- a/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java +++ b/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java @@ -64,9 +64,6 @@ import org.springframework.util.ReflectionUtils; */ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropertyAccessorFactory { - private static final boolean IS_JAVA_7_OR_BETTER = org.springframework.util.ClassUtils - .isPresent("java.lang.invoke.MethodHandle", ClassGeneratingPropertyAccessorFactory.class.getClassLoader()); - private volatile Map, Class> propertyAccessorClasses = new HashMap, Class>( 32); @@ -103,15 +100,11 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert Assert.notNull(entity, "PersistentEntity must not be null!"); - if (!IS_JAVA_7_OR_BETTER) { - return false; - } - if (entity.getType().getClassLoader() == null || entity.getType().getPackage().getName().startsWith("java")) { return false; } - final Set hashCodes = new HashSet(); + final Set hashCodes = new HashSet<>(); final AtomicInteger propertyCount = new AtomicInteger(); entity.doWithProperties(new SimplePropertyHandler() { @@ -821,7 +814,7 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert int[] hashes = new int[propertyStackMap.size()]; Label[] switchJumpLabels = new Label[propertyStackMap.size()]; - List stackmap = new ArrayList(propertyStackMap.values()); + List stackmap = new ArrayList<>(propertyStackMap.values()); Collections.sort(stackmap); for (int i = 0; i < stackmap.size(); i++) { @@ -983,8 +976,8 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert mv.visitLocalVariable(THIS_REF, referenceName(internalClassName), null, l0, l1, 0); mv.visitLocalVariable("property", "Lorg/springframework/data/mapping/PersistentProperty;", "Lorg/springframework/data/mapping/PersistentProperty<*>;", l0, l1, 1); - mv.visitLocalVariable("optional", referenceName(JAVA_UTIL_OPTIONAL), - "Ljava/util/Optional<+Ljava/lang/Object;>;", l0, l1, 2); + mv.visitLocalVariable("optional", referenceName(JAVA_UTIL_OPTIONAL), "Ljava/util/Optional<+Ljava/lang/Object;>;", + l0, l1, 2); if (isAccessible(entity)) { mv.visitLocalVariable(BEAN_FIELD, referenceName(entity.getType()), null, l0, l1, 3); @@ -1022,7 +1015,7 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert int[] hashes = new int[propertyStackMap.size()]; Label[] switchJumpLabels = new Label[propertyStackMap.size()]; - List stackmap = new ArrayList(propertyStackMap.values()); + List stackmap = new ArrayList<>(propertyStackMap.values()); Collections.sort(stackmap); for (int i = 0; i < stackmap.size(); i++) { diff --git a/src/main/java/org/springframework/data/mapping/model/ConvertingPropertyAccessor.java b/src/main/java/org/springframework/data/mapping/model/ConvertingPropertyAccessor.java index aac706809..4e5a398f6 100644 --- a/src/main/java/org/springframework/data/mapping/model/ConvertingPropertyAccessor.java +++ b/src/main/java/org/springframework/data/mapping/model/ConvertingPropertyAccessor.java @@ -65,7 +65,7 @@ public class ConvertingPropertyAccessor implements PersistentPropertyAccessor { * @see org.springframework.data.mapping.PersistentPropertyAccessor#getProperty(org.springframework.data.mapping.PersistentProperty) */ @Override - public Optional getProperty(PersistentProperty property) { + public Optional getProperty(PersistentProperty property) { return accessor.getProperty(property); } diff --git a/src/main/java/org/springframework/data/mapping/model/IdPropertyIdentifierAccessor.java b/src/main/java/org/springframework/data/mapping/model/IdPropertyIdentifierAccessor.java index eddc53d19..334d7bacb 100644 --- a/src/main/java/org/springframework/data/mapping/model/IdPropertyIdentifierAccessor.java +++ b/src/main/java/org/springframework/data/mapping/model/IdPropertyIdentifierAccessor.java @@ -56,7 +56,7 @@ public class IdPropertyIdentifierAccessor implements IdentifierAccessor { * (non-Javadoc) * @see org.springframework.data.keyvalue.core.IdentifierAccessor#getIdentifier() */ - public Optional getIdentifier() { - return idProperty.map(it -> accessor.getProperty(it)); + public Optional getIdentifier() { + return idProperty.flatMap(it -> accessor.getProperty(it)); } } diff --git a/src/main/java/org/springframework/data/mapping/model/Property.java b/src/main/java/org/springframework/data/mapping/model/Property.java new file mode 100644 index 000000000..ceef9d067 --- /dev/null +++ b/src/main/java/org/springframework/data/mapping/model/Property.java @@ -0,0 +1,138 @@ +/* + * Copyright 2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.mapping.model; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Optional; + +import org.springframework.data.util.Lazy; +import org.springframework.util.Assert; + +/** + * @author Oliver Gierke + */ +@RequiredArgsConstructor +public class Property { + + private final @Getter Optional field; + private final Optional descriptor; + + private final Lazy> rawType; + private final Lazy hashCode; + + private Property(Optional field, Optional descriptor) { + + this.field = field; + this.descriptor = descriptor; + this.hashCode = Lazy.of(() -> computeHashCode()); + this.rawType = Lazy + .of(() -> field.>map(Field::getType).orElseGet(() -> descriptor.map(it -> it.getPropertyType())// + .orElseThrow(() -> new IllegalStateException()))); + } + + public static Property of(Field field) { + return of(field, Optional.empty()); + } + + public static Property of(Field field, Optional descriptor) { + + Assert.notNull(field, "Field must not be null!"); + + return new Property(Optional.of(field), descriptor); + } + + public static Property of(PropertyDescriptor descriptor) { + + Assert.notNull(descriptor, "PropertyDescriptor must not be null!"); + return new Property(Optional.empty(), Optional.of(descriptor)); + } + + public boolean isFieldBacked() { + return field.isPresent(); + } + + public Optional getGetter() { + return descriptor.map(it -> it.getReadMethod())// + .filter(it -> getRawType().isAssignableFrom(it.getReturnType())); + } + + public Optional getSetter() { + return descriptor.map(it -> it.getWriteMethod())// + .filter(it -> it.getParameterTypes()[0].isAssignableFrom(getRawType())); + } + + /** + * @return + */ + public String getName() { + return field.map(Field::getName).orElseGet(() -> descriptor.map(it -> it.getName())// + .orElseThrow(() -> new IllegalStateException())); + } + + public Class getRawType() { + return rawType.get(); + } + + private int computeHashCode() { + + return this.field.map(it -> it.hashCode()) + .orElseGet(() -> this.descriptor.map(it -> it.hashCode()).orElseThrow(() -> new IllegalStateException())); + } + + /* + * (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return hashCode.get(); + } + + /* + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof Property)) { + return false; + } + + Property that = (Property) obj; + + return this.field.isPresent() ? this.field.equals(that.field) : this.descriptor.equals(that.descriptor); + } + + /* + * (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return field.map(Object::toString) + .orElseGet(() -> descriptor.map(Object::toString).orElseThrow(() -> new IllegalStateException())); + } +} diff --git a/src/main/java/org/springframework/data/mapping/model/SpELExpressionParameterValueProvider.java b/src/main/java/org/springframework/data/mapping/model/SpELExpressionParameterValueProvider.java index ea6b41b2e..3e404d8ed 100644 --- a/src/main/java/org/springframework/data/mapping/model/SpELExpressionParameterValueProvider.java +++ b/src/main/java/org/springframework/data/mapping/model/SpELExpressionParameterValueProvider.java @@ -62,13 +62,10 @@ public class SpELExpressionParameterValueProvider

Optional getParameterValue(Parameter parameter) { - if (!parameter.hasSpelExpression()) { - return delegate.getParameterValue(parameter); - } - - Optional object = Optional.ofNullable(evaluator.evaluate(parameter.getSpelExpression().orElse(null))); - - return object.map(it -> potentiallyConvertSpelValue(object, parameter)); + return parameter.getSpelExpression()// + .map(it -> Optional.ofNullable(evaluator.evaluate(it))// + .map(result -> potentiallyConvertSpelValue(result, parameter))) + .orElseGet(() -> delegate.getParameterValue(parameter)); } /** diff --git a/src/main/java/org/springframework/data/projection/ProjectingMethodInterceptor.java b/src/main/java/org/springframework/data/projection/ProjectingMethodInterceptor.java index f09c347a4..eb2e990ed 100644 --- a/src/main/java/org/springframework/data/projection/ProjectingMethodInterceptor.java +++ b/src/main/java/org/springframework/data/projection/ProjectingMethodInterceptor.java @@ -107,11 +107,11 @@ class ProjectingMethodInterceptor implements MethodInterceptor { sources.size()); for (Object source : sources) { - result.add(getProjection(source, type.getComponentType().getType())); + result.add(getProjection(source, type.getRequiredComponentType().getType())); } if (rawType.isArray()) { - return result.toArray((Object[]) Array.newInstance(type.getComponentType().getType(), result.size())); + return result.toArray((Object[]) Array.newInstance(type.getRequiredComponentType().getType(), result.size())); } return result; @@ -130,7 +130,7 @@ class ProjectingMethodInterceptor implements MethodInterceptor { Map result = CollectionFactory.createMap(type.getType(), sources.size()); for (Entry source : sources.entrySet()) { - result.put(source.getKey(), getProjection(source.getValue(), type.getMapValueType().getType())); + result.put(source.getKey(), getProjection(source.getValue(), type.getRequiredMapValueType().getType())); } return result; diff --git a/src/main/java/org/springframework/data/projection/ProxyProjectionFactory.java b/src/main/java/org/springframework/data/projection/ProxyProjectionFactory.java index 94f07e004..cd31e0622 100644 --- a/src/main/java/org/springframework/data/projection/ProxyProjectionFactory.java +++ b/src/main/java/org/springframework/data/projection/ProxyProjectionFactory.java @@ -144,7 +144,7 @@ class ProxyProjectionFactory implements ProjectionFactory, ResourceLoaderAware, Assert.notNull(projectionType, "Projection type must not be null!"); - List result = new ArrayList(); + List result = new ArrayList<>(); for (PropertyDescriptor descriptor : getProjectionInformation(projectionType).getInputProperties()) { result.add(descriptor.getName()); diff --git a/src/main/java/org/springframework/data/projection/SpelAwareProxyProjectionFactory.java b/src/main/java/org/springframework/data/projection/SpelAwareProxyProjectionFactory.java index 5493d5e4d..7ad511b57 100644 --- a/src/main/java/org/springframework/data/projection/SpelAwareProxyProjectionFactory.java +++ b/src/main/java/org/springframework/data/projection/SpelAwareProxyProjectionFactory.java @@ -70,7 +70,7 @@ public class SpelAwareProxyProjectionFactory extends ProxyProjectionFactory impl if (!typeCache.containsKey(projectionType)) { - AnnotationDetectionMethodCallback callback = new AnnotationDetectionMethodCallback(Value.class); + AnnotationDetectionMethodCallback callback = new AnnotationDetectionMethodCallback<>(Value.class); ReflectionUtils.doWithMethods(projectionType, callback); typeCache.put(projectionType, callback.hasFoundAnnotation()); diff --git a/src/main/java/org/springframework/data/querydsl/QPageRequest.java b/src/main/java/org/springframework/data/querydsl/QPageRequest.java index 6bb97d6f7..bb9f4ee6f 100644 --- a/src/main/java/org/springframework/data/querydsl/QPageRequest.java +++ b/src/main/java/org/springframework/data/querydsl/QPageRequest.java @@ -17,6 +17,7 @@ package org.springframework.data.querydsl; import org.springframework.data.domain.AbstractPageRequest; import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import com.querydsl.core.types.OrderSpecifier; @@ -39,7 +40,7 @@ public class QPageRequest extends AbstractPageRequest { * @param size */ public QPageRequest(int page, int size) { - this(page, size, (QSort) null); + this(page, size, QSort.unsorted()); } /** @@ -71,7 +72,7 @@ public class QPageRequest extends AbstractPageRequest { * @see org.springframework.data.domain.Pageable#getSort() */ @Override - public QSort getSort() { + public Sort getSort() { return sort; } @@ -81,7 +82,7 @@ public class QPageRequest extends AbstractPageRequest { */ @Override public Pageable next() { - return new QPageRequest(getPageNumber() + 1, getPageSize(), getSort()); + return new QPageRequest(getPageNumber() + 1, getPageSize(), sort); } /* @@ -90,7 +91,7 @@ public class QPageRequest extends AbstractPageRequest { */ @Override public Pageable previous() { - return new QPageRequest(getPageNumber() - 1, getPageSize(), getSort()); + return new QPageRequest(getPageNumber() - 1, getPageSize(), sort); } /* @@ -99,6 +100,6 @@ public class QPageRequest extends AbstractPageRequest { */ @Override public Pageable first() { - return new QPageRequest(0, getPageSize(), getSort()); + return new QPageRequest(0, getPageSize(), sort); } } diff --git a/src/main/java/org/springframework/data/querydsl/QSort.java b/src/main/java/org/springframework/data/querydsl/QSort.java index 2e1307155..ead8331ed 100644 --- a/src/main/java/org/springframework/data/querydsl/QSort.java +++ b/src/main/java/org/springframework/data/querydsl/QSort.java @@ -19,6 +19,7 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; import org.springframework.data.domain.Sort; import org.springframework.util.Assert; @@ -36,13 +37,14 @@ import com.querydsl.core.types.Path; public class QSort extends Sort implements Serializable { private static final long serialVersionUID = -6701117396842171930L; + private static final QSort UNSORTED = new QSort(); private final List> orderSpecifiers; /** * Creates a new {@link QSort} instance with the given {@link OrderSpecifier}s. * - * @param orderSpecifiers must not be {@literal null} or empty. + * @param orderSpecifiers must not be {@literal null} . */ public QSort(OrderSpecifier... orderSpecifiers) { this(Arrays.asList(orderSpecifiers)); @@ -51,16 +53,24 @@ public class QSort extends Sort implements Serializable { /** * Creates a new {@link QSort} instance with the given {@link OrderSpecifier}s. * - * @param orderSpecifiers must not be {@literal null} or empty. + * @param orderSpecifiers must not be {@literal null}. */ + public QSort(List> orderSpecifiers) { super(toOrders(orderSpecifiers)); - Assert.notEmpty(orderSpecifiers, "Order specifiers must not be null or empty!"); this.orderSpecifiers = orderSpecifiers; } + public static QSort by(OrderSpecifier... orderSpecifiers) { + return new QSort(orderSpecifiers); + } + + public static QSort unsorted() { + return UNSORTED; + } + /** * Converts the given {@link OrderSpecifier}s into a list of {@link Order}s. * @@ -69,14 +79,9 @@ public class QSort extends Sort implements Serializable { */ private static List toOrders(List> orderSpecifiers) { - Assert.notEmpty(orderSpecifiers, "Order specifiers must not be null or empty!"); - - List orders = new ArrayList(); - for (OrderSpecifier orderSpecifier : orderSpecifiers) { - orders.add(toOrder(orderSpecifier)); - } + Assert.notNull(orderSpecifiers, "Order specifiers must not be null!"); - return orders; + return orderSpecifiers.stream().map(QSort::toOrder).collect(Collectors.toList()); } /** diff --git a/src/main/java/org/springframework/data/querydsl/QuerydslRepositoryInvokerAdapter.java b/src/main/java/org/springframework/data/querydsl/QuerydslRepositoryInvokerAdapter.java index 176095723..d9a334d9f 100644 --- a/src/main/java/org/springframework/data/querydsl/QuerydslRepositoryInvokerAdapter.java +++ b/src/main/java/org/springframework/data/querydsl/QuerydslRepositoryInvokerAdapter.java @@ -57,18 +57,18 @@ public class QuerydslRepositoryInvokerAdapter implements RepositoryInvoker { this.predicate = predicate; } - /* + /* * (non-Javadoc) - * @see org.springframework.data.repository.support.RepositoryInvoker#invokeFindAll(org.springframework.data.domain.Pageable) + * @see org.springframework.data.repository.support.RepositoryInvoker#invokePagedFindAll(org.springframework.data.domain.Pageable) */ @Override public Iterable invokeFindAll(Pageable pageable) { return executor.findAll(predicate, pageable); } - /* + /* * (non-Javadoc) - * @see org.springframework.data.repository.support.RepositoryInvoker#invokeFindAll(org.springframework.data.domain.Sort) + * @see org.springframework.data.repository.support.RepositoryInvoker#invokeSortedFindAll(org.springframework.data.domain.Sort) */ @Override public Iterable invokeFindAll(Sort sort) { @@ -129,7 +129,7 @@ public class QuerydslRepositoryInvokerAdapter implements RepositoryInvoker { return delegate.invokeFindOne(id); } - /* + /* * (non-Javadoc) * @see org.springframework.data.repository.support.RepositoryInvoker#invokeQueryMethod(java.lang.reflect.Method, org.springframework.util.MultiValueMap, org.springframework.data.domain.Pageable, org.springframework.data.domain.Sort) */ diff --git a/src/main/java/org/springframework/data/querydsl/binding/MultiValueBinding.java b/src/main/java/org/springframework/data/querydsl/binding/MultiValueBinding.java index e8014f8f2..0e49f463c 100644 --- a/src/main/java/org/springframework/data/querydsl/binding/MultiValueBinding.java +++ b/src/main/java/org/springframework/data/querydsl/binding/MultiValueBinding.java @@ -38,8 +38,8 @@ public interface MultiValueBinding, S> { * * @param path {@link Path} to the property. Will not be {@literal null}. * @param value the value that should be bound. Will not be {@literal null} or empty. - * @return can be {@literal null}, in which case the binding will not be incorporated in the overall {@link Predicate} - * . + * @return can be {@literal null}, in which case the binding will not be incorporated in the overall + * {@link Predicate}. */ Optional bind(T path, Collection value); } diff --git a/src/main/java/org/springframework/data/querydsl/binding/QuerydslBindings.java b/src/main/java/org/springframework/data/querydsl/binding/QuerydslBindings.java index c716f5ead..77d17ca04 100644 --- a/src/main/java/org/springframework/data/querydsl/binding/QuerydslBindings.java +++ b/src/main/java/org/springframework/data/querydsl/binding/QuerydslBindings.java @@ -81,9 +81,9 @@ public class QuerydslBindings { this.pathSpecs = new LinkedHashMap>(); this.typeSpecs = new LinkedHashMap, PathAndBinding>(); - this.whiteList = new HashSet(); - this.blackList = new HashSet(); - this.aliases = new HashSet(); + this.whiteList = new HashSet<>(); + this.blackList = new HashSet<>(); + this.aliases = new HashSet<>(); } @@ -115,7 +115,7 @@ public class QuerydslBindings { * @return */ public final TypeBinder bind(Class type) { - return new TypeBinder(type); + return new TypeBinder<>(type); } /** @@ -502,7 +502,7 @@ public class QuerydslBindings { Assert.notNull(binding, "Binding must not be null!"); - QuerydslBindings.this.typeSpecs.put(type, PathAndBinding. withoutPath().with(binding)); + QuerydslBindings.this.typeSpecs.put(type, PathAndBinding.withoutPath().with(binding)); } } diff --git a/src/main/java/org/springframework/data/querydsl/binding/QuerydslPredicateBuilder.java b/src/main/java/org/springframework/data/querydsl/binding/QuerydslPredicateBuilder.java index 4d914b8a5..9945ca40a 100644 --- a/src/main/java/org/springframework/data/querydsl/binding/QuerydslPredicateBuilder.java +++ b/src/main/java/org/springframework/data/querydsl/binding/QuerydslPredicateBuilder.java @@ -148,7 +148,37 @@ public class QuerydslPredicateBuilder { Optional> resolvedPath = bindings.getExistingPath(path); - return resolvedPath.orElseGet(() -> paths.computeIfAbsent(path, it -> path.reifyPath(resolver))); + return resolvedPath.orElseGet(() -> paths.computeIfAbsent(path, it -> reifyPath(path, Optional.empty()))); + } + + /** + * Tries to reify a Querydsl {@link Path} from the given {@link PropertyPath} and base. + * + * @param path must not be {@literal null}. + * @param base can be empty. + * @return + */ + private Path reifyPath(PropertyPath path, Optional> base) { + + Optional> map = base.filter(it -> it instanceof CollectionPathBase) + .map(it -> CollectionPathBase.class.cast(it))// + .map(CollectionPathBase::any)// + .map(it -> Path.class.cast(it))// + .map(it -> reifyPath(path, Optional.of(it))); + + return map.orElseGet(() -> { + + Path entityPath = base.orElseGet(() -> resolver.createPath(path.getOwningType().getType())); + + Field field = ReflectionUtils.findField(entityPath.getClass(), path.getSegment()); + Object value = ReflectionUtils.getField(field, entityPath); + + if (path.hasNext()) { + return reifyPath(path.next(), Optional.of((Path) value)); + } + + return (Path) value; + }); } /** @@ -162,13 +192,13 @@ public class QuerydslPredicateBuilder { */ private Collection convertToPropertyPathSpecificType(List source, PathInformation path) { - Class targetType = path.getLeafType(); + Class targetType = path.getLeafProperty().getType(); if (source.isEmpty() || isSingleElementCollectionWithoutText(source)) { return Collections.emptyList(); } - Collection target = new ArrayList(source.size()); + Collection target = new ArrayList<>(source.size()); for (String value : source) { diff --git a/src/main/java/org/springframework/data/repository/PagingAndSortingRepository.java b/src/main/java/org/springframework/data/repository/PagingAndSortingRepository.java index 3a4b2d206..74137baef 100644 --- a/src/main/java/org/springframework/data/repository/PagingAndSortingRepository.java +++ b/src/main/java/org/springframework/data/repository/PagingAndSortingRepository.java @@ -47,5 +47,5 @@ public interface PagingAndSortingRepository extends * @param pageable * @return a page of entities */ - Page findAll(Pageable pageable); + Page findAll(Pageable pageable); } diff --git a/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryBean.java b/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryBean.java index 5da0b70df..6ee5ecaf7 100644 --- a/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryBean.java +++ b/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryBean.java @@ -110,7 +110,7 @@ public abstract class CdiRepositoryBean implements Bean, PassivationCapabl */ private final String createPassivationId(Set qualifiers, Class repositoryType) { - List qualifierNames = new ArrayList(qualifiers.size()); + List qualifierNames = new ArrayList<>(qualifiers.size()); for (Annotation qualifier : qualifiers) { qualifierNames.add(qualifier.annotationType().getName()); @@ -131,11 +131,11 @@ public abstract class CdiRepositoryBean implements Bean, PassivationCapabl @SuppressWarnings("rawtypes") public Set getTypes() { - Set interfaces = new HashSet(); + Set interfaces = new HashSet<>(); interfaces.add(repositoryType); interfaces.addAll(Arrays.asList(repositoryType.getInterfaces())); - return new HashSet(interfaces); + return new HashSet<>(interfaces); } /** diff --git a/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryExtensionSupport.java b/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryExtensionSupport.java index 05c00c14d..063e386c6 100644 --- a/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryExtensionSupport.java +++ b/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryExtensionSupport.java @@ -119,7 +119,7 @@ public abstract class CdiRepositoryExtensionSupport implements Extension { */ private Set getQualifiers(final Class type) { - Set qualifiers = new HashSet(); + Set qualifiers = new HashSet<>(); Annotation[] annotations = type.getAnnotations(); for (Annotation annotation : annotations) { Class annotationType = annotation.annotationType(); diff --git a/src/main/java/org/springframework/data/repository/config/AnnotationRepositoryConfigurationSource.java b/src/main/java/org/springframework/data/repository/config/AnnotationRepositoryConfigurationSource.java index 9d4259da7..eb14ad074 100644 --- a/src/main/java/org/springframework/data/repository/config/AnnotationRepositoryConfigurationSource.java +++ b/src/main/java/org/springframework/data/repository/config/AnnotationRepositoryConfigurationSource.java @@ -124,7 +124,7 @@ public class AnnotationRepositoryConfigurationSource extends RepositoryConfigura return Collections.singleton(ClassUtils.getPackageName(className)); } - Set packages = new HashSet(); + Set packages = new HashSet<>(); packages.addAll(Arrays.asList(value)); packages.addAll(Arrays.asList(basePackages)); @@ -187,7 +187,7 @@ public class AnnotationRepositoryConfigurationSource extends RepositoryConfigura private Set parseFilters(String attributeName) { - Set result = new HashSet(); + Set result = new HashSet<>(); AnnotationAttributes[] filters = attributes.getAnnotationArray(attributeName); for (AnnotationAttributes filter : filters) { @@ -259,7 +259,7 @@ public class AnnotationRepositoryConfigurationSource extends RepositoryConfigura */ private List typeFiltersFor(AnnotationAttributes filterAttributes) { - List typeFilters = new ArrayList(); + List typeFilters = new ArrayList<>(); FilterType filterType = filterAttributes.getEnum("type"); for (Class filterClass : filterAttributes.getClassArray("value")) { diff --git a/src/main/java/org/springframework/data/repository/config/CustomRepositoryImplementationDetector.java b/src/main/java/org/springframework/data/repository/config/CustomRepositoryImplementationDetector.java index 8c22fd22d..6741a8b47 100644 --- a/src/main/java/org/springframework/data/repository/config/CustomRepositoryImplementationDetector.java +++ b/src/main/java/org/springframework/data/repository/config/CustomRepositoryImplementationDetector.java @@ -94,7 +94,7 @@ public class CustomRepositoryImplementationDetector { provider.addExcludeFilter(excludeFilter); } - Set definitions = new HashSet(); + Set definitions = new HashSet<>(); for (String basePackage : basePackages) { definitions.addAll(provider.findCandidateComponents(basePackage)); diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java b/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java index bfb09e759..a000058ec 100644 --- a/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java +++ b/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java @@ -89,7 +89,8 @@ class RepositoryBeanDefinitionBuilder { builder.addConstructorArgValue(configuration.getRepositoryInterface()); builder.addPropertyValue("queryLookupStrategyKey", configuration.getQueryLookupStrategyKey()); builder.addPropertyValue("lazyInit", configuration.isLazyInit()); - builder.addPropertyValue("repositoryBaseClass", configuration.getRepositoryBaseClassName()); + builder.addPropertyValue("repositoryBaseClass", + configuration.getRepositoryBaseClassName().orElseGet(() -> extension.getRepositoryFactoryClassName())); NamedQueriesBeanDefinitionBuilder definitionBuilder = new NamedQueriesBeanDefinitionBuilder( extension.getDefaultNamedQueryLocation()); diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryComponentProvider.java b/src/main/java/org/springframework/data/repository/config/RepositoryComponentProvider.java index 6d1a9f979..fedda5f32 100644 --- a/src/main/java/org/springframework/data/repository/config/RepositoryComponentProvider.java +++ b/src/main/java/org/springframework/data/repository/config/RepositoryComponentProvider.java @@ -85,13 +85,13 @@ class RepositoryComponentProvider extends ClassPathScanningCandidateComponentPro @Override public void addIncludeFilter(TypeFilter includeFilter) { - List filterPlusInterface = new ArrayList(2); + List filterPlusInterface = new ArrayList<>(2); filterPlusInterface.add(includeFilter); filterPlusInterface.add(new InterfaceTypeFilter(Repository.class)); super.addIncludeFilter(new AllTypeFilter(filterPlusInterface)); - List filterPlusAnnotation = new ArrayList(2); + List filterPlusAnnotation = new ArrayList<>(2); filterPlusAnnotation.add(includeFilter); filterPlusAnnotation.add(new AnnotationTypeFilter(RepositoryDefinition.class, true, true)); diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationDelegate.java b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationDelegate.java index 85588314e..105abce74 100644 --- a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationDelegate.java +++ b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationDelegate.java @@ -117,7 +117,7 @@ public class RepositoryConfigurationDelegate { RepositoryBeanDefinitionBuilder builder = new RepositoryBeanDefinitionBuilder(registry, extension, resourceLoader, environment); - List definitions = new ArrayList(); + List definitions = new ArrayList<>(); for (RepositoryConfiguration configuration : extension .getRepositoryConfigurations(configurationSource, resourceLoader, inMultiStoreMode)) { diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java index e070032a8..9d3173317 100644 --- a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java +++ b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java @@ -239,7 +239,7 @@ public abstract class RepositoryConfigurationExtensionSupport implements Reposit */ protected RepositoryConfiguration getRepositoryConfiguration( BeanDefinition definition, T configSource) { - return new DefaultRepositoryConfiguration(configSource, definition); + return new DefaultRepositoryConfiguration<>(configSource, definition); } /** diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationSourceSupport.java b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationSourceSupport.java index 3072d9c66..716a100f6 100644 --- a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationSourceSupport.java +++ b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationSourceSupport.java @@ -65,7 +65,7 @@ public abstract class RepositoryConfigurationSourceSupport implements Repository scanner.addExcludeFilter(filter); } - Set result = new HashSet(); + Set result = new HashSet<>(); for (String basePackage : getBasePackages()) { Set candidate = scanner.findCandidateComponents(basePackage); diff --git a/src/main/java/org/springframework/data/repository/core/EntityInformation.java b/src/main/java/org/springframework/data/repository/core/EntityInformation.java index bb05a7774..74218549e 100644 --- a/src/main/java/org/springframework/data/repository/core/EntityInformation.java +++ b/src/main/java/org/springframework/data/repository/core/EntityInformation.java @@ -16,6 +16,7 @@ package org.springframework.data.repository.core; import java.io.Serializable; +import java.util.Optional; /** * Extension of {@link EntityMetadata} to add functionality to query information of entity instances. @@ -38,7 +39,7 @@ public interface EntityInformation extends EntityMet * @param entity must never be {@literal null} * @return */ - ID getId(T entity); + Optional getId(T entity); /** * Returns the type of the id of the entity. diff --git a/src/main/java/org/springframework/data/repository/core/support/AbstractEntityInformation.java b/src/main/java/org/springframework/data/repository/core/support/AbstractEntityInformation.java index 3e8a9513b..bb072771f 100644 --- a/src/main/java/org/springframework/data/repository/core/support/AbstractEntityInformation.java +++ b/src/main/java/org/springframework/data/repository/core/support/AbstractEntityInformation.java @@ -16,6 +16,7 @@ package org.springframework.data.repository.core.support; import java.io.Serializable; +import java.util.Optional; import org.springframework.data.repository.core.EntityInformation; import org.springframework.util.Assert; @@ -48,18 +49,22 @@ public abstract class AbstractEntityInformation impl */ public boolean isNew(T entity) { - ID id = getId(entity); + Optional id = getId(entity); Class idType = getIdType(); if (!idType.isPrimitive()) { - return id == null; + return !id.isPresent(); } - if (id instanceof Number) { - return ((Number) id).longValue() == 0L; - } + return id.map(it -> { + + if (it instanceof Number) { + return ((Number) it).longValue() == 0L; + } + + return null; - throw new IllegalArgumentException(String.format("Unsupported primitive id type %s!", idType)); + }).orElseThrow(() -> new IllegalArgumentException(String.format("Unsupported primitive id type %s!", idType))); } /* diff --git a/src/main/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadata.java b/src/main/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadata.java index 4614489e0..b7594ff43 100644 --- a/src/main/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadata.java +++ b/src/main/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadata.java @@ -149,6 +149,6 @@ public abstract class AbstractRepositoryMetadata implements RepositoryMetadata { boolean needToUnwrap = Iterable.class.isAssignableFrom(rawType) || rawType.isArray() || QueryExecutionConverters.supports(rawType) || ReflectionUtils.isJava8StreamType(rawType); - return needToUnwrap ? unwrapWrapperTypes(type.getComponentType()) : rawType; + return needToUnwrap ? unwrapWrapperTypes(type.getRequiredComponentType()) : rawType; } } diff --git a/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryInformation.java b/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryInformation.java index 5c1ca2722..8b9d7aaec 100644 --- a/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryInformation.java +++ b/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryInformation.java @@ -76,8 +76,9 @@ class DefaultRepositoryInformation implements RepositoryInformation { public DefaultRepositoryInformation(RepositoryMetadata metadata, Class repositoryBaseClass, Optional> customImplementationClass) { - Assert.notNull(metadata, "Metadata must not be null!"); - Assert.notNull(repositoryBaseClass, "RepositoryBaseClass must not be null!"); + Assert.notNull(metadata, "Repository metadata must not be null!"); + Assert.notNull(repositoryBaseClass, "Repository base class must not be null!"); + Assert.notNull(customImplementationClass, "Custom implementation class must not be null!"); this.metadata = metadata; this.repositoryBaseClass = repositoryBaseClass; @@ -162,7 +163,7 @@ class DefaultRepositoryInformation implements RepositoryInformation { @Override public Streamable getQueryMethods() { - Set result = new HashSet(); + Set result = new HashSet<>(); for (Method method : getRepositoryInterface().getMethods()) { method = ClassUtils.getMostSpecificMethod(method, getRepositoryInterface()); diff --git a/src/main/java/org/springframework/data/repository/core/support/DelegatingEntityInformation.java b/src/main/java/org/springframework/data/repository/core/support/DelegatingEntityInformation.java index 7a11e4f68..2986b3349 100644 --- a/src/main/java/org/springframework/data/repository/core/support/DelegatingEntityInformation.java +++ b/src/main/java/org/springframework/data/repository/core/support/DelegatingEntityInformation.java @@ -16,6 +16,7 @@ package org.springframework.data.repository.core.support; import java.io.Serializable; +import java.util.Optional; import org.springframework.data.repository.core.EntityInformation; import org.springframework.util.Assert; @@ -62,7 +63,7 @@ public class DelegatingEntityInformation implements * (non-Javadoc) * @see org.springframework.data.repository.core.EntityInformation#getId(java.lang.Object) */ - public ID getId(T entity) { + public Optional getId(T entity) { return delegate.getId(entity); } diff --git a/src/main/java/org/springframework/data/repository/core/support/PersistableEntityInformation.java b/src/main/java/org/springframework/data/repository/core/support/PersistableEntityInformation.java index bb55c2ee6..c48b13f45 100644 --- a/src/main/java/org/springframework/data/repository/core/support/PersistableEntityInformation.java +++ b/src/main/java/org/springframework/data/repository/core/support/PersistableEntityInformation.java @@ -16,6 +16,7 @@ package org.springframework.data.repository.core.support; import java.io.Serializable; +import java.util.Optional; import org.springframework.core.GenericTypeResolver; import org.springframework.data.domain.Persistable; @@ -27,8 +28,8 @@ import org.springframework.data.repository.core.EntityMetadata; * * @author Oliver Gierke */ -public class PersistableEntityInformation, ID extends Serializable> extends - AbstractEntityInformation { +public class PersistableEntityInformation, ID extends Serializable> + extends AbstractEntityInformation { private Class idClass; @@ -45,34 +46,29 @@ public class PersistableEntityInformation, ID extends } /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.support.IsNewAware#isNew(java.lang - * .Object) - */ + * (non-Javadoc) + * @see org.springframework.data.repository.core.support.AbstractEntityInformation#isNew(java.lang.Object) + */ @Override public boolean isNew(T entity) { - return entity.isNew(); } /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.support.IdAware#getId(java.lang.Object - * ) - */ - public ID getId(T entity) { - - return entity.getId(); + * (non-Javadoc) + * @see org.springframework.data.repository.core.EntityInformation#getId(java.lang.Object) + */ + @Override + public Optional getId(T entity) { + return Optional.ofNullable(entity.getId()); } - /* (non-Javadoc) - * @see org.springframework.data.repository.support.EntityInformation#getIdType() - */ + /* + * (non-Javadoc) + * @see org.springframework.data.repository.core.EntityInformation#getIdType() + */ + @Override public Class getIdType() { return this.idClass; } -} \ No newline at end of file +} diff --git a/src/main/java/org/springframework/data/repository/core/support/PersistentEntityInformation.java b/src/main/java/org/springframework/data/repository/core/support/PersistentEntityInformation.java index b50e4e0bb..4f505ab5c 100644 --- a/src/main/java/org/springframework/data/repository/core/support/PersistentEntityInformation.java +++ b/src/main/java/org/springframework/data/repository/core/support/PersistentEntityInformation.java @@ -16,6 +16,7 @@ package org.springframework.data.repository.core.support; import java.io.Serializable; +import java.util.Optional; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.repository.core.EntityInformation; @@ -47,8 +48,8 @@ public class PersistentEntityInformation extends Abs * @see org.springframework.data.repository.core.EntityInformation#getId(java.lang.Object) */ @Override - public ID getId(T entity) { - return (ID) persistentEntity.getIdentifierAccessor(entity).getIdentifier().orElse(null); + public Optional getId(T entity) { + return persistentEntity.getIdentifierAccessor(entity).getIdentifier().map(it -> (ID) it); } /* diff --git a/src/main/java/org/springframework/data/repository/core/support/ReflectionEntityInformation.java b/src/main/java/org/springframework/data/repository/core/support/ReflectionEntityInformation.java index 34224de8a..819014d48 100644 --- a/src/main/java/org/springframework/data/repository/core/support/ReflectionEntityInformation.java +++ b/src/main/java/org/springframework/data/repository/core/support/ReflectionEntityInformation.java @@ -18,13 +18,12 @@ package org.springframework.data.repository.core.support; import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.Field; +import java.util.Optional; import org.springframework.data.annotation.Id; import org.springframework.data.repository.core.EntityInformation; -import org.springframework.data.repository.core.support.AbstractEntityInformation; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; -import org.springframework.util.ReflectionUtils.FieldCallback; /** * {@link EntityInformation} implementation that inspects fields for an annotation and looks up this field's value to @@ -60,12 +59,10 @@ public class ReflectionEntityInformation extends Abs super(domainClass); Assert.notNull(annotation, "Annotation must not be null!"); - ReflectionUtils.doWithFields(domainClass, new FieldCallback() { - public void doWith(Field field) { - if (field.getAnnotation(annotation) != null) { - ReflectionEntityInformation.this.field = field; - return; - } + ReflectionUtils.doWithFields(domainClass, field -> { + if (field.getAnnotation(annotation) != null) { + ReflectionEntityInformation.this.field = field; + return; } }); @@ -78,8 +75,8 @@ public class ReflectionEntityInformation extends Abs * @see org.springframework.data.repository.core.EntityInformation#getId(java.lang.Object) */ @SuppressWarnings("unchecked") - public ID getId(Object entity) { - return entity == null ? null : (ID) ReflectionUtils.getField(field, entity); + public Optional getId(Object entity) { + return entity == null ? null : Optional.of((ID) ReflectionUtils.getField(field, entity)); } /* diff --git a/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupport.java b/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupport.java index 6926f7e31..36e98cfe6 100644 --- a/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupport.java +++ b/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupport.java @@ -199,9 +199,8 @@ public abstract class RepositoryFactoryBeanSupport, */ public PersistentEntity getPersistentEntity() { - return mappingContext// - .map(context -> context.getPersistentEntity(repositoryMetadata.getDomainType()))// - .orElseGet(null); + return mappingContext.orElseThrow(() -> new IllegalStateException("No MappingContext available!")) + .getRequiredPersistentEntity(repositoryMetadata.getDomainType()); } /* (non-Javadoc) diff --git a/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java b/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java index 66001acc2..01fefcf88 100644 --- a/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java +++ b/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java @@ -40,8 +40,8 @@ import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.core.GenericTypeResolver; import org.springframework.core.MethodParameter; +import org.springframework.core.ResolvableType; import org.springframework.core.convert.TypeDescriptor; import org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; @@ -73,8 +73,6 @@ import org.springframework.util.Assert; */ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware, BeanFactoryAware { - private static final boolean IS_JAVA_8 = org.springframework.util.ClassUtils.isPresent("java.util.Optional", - RepositoryFactorySupport.class.getClassLoader()); private static final Class TRANSACTION_PROXY_TYPE = getTransactionProxyType(); private final Map repositoryInformationCache; @@ -197,6 +195,19 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware, return getRepository(repositoryInterface, Optional.empty()); } + /** + * Returns a repository instance for the given interface backed by an instance providing implementation logic for + * custom logic. + * + * @param + * @param repositoryInterface + * @param customImplementation + * @return + */ + public T getRepository(Class repositoryInterface, Object customImplementation) { + return getRepository(repositoryInterface, Optional.of(customImplementation)); + } + /** * Returns a repository instance for the given interface backed by an instance providing implementation logic for * custom logic. @@ -207,7 +218,7 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware, * @return */ @SuppressWarnings({ "unchecked" }) - public T getRepository(Class repositoryInterface, Optional customImplementation) { + protected T getRepository(Class repositoryInterface, Optional customImplementation) { RepositoryMetadata metadata = getRepositoryMetadata(repositoryInterface); RepositoryInformation information = getRepositoryInformation(metadata, customImplementation.map(Object::getClass)); @@ -230,10 +241,7 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware, postProcessors.forEach(processor -> processor.postProcess(result, information)); - if (IS_JAVA_8) { - result.addAdvice(new DefaultMethodInvokingMethodInterceptor()); - } - + result.addAdvice(new DefaultMethodInvokingMethodInterceptor()); result.addAdvice(new QueryExecutorMethodInterceptor(information)); result.addAdvice(information.isReactiveRepository() @@ -265,15 +273,14 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware, RepositoryInformationCacheKey cacheKey = new RepositoryInformationCacheKey(metadata, customImplementationClass); - return repositoryInformationCache.computeIfAbsent(cacheKey, key -> new DefaultRepositoryInformation(metadata, - repositoryBaseClass.orElse(getRepositoryBaseClass(metadata)), customImplementationClass)); + return repositoryInformationCache.computeIfAbsent(cacheKey, key -> { - /* - repositoryInformation = metadata.isReactiveRepository() - ? new ReactiveRepositoryInformation(metadata, repositoryBaseClass, customImplementationClass) - : new DefaultRepositoryInformation(metadata, repositoryBaseClass, customImplementationClass); - */ + Class baseClass = repositoryBaseClass.orElse(getRepositoryBaseClass(metadata)); + return metadata.isReactiveRepository() + ? new ReactiveRepositoryInformation(metadata, baseClass, customImplementationClass) + : new DefaultRepositoryInformation(metadata, baseClass, customImplementationClass); + }); } protected List getQueryMethods() { @@ -432,9 +439,11 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware, private void invokeListeners(RepositoryQuery query) { for (QueryCreationListener listener : queryPostProcessors) { - Class typeArgument = GenericTypeResolver.resolveTypeArgument(listener.getClass(), - QueryCreationListener.class); - if (typeArgument != null && typeArgument.isAssignableFrom(query.getClass())) { + + ResolvableType typeArgument = ResolvableType.forClass(QueryCreationListener.class, listener.getClass()) + .getGeneric(0); + + if (typeArgument != null && typeArgument.isAssignableFrom(ResolvableType.forClass(query.getClass()))) { listener.onCreation(query); } } @@ -620,7 +629,7 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware, /** * All {@link QueryMethod}s. */ - private List queryMethods = new ArrayList(); + private List queryMethods = new ArrayList<>(); /* (non-Javadoc) * @see org.springframework.data.repository.core.support.QueryCreationListener#onCreation(org.springframework.data.repository.query.RepositoryQuery) diff --git a/src/main/java/org/springframework/data/repository/core/support/TransactionalRepositoryProxyPostProcessor.java b/src/main/java/org/springframework/data/repository/core/support/TransactionalRepositoryProxyPostProcessor.java index d43c10d6b..376a87256 100644 --- a/src/main/java/org/springframework/data/repository/core/support/TransactionalRepositoryProxyPostProcessor.java +++ b/src/main/java/org/springframework/data/repository/core/support/TransactionalRepositoryProxyPostProcessor.java @@ -157,7 +157,7 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr */ public CustomAnnotationTransactionAttributeSource(boolean publicMethodsOnly) { this.publicMethodsOnly = publicMethodsOnly; - this.annotationParsers = new LinkedHashSet(2); + this.annotationParsers = new LinkedHashSet<>(2); this.annotationParsers.add(new SpringTransactionAnnotationParser()); if (jta12Present) { this.annotationParsers.add(new JtaTransactionAnnotationParser()); @@ -186,7 +186,7 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr public CustomAnnotationTransactionAttributeSource(TransactionAnnotationParser... annotationParsers) { this.publicMethodsOnly = true; Assert.notEmpty(annotationParsers, "At least one TransactionAnnotationParser needs to be specified"); - Set parsers = new LinkedHashSet( + Set parsers = new LinkedHashSet<>( annotationParsers.length); Collections.addAll(parsers, annotationParsers); this.annotationParsers = parsers; diff --git a/src/main/java/org/springframework/data/repository/init/Jackson2ResourceReader.java b/src/main/java/org/springframework/data/repository/init/Jackson2ResourceReader.java index 90a743a29..0c93a7910 100644 --- a/src/main/java/org/springframework/data/repository/init/Jackson2ResourceReader.java +++ b/src/main/java/org/springframework/data/repository/init/Jackson2ResourceReader.java @@ -80,12 +80,12 @@ public class Jackson2ResourceReader implements ResourceReader { public Object readFrom(Resource resource, ClassLoader classLoader) throws Exception { InputStream stream = resource.getInputStream(); - JsonNode node = mapper.reader(JsonNode.class).readTree(stream); + JsonNode node = mapper.readerFor(JsonNode.class).readTree(stream); if (node.isArray()) { Iterator elements = node.elements(); - List result = new ArrayList(); + List result = new ArrayList<>(); while (elements.hasNext()) { JsonNode element = elements.next(); @@ -112,6 +112,6 @@ public class Jackson2ResourceReader implements ResourceReader { Class type = ClassUtils.resolveClassName(typeName, classLoader); - return mapper.reader(type).readValue(node); + return mapper.readerFor(type).readValue(node); } } diff --git a/src/main/java/org/springframework/data/repository/query/EvaluationContextExtensionInformation.java b/src/main/java/org/springframework/data/repository/query/EvaluationContextExtensionInformation.java index b9e9e824e..68b6ffe82 100644 --- a/src/main/java/org/springframework/data/repository/query/EvaluationContextExtensionInformation.java +++ b/src/main/java/org/springframework/data/repository/query/EvaluationContextExtensionInformation.java @@ -91,7 +91,7 @@ class EvaluationContextExtensionInformation { */ public RootObjectInformation getRootObjectInformation(Optional target) { - return target.map(it -> rootObjectInformation.orElse(new RootObjectInformation(it.getClass()))) + return target.map(it -> rootObjectInformation.orElseGet(() -> new RootObjectInformation(it.getClass()))) .orElse(RootObjectInformation.NONE); } @@ -215,8 +215,8 @@ class EvaluationContextExtensionInformation { Assert.notNull(type, "Type must not be null!"); this.accessors = new HashMap(); - this.methods = new HashSet(); - this.fields = new ArrayList(); + this.methods = new HashSet<>(); + this.fields = new ArrayList<>(); if (Object.class.equals(type)) { return; @@ -232,7 +232,7 @@ class EvaluationContextExtensionInformation { .filter(it -> method.equals(it.getReadMethod()))// .forEach(it -> RootObjectInformation.this.accessors.put(it.getName(), method)); - } , PublicMethodAndFieldFilter.NON_STATIC); + }, PublicMethodAndFieldFilter.NON_STATIC); ReflectionUtils.doWithFields(type, field -> RootObjectInformation.this.fields.add(field), PublicMethodAndFieldFilter.NON_STATIC); @@ -250,7 +250,7 @@ class EvaluationContextExtensionInformation { .collect(Collectors.toMap(// Method::getName, // method -> new Function(method, it)))) - .orElse(Collections.emptyMap()); + .orElseGet(() -> Collections.emptyMap()); } /** @@ -271,7 +271,7 @@ class EvaluationContextExtensionInformation { return Collections.unmodifiableMap(properties); - }).orElse(Collections.emptyMap()); + }).orElseGet(() -> Collections.emptyMap()); } } diff --git a/src/main/java/org/springframework/data/repository/query/ExtensionAwareEvaluationContextProvider.java b/src/main/java/org/springframework/data/repository/query/ExtensionAwareEvaluationContextProvider.java index 3a73eb8b1..e47b92b27 100644 --- a/src/main/java/org/springframework/data/repository/query/ExtensionAwareEvaluationContextProvider.java +++ b/src/main/java/org/springframework/data/repository/query/ExtensionAwareEvaluationContextProvider.java @@ -163,7 +163,7 @@ public class ExtensionAwareEvaluationContextProvider implements EvaluationContex this.extensions = Collections.emptyList(); beanFactory.ifPresent(it -> { - this.extensions = new ArrayList( + this.extensions = new ArrayList<>( it.getBeansOfType(EvaluationContextExtension.class, true, false).values()); }); diff --git a/src/main/java/org/springframework/data/repository/query/ParameterAccessor.java b/src/main/java/org/springframework/data/repository/query/ParameterAccessor.java index a100e3e28..1730fc55a 100644 --- a/src/main/java/org/springframework/data/repository/query/ParameterAccessor.java +++ b/src/main/java/org/springframework/data/repository/query/ParameterAccessor.java @@ -16,6 +16,7 @@ package org.springframework.data.repository.query; import java.util.Iterator; +import java.util.Optional; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -48,7 +49,7 @@ public interface ParameterAccessor extends Iterable { * @return * @since 1.12 */ - Class getDynamicProjection(); + Optional> getDynamicProjection(); /** * Returns the bindable value with the given index. Bindable means, that {@link Pageable} and {@link Sort} values are diff --git a/src/main/java/org/springframework/data/repository/query/Parameters.java b/src/main/java/org/springframework/data/repository/query/Parameters.java index 200146e5b..8c6a2eeef 100644 --- a/src/main/java/org/springframework/data/repository/query/Parameters.java +++ b/src/main/java/org/springframework/data/repository/query/Parameters.java @@ -64,7 +64,7 @@ public abstract class Parameters, T extends Parameter List> types = Arrays.asList(method.getParameterTypes()); - this.parameters = new ArrayList(types.size()); + this.parameters = new ArrayList<>(types.size()); this.dynamicProjectionIndex = -1; for (int i = 0; i < types.size(); i++) { @@ -98,7 +98,7 @@ public abstract class Parameters, T extends Parameter */ protected Parameters(List originals) { - this.parameters = new ArrayList(originals.size()); + this.parameters = new ArrayList<>(originals.size()); int pageableIndexTemp = -1; int sortIndexTemp = -1; @@ -251,7 +251,7 @@ public abstract class Parameters, T extends Parameter */ public S getBindableParameters() { - List bindables = new ArrayList(); + List bindables = new ArrayList<>(); for (T candidate : this) { diff --git a/src/main/java/org/springframework/data/repository/query/ParametersParameterAccessor.java b/src/main/java/org/springframework/data/repository/query/ParametersParameterAccessor.java index 76fd3a504..8e64c3e61 100644 --- a/src/main/java/org/springframework/data/repository/query/ParametersParameterAccessor.java +++ b/src/main/java/org/springframework/data/repository/query/ParametersParameterAccessor.java @@ -18,6 +18,7 @@ package org.springframework.data.repository.query; import java.util.Arrays; import java.util.Iterator; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import org.springframework.data.domain.Pageable; @@ -70,10 +71,12 @@ public class ParametersParameterAccessor implements ParameterAccessor { public Pageable getPageable() { if (!parameters.hasPageableParameter()) { - return null; + return Pageable.NONE; } - return (Pageable) values.get(parameters.getPageableIndex()); + Pageable pageable = (Pageable) values.get(parameters.getPageableIndex()); + + return pageable == null ? Pageable.NONE : pageable; } /* @@ -83,14 +86,16 @@ public class ParametersParameterAccessor implements ParameterAccessor { public Sort getSort() { if (parameters.hasSortParameter()) { - return (Sort) values.get(parameters.getSortIndex()); + + Sort sort = (Sort) values.get(parameters.getSortIndex()); + return sort == null ? Sort.unsorted() : sort; } - if (parameters.hasPageableParameter() && getPageable() != null) { + if (parameters.hasPageableParameter()) { return getPageable().getSort(); } - return null; + return Sort.unsorted(); } /** @@ -98,8 +103,9 @@ public class ParametersParameterAccessor implements ParameterAccessor { * * @return */ - public Class getDynamicProjection() { - return parameters.hasDynamicProjection() ? (Class) values.get(parameters.getDynamicProjectionIndex()) : null; + public Optional> getDynamicProjection() { + return Optional.ofNullable( + parameters.hasDynamicProjection() ? (Class) values.get(parameters.getDynamicProjectionIndex()) : null); } /** diff --git a/src/main/java/org/springframework/data/repository/query/QueryMethod.java b/src/main/java/org/springframework/data/repository/query/QueryMethod.java index ed59b8b39..333591379 100644 --- a/src/main/java/org/springframework/data/repository/query/QueryMethod.java +++ b/src/main/java/org/springframework/data/repository/query/QueryMethod.java @@ -265,7 +265,9 @@ public class QueryMethod { if (QueryExecutionConverters.supports(method.getReturnType())) { // unwrap only one level to handle cases like Future> correctly. - return ClassTypeInformation.fromReturnTypeOf(method).getComponentType().getType(); + return ClassTypeInformation.fromReturnTypeOf(method).getComponentType().map(it -> it.getType()) + .orElseThrow(() -> new IllegalStateException( + String.format("Couldn't find component type for return value of method %s!", method))); } return method.getReturnType(); diff --git a/src/main/java/org/springframework/data/repository/query/ResultProcessor.java b/src/main/java/org/springframework/data/repository/query/ResultProcessor.java index b7dd5eac7..1b15c30f3 100644 --- a/src/main/java/org/springframework/data/repository/query/ResultProcessor.java +++ b/src/main/java/org/springframework/data/repository/query/ResultProcessor.java @@ -23,6 +23,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Stream; import org.springframework.core.CollectionFactory; @@ -48,8 +49,7 @@ public class ResultProcessor { private final QueryMethod method; private final ProjectingConverter converter; private final ProjectionFactory factory; - - private ReturnedType type; + private final ReturnedType type; /** * Creates a new {@link ResultProcessor} from the given {@link QueryMethod} and {@link ProjectionFactory}. @@ -86,15 +86,11 @@ public class ResultProcessor { * @param accessor can be {@literal null}. * @return */ - public ResultProcessor withDynamicProjection(ParameterAccessor accessor) { - - if (accessor == null) { - return this; - } + public ResultProcessor withDynamicProjection(Optional accessor) { - Class projectionType = accessor.getDynamicProjection(); - - return projectionType == null ? this : new ResultProcessor(method, factory, projectionType); + return accessor.flatMap(it -> it.getDynamicProjection())// + .map(it -> new ResultProcessor(method, factory, it))// + .orElse(this); } /** @@ -280,34 +276,4 @@ public class ResultProcessor { return result; } } - - /** - * Handler for Repository query methods returning a Java 8 Stream result by ensuring the {@link Stream} elements match - * the expected return type of the query method. - * - * @author John Blum - * @author Oliver Gierke - */ - @RequiredArgsConstructor - static class StreamQueryResultHandler { - - private final @NonNull ReturnedType returnType; - private final @NonNull Converter converter; - - /** - * Processes the given source object as a {@link Stream}, mapping each element to the required return type, - * converting if necessary. - * - * @param source the {@link Stream} of elements to process, must not be {@literal null}. - * @return a new {@link Stream} with the source {@link Stream}'s elements mapped to the target type. - */ - @SuppressWarnings("unchecked") - public Object handle(Object source) { - - Assert.isInstanceOf(Stream.class, source, "Source must not be null and an instance of Stream!"); - - return ((Stream) source) - .map(element -> returnType.isInstance(element) ? element : converter.convert(element)); - } - } } diff --git a/src/main/java/org/springframework/data/repository/query/ReturnedType.java b/src/main/java/org/springframework/data/repository/query/ReturnedType.java index b82901f80..015976c89 100644 --- a/src/main/java/org/springframework/data/repository/query/ReturnedType.java +++ b/src/main/java/org/springframework/data/repository/query/ReturnedType.java @@ -189,7 +189,7 @@ public abstract class ReturnedType { @Override public List getInputProperties() { - List properties = new ArrayList(); + List properties = new ArrayList<>(); for (PropertyDescriptor descriptor : information.getInputProperties()) { if (!properties.contains(descriptor.getName())) { @@ -291,7 +291,7 @@ public abstract class ReturnedType { .flatMap(parameter -> Optionals.toStream(parameter.getName()))// .collect(Collectors.toList()); - }).orElse(Collections.emptyList()); + }).orElseGet(() -> Collections.emptyList()); } private boolean isDto() { diff --git a/src/main/java/org/springframework/data/repository/query/parser/AbstractQueryCreator.java b/src/main/java/org/springframework/data/repository/query/parser/AbstractQueryCreator.java index ef2d4fdbf..0d01fde40 100644 --- a/src/main/java/org/springframework/data/repository/query/parser/AbstractQueryCreator.java +++ b/src/main/java/org/springframework/data/repository/query/parser/AbstractQueryCreator.java @@ -68,9 +68,7 @@ public abstract class AbstractQueryCreator { * @return */ public T createQuery() { - - Sort dynamicSort = parameters != null ? parameters.getSort() : null; - return createQuery(dynamicSort); + return createQuery(parameters.getSort()); } /** @@ -82,10 +80,7 @@ public abstract class AbstractQueryCreator { */ public T createQuery(Sort dynamicSort) { - Sort staticSort = tree.getSort(); - Sort sort = staticSort != null ? staticSort.and(dynamicSort) : dynamicSort; - - return complete(createCriteria(tree), sort); + return complete(createCriteria(tree), tree.getSort().and(dynamicSort)); } /** diff --git a/src/main/java/org/springframework/data/repository/query/parser/OrderBySource.java b/src/main/java/org/springframework/data/repository/query/parser/OrderBySource.java index c0ca0528a..33f31478a 100644 --- a/src/main/java/org/springframework/data/repository/query/parser/OrderBySource.java +++ b/src/main/java/org/springframework/data/repository/query/parser/OrderBySource.java @@ -39,10 +39,12 @@ import org.springframework.util.StringUtils; */ class OrderBySource { + public static OrderBySource EMPTY = new OrderBySource(""); + private static final String BLOCK_SPLIT = "(?<=Asc|Desc)(?=\\p{Lu})"; private static final Pattern DIRECTION_SPLIT = Pattern.compile("(.+?)(Asc|Desc)?$"); private static final String INVALID_ORDER_SYNTAX = "Invalid order syntax for part %s!"; - private static final Set DIRECTION_KEYWORDS = new HashSet(Arrays.asList("Asc", "Desc")); + private static final Set DIRECTION_KEYWORDS = new HashSet<>(Arrays.asList("Asc", "Desc")); private final List orders; @@ -53,7 +55,7 @@ class OrderBySource { * @param clause must not be {@literal null}. */ public OrderBySource(String clause) { - this(clause, null); + this(clause, Optional.empty()); } /** @@ -61,12 +63,16 @@ class OrderBySource { * type. * * @param clause must not be {@literal null}. - * @param domainClass can be {@literal null}. + * @param domainClass must not be {@literal null}. */ - public OrderBySource(String clause, Class domainClass) { + public OrderBySource(String clause, Optional> domainClass) { this.orders = new ArrayList(); + if (!StringUtils.hasText(clause)) { + return; + } + for (String part : clause.split(BLOCK_SPLIT)) { Matcher matcher = DIRECTION_SPLIT.matcher(part); @@ -83,8 +89,7 @@ class OrderBySource { throw new IllegalArgumentException(String.format(INVALID_ORDER_SYNTAX, part)); } - Direction direction = StringUtils.hasText(directionString) ? Direction.fromString(directionString) : null; - this.orders.add(createOrder(propertyString, direction, domainClass)); + this.orders.add(createOrder(propertyString, Direction.fromOptionalString(directionString), domainClass)); } } @@ -98,13 +103,17 @@ class OrderBySource { * @return * @see PropertyPath#from(String, Class) */ - private Order createOrder(String propertySource, Direction direction, Class domainClass) { + private Order createOrder(String propertySource, Optional direction, Optional> domainClass) { - if (null == domainClass) { - return new Order(direction, StringUtils.uncapitalize(propertySource)); - } - PropertyPath propertyPath = PropertyPath.from(propertySource, domainClass); - return new Order(direction, propertyPath.toDotPath()); + return domainClass.map(type -> { + + PropertyPath propertyPath = PropertyPath.from(propertySource, type); + return direction.map(it -> new Order(it, propertyPath.toDotPath())) + .orElseGet(() -> new Order(propertyPath.toDotPath())); + + }).orElseGet(() -> direction// + .map(it -> new Order(it, StringUtils.uncapitalize(propertySource))) + .orElseGet(() -> new Order(StringUtils.uncapitalize(propertySource)))); } /** @@ -112,8 +121,8 @@ class OrderBySource { * * @return the {@link Sort}. */ - public Optional toSort() { - return this.orders.isEmpty() ? Optional.empty() : Optional.of(new Sort(this.orders)); + public Sort toSort() { + return Sort.by(this.orders); } /* diff --git a/src/main/java/org/springframework/data/repository/query/parser/Part.java b/src/main/java/org/springframework/data/repository/query/parser/Part.java index 00fc6581f..e1dcee3f8 100644 --- a/src/main/java/org/springframework/data/repository/query/parser/Part.java +++ b/src/main/java/org/springframework/data/repository/query/parser/Part.java @@ -169,7 +169,7 @@ public class Part { public static final Collection ALL_KEYWORDS; static { - List allKeywords = new ArrayList(); + List allKeywords = new ArrayList<>(); for (Type type : ALL) { allKeywords.addAll(type.keywords); } diff --git a/src/main/java/org/springframework/data/repository/query/parser/PartTree.java b/src/main/java/org/springframework/data/repository/query/parser/PartTree.java index 477a633ef..7b99e807f 100644 --- a/src/main/java/org/springframework/data/repository/query/parser/PartTree.java +++ b/src/main/java/org/springframework/data/repository/query/parser/PartTree.java @@ -110,7 +110,7 @@ public class PartTree implements Streamable { * @return the sort */ public Sort getSort() { - return predicate.getOrderBySource().flatMap(OrderBySource::toSort).orElse(null); + return predicate.getOrderBySource().toSort(); } /** @@ -193,12 +193,15 @@ public class PartTree implements Streamable { .collect(Collectors.toList())); } + /* + * (non-Javadoc) + * @see java.lang.Object#toString() + */ @Override public String toString() { - Optional orderBySource = predicate.getOrderBySource(); - return String.format("%s%s", StringUtils.collectionToDelimitedString(predicate.nodes, " or "), - orderBySource.map(it -> " ".concat(it.toString())).orElse("")); + return String.format("%s %s", StringUtils.collectionToDelimitedString(predicate.nodes, " or "), + predicate.getOrderBySource().toString()).trim(); } /** @@ -347,13 +350,13 @@ public class PartTree implements Streamable { * @author Oliver Gierke * @author Phil Webb */ - private static class Predicate implements Iterable { + private static class Predicate implements Streamable { private static final Pattern ALL_IGNORE_CASE = Pattern.compile("AllIgnor(ing|e)Case"); private static final String ORDER_BY = "OrderBy"; private final List nodes; - private final @Getter Optional orderBySource; + private final @Getter OrderBySource orderBySource; private boolean alwaysIgnoreCase; public Predicate(String predicate, Class domainClass) { @@ -368,7 +371,8 @@ public class PartTree implements Streamable { .map(part -> new OrPart(part, domainClass, alwaysIgnoreCase))// .collect(Collectors.toList()); - this.orderBySource = Optional.ofNullable(parts.length == 2 ? new OrderBySource(parts[1], domainClass) : null); + this.orderBySource = parts.length == 2 ? new OrderBySource(parts[1], Optional.of(domainClass)) + : OrderBySource.EMPTY; } private String detectAndSetAllIgnoreCase(String predicate) { diff --git a/src/main/java/org/springframework/data/repository/support/CrudRepositoryInvoker.java b/src/main/java/org/springframework/data/repository/support/CrudRepositoryInvoker.java index b43b70149..7a809224d 100644 --- a/src/main/java/org/springframework/data/repository/support/CrudRepositoryInvoker.java +++ b/src/main/java/org/springframework/data/repository/support/CrudRepositoryInvoker.java @@ -88,7 +88,7 @@ class CrudRepositoryInvoker extends ReflectionRepositoryInvoker { @Override @SuppressWarnings("unchecked") public T invokeFindOne(Serializable id) { - return customFindOneMethod ? super. invokeFindOne(id) : (T) repository.findOne(convertId(id)); + return customFindOneMethod ? super.invokeFindOne(id) : (T) repository.findOne(convertId(id)); } /* diff --git a/src/main/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactory.java b/src/main/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactory.java index 5acf5d62a..2d5a20384 100644 --- a/src/main/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactory.java +++ b/src/main/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactory.java @@ -18,11 +18,14 @@ package org.springframework.data.repository.support; import java.io.Serializable; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import org.springframework.core.convert.ConversionService; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.core.RepositoryInformation; +import org.springframework.data.util.Optionals; +import org.springframework.data.util.Pair; import org.springframework.format.support.DefaultFormattingConversionService; import org.springframework.util.Assert; @@ -84,11 +87,13 @@ public class DefaultRepositoryInvokerFactory implements RepositoryInvokerFactory */ private RepositoryInvoker prepareInvokers(Class domainType) { - Object repository = repositories.getRepositoryFor(domainType); - Assert.notNull(repository, String.format("No repository found for domain type: %s", domainType)); - RepositoryInformation information = repositories.getRepositoryInformationFor(domainType); + Optional> repositoryAndInformation = Optionals + .withBoth(repositories.getRepositoryFor(domainType), repositories.getRepositoryInformationFor(domainType)); - return createInvoker(information, repository); + return repositoryAndInformation// + .map(it -> createInvoker(it.getSecond(), it.getFirst())) // + .orElseThrow( + () -> new IllegalArgumentException(String.format("No repository found for domain type: %s", domainType))); } @SuppressWarnings("unchecked") diff --git a/src/main/java/org/springframework/data/repository/support/DomainClassConverter.java b/src/main/java/org/springframework/data/repository/support/DomainClassConverter.java index 7362b247b..63351f18f 100644 --- a/src/main/java/org/springframework/data/repository/support/DomainClassConverter.java +++ b/src/main/java/org/springframework/data/repository/support/DomainClassConverter.java @@ -16,6 +16,7 @@ package org.springframework.data.repository.support; import java.util.Collections; +import java.util.Optional; import java.util.Set; import org.springframework.context.ApplicationContext; @@ -150,11 +151,12 @@ public class DomainClassConverter domainType = targetType.getType(); - - RepositoryInformation info = repositories.getRepositoryInformationFor(domainType); RepositoryInvoker invoker = repositoryInvokerFactory.getInvokerFor(domainType); - return invoker.invokeFindOne(conversionService.convert(source, info.getIdType())); + return repositories.getRepositoryInformationFor(domainType)// + .map(it -> invoker.invokeFindOne(conversionService.convert(source, it.getIdType())))// + .orElseThrow(() -> new IllegalStateException( + String.format("Couldn't find RepositoryInformation for %s!", domainType))); } /* @@ -168,14 +170,22 @@ public class DomainClassConverter domainType = targetType.getType(); + + if (!repositories.hasRepositoryFor(domainType)) { return false; } - Class rawIdType = repositories.getRepositoryInformationFor(targetType.getType()).getIdType(); + Optional repositoryInformation = repositories.getRepositoryInformationFor(domainType); + + return repositoryInformation.map(it -> { + + Class rawIdType = it.getIdType(); - return sourceType.equals(TypeDescriptor.valueOf(rawIdType)) - || conversionService.canConvert(sourceType.getType(), rawIdType); + return sourceType.equals(TypeDescriptor.valueOf(rawIdType)) + || conversionService.canConvert(sourceType.getType(), rawIdType); + }).orElseThrow( + () -> new IllegalStateException(String.format("Couldn't find RepositoryInformation for %s!", domainType))); } } @@ -229,14 +239,23 @@ public class DomainClassConverter domainType = sourceType.getType(); + + if (!repositories.hasRepositoryFor(domainType)) { return false; } - Class rawIdType = repositories.getRepositoryInformationFor(sourceType.getType()).getIdType(); + Optional information = repositories.getRepositoryInformationFor(domainType); + + return information.map(it -> { + + Class rawIdType = it.getIdType(); + + return targetType.equals(TypeDescriptor.valueOf(rawIdType)) + || conversionService.canConvert(rawIdType, targetType.getType()); - return targetType.equals(TypeDescriptor.valueOf(rawIdType)) - || conversionService.canConvert(rawIdType, targetType.getType()); + }).orElseThrow( + () -> new IllegalStateException(String.format("Couldn't find RepositoryInformation for %s!", domainType))); } } } diff --git a/src/main/java/org/springframework/data/repository/support/MethodParameters.java b/src/main/java/org/springframework/data/repository/support/MethodParameters.java index 821574764..252ef1c95 100644 --- a/src/main/java/org/springframework/data/repository/support/MethodParameters.java +++ b/src/main/java/org/springframework/data/repository/support/MethodParameters.java @@ -19,10 +19,13 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.MethodParameter; import org.springframework.core.ParameterNameDiscoverer; +import org.springframework.data.util.Lazy; import org.springframework.util.Assert; /** @@ -42,7 +45,7 @@ class MethodParameters { * @param method must not be {@literal null}. */ public MethodParameters(Method method) { - this(method, null); + this(method, Optional.empty()); } /** @@ -50,12 +53,12 @@ class MethodParameters { * is given, method parameter names will be looked up from the annotation attribute if present. * * @param method must not be {@literal null}. - * @param namingAnnotation can be {@literal null}. + * @param namingAnnotation must not be {@literal null}. */ - public MethodParameters(Method method, AnnotationAttribute namingAnnotation) { + public MethodParameters(Method method, Optional namingAnnotation) { Assert.notNull(method, "Method must not be null!"); - this.parameters = new ArrayList(); + this.parameters = new ArrayList<>(); for (int i = 0; i < method.getParameterTypes().length; i++) { @@ -80,17 +83,12 @@ class MethodParameters { * @param name must not be {@literal null} or empty. * @return */ - public MethodParameter getParameter(String name) { + public Optional getParameter(String name) { Assert.hasText(name, "Parameter name must not be null!"); - for (MethodParameter parameter : parameters) { - if (name.equals(parameter.getParameterName())) { - return parameter; - } - } - - return null; + return getParameters().stream()// + .filter(it -> name.equals(it.getParameterName())).findFirst(); } /** @@ -103,15 +101,10 @@ class MethodParameters { public List getParametersOfType(Class type) { Assert.notNull(type, "Type must not be null!"); - List result = new ArrayList(); - for (MethodParameter parameter : getParameters()) { - if (parameter.getParameterType().equals(type)) { - result.add(parameter); - } - } - - return result; + return getParameters().stream()// + .filter(it -> it.getParameterType().equals(type))// + .collect(Collectors.toList()); } /** @@ -123,15 +116,10 @@ class MethodParameters { public List getParametersWith(Class annotation) { Assert.notNull(annotation, "Annotation must not be null!"); - List result = new ArrayList(); - - for (MethodParameter parameter : getParameters()) { - if (parameter.hasParameterAnnotation(annotation)) { - result.add(parameter); - } - } - return result; + return getParameters().stream()// + .filter(it -> it.hasParameterAnnotation(annotation))// + .collect(Collectors.toList()); } /** @@ -142,8 +130,8 @@ class MethodParameters { */ private static class AnnotationNamingMethodParameter extends MethodParameter { - private final AnnotationAttribute attribute; - private String name; + private final Optional attribute; + private final Lazy name; /** * Creates a new {@link AnnotationNamingMethodParameter} for the given {@link Method}'s parameter with the given @@ -153,11 +141,17 @@ class MethodParameters { * @param parameterIndex * @param attribute can be {@literal null} */ - public AnnotationNamingMethodParameter(Method method, int parameterIndex, AnnotationAttribute attribute) { + public AnnotationNamingMethodParameter(Method method, int parameterIndex, Optional attribute) { super(method, parameterIndex); + this.attribute = attribute; + this.name = Lazy.of(() -> { + return this.attribute.// + flatMap(it -> it.getValueFrom(this).map(Object::toString)).// + orElseGet(() -> super.getParameterName()); + }); } /* @@ -166,21 +160,7 @@ class MethodParameters { */ @Override public String getParameterName() { - - if (name != null) { - return name; - } - - if (attribute != null) { - Object foundName = attribute.getValueFrom(this); - if (foundName != null) { - name = foundName.toString(); - return name; - } - } - - name = super.getParameterName(); - return name; + return name.get(); } } } diff --git a/src/main/java/org/springframework/data/repository/support/PageableExecutionUtils.java b/src/main/java/org/springframework/data/repository/support/PageableExecutionUtils.java index c222ed596..b9d0a3659 100644 --- a/src/main/java/org/springframework/data/repository/support/PageableExecutionUtils.java +++ b/src/main/java/org/springframework/data/repository/support/PageableExecutionUtils.java @@ -15,7 +15,10 @@ */ package org.springframework.data.repository.support; +import lombok.experimental.UtilityClass; + import java.util.List; +import java.util.function.LongSupplier; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -27,53 +30,41 @@ import org.springframework.util.Assert; * are cheaper than {@code COUNT} queries and so some cases can take advantage of optimizations. * * @author Mark Paluch + * @author Oliver Gierke * @since 1.13 */ -public abstract class PageableExecutionUtils { - - private PageableExecutionUtils() {} +@UtilityClass +public class PageableExecutionUtils { /** - * Constructs a {@link Page} based on the given {@code content}, {@link Pageable} and {@link TotalSupplier} applying + * Constructs a {@link Page} based on the given {@code content}, {@link Pageable} and {@link Supplier} applying * optimizations. The construction of {@link Page} omits a count query if the total can be determined based on the * result size and {@link Pageable}. * * @param content must not be {@literal null}. - * @param pageable can be {@literal null}. + * @param pageable must not be {@literal null}. * @param totalSupplier must not be {@literal null}. * @return the {@link Page}. */ - public static Page getPage(List content, Pageable pageable, TotalSupplier totalSupplier) { + public static Page getPage(List content, Pageable pageable, LongSupplier totalSupplier) { Assert.notNull(content, "Content must not be null!"); + Assert.notNull(pageable, "Pageable must not be null!"); Assert.notNull(totalSupplier, "TotalSupplier must not be null!"); - if (pageable == null || pageable.getOffset() == 0) { + if (pageable == Pageable.NONE || pageable.getOffset() == 0) { - if (pageable == null || pageable.getPageSize() > content.size()) { + if (pageable == Pageable.NONE || pageable.getPageSize() > content.size()) { return new PageImpl(content, pageable, content.size()); } - return new PageImpl(content, pageable, totalSupplier.get()); + return new PageImpl(content, pageable, totalSupplier.getAsLong()); } if (content.size() != 0 && pageable.getPageSize() > content.size()) { return new PageImpl(content, pageable, pageable.getOffset() + content.size()); } - return new PageImpl(content, pageable, totalSupplier.get()); - } - - /** - * Supplies the total count for a particular query. Can be replaced with a Java 8 Supplier when upgrading to Java 8. - * - * @author Mark Paluch - */ - public interface TotalSupplier { - - /** - * @return the total count for a particular query. - */ - long get(); + return new PageImpl(content, pageable, totalSupplier.getAsLong()); } } diff --git a/src/main/java/org/springframework/data/repository/support/PagingAndSortingRepositoryInvoker.java b/src/main/java/org/springframework/data/repository/support/PagingAndSortingRepositoryInvoker.java index dba30d465..ffb7c7c28 100644 --- a/src/main/java/org/springframework/data/repository/support/PagingAndSortingRepositoryInvoker.java +++ b/src/main/java/org/springframework/data/repository/support/PagingAndSortingRepositoryInvoker.java @@ -57,22 +57,22 @@ class PagingAndSortingRepositoryInvoker extends CrudRepositoryInvoker { this.customFindAll = isRedeclaredMethod(crudMethods.getFindAllMethod()); } - /* + /* * (non-Javadoc) - * @see org.springframework.data.rest.core.invoke.CrudRepositoryInvoker#invokeFindAll(org.springframework.data.domain.Sort) + * @see org.springframework.data.repository.support.CrudRepositoryInvoker#invokeSortedFindAll(java.util.Optional) */ @Override public Iterable invokeFindAll(Sort sort) { - return customFindAll ? invokeFindAllReflectively(sort) : repository.findAll(sort); + return customFindAll ? invokeSortedFindAllReflectively(sort) : repository.findAll(sort); } /* * (non-Javadoc) - * @see org.springframework.data.rest.core.invoke.CrudRepositoryInvoker#invokeFindAll(org.springframework.data.domain.Pageable) + * @see org.springframework.data.repository.support.CrudRepositoryInvoker#invokePagedFindAll(java.util.Optional) */ @Override public Iterable invokeFindAll(Pageable pageable) { - return customFindAll ? invokeFindAllReflectively(pageable) : repository.findAll(pageable); + return customFindAll ? invokePagedFindAllReflectively(pageable) : repository.findAll(pageable); } private boolean isRedeclaredMethod(Method method) { diff --git a/src/main/java/org/springframework/data/repository/support/ReflectionRepositoryInvoker.java b/src/main/java/org/springframework/data/repository/support/ReflectionRepositoryInvoker.java index e131af118..615ef00e2 100644 --- a/src/main/java/org/springframework/data/repository/support/ReflectionRepositoryInvoker.java +++ b/src/main/java/org/springframework/data/repository/support/ReflectionRepositoryInvoker.java @@ -19,6 +19,7 @@ import java.io.Serializable; import java.lang.reflect.Method; import java.util.Arrays; import java.util.List; +import java.util.Optional; import org.springframework.core.MethodParameter; import org.springframework.core.convert.ConversionException; @@ -81,21 +82,22 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker { return methods.hasFindAllMethod(); } - /* (non-Javadoc) - * @see org.springframework.data.rest.core.invoke.RepositoryInvoker#invokeFindAll(org.springframework.data.domain.Sort) + /* + * (non-Javadoc) + * @see org.springframework.data.repository.support.RepositoryInvoker#invokeSortedFindAll(java.util.Optional) */ @Override public Iterable invokeFindAll(Sort sort) { - return invokeFindAllReflectively(sort); + return invokeSortedFindAllReflectively(sort); } - /* + /* * (non-Javadoc) - * @see org.springframework.data.rest.core.invoke.RepositoryInvoker#invokeFindAll(org.springframework.data.domain.Pageable) + * @see org.springframework.data.repository.support.RepositoryInvoker#invokePagedFindAll(java.util.Optional) */ @Override public Iterable invokeFindAll(Pageable pageable) { - return invokeFindAllReflectively(pageable); + return invokePagedFindAllReflectively(pageable); } /* @@ -163,7 +165,7 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker { if (idTypes.contains(parameterType)) { invoke(method, convertId(id)); } else { - invoke(method, this. invokeFindOne(id)); + invoke(method, this.invokeFindOne(id)); } } @@ -177,6 +179,8 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker { Assert.notNull(method, "Method must not be null!"); Assert.notNull(parameters, "Parameters must not be null!"); + Assert.notNull(pageable, "Pageable must not be null!"); + Assert.notNull(sort, "Sort must not be null!"); ReflectionUtils.makeAccessible(method); @@ -186,14 +190,14 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker { private Object[] prepareParameters(Method method, MultiValueMap rawParameters, Pageable pageable, Sort sort) { - List parameters = new MethodParameters(method, PARAM_ANNOTATION).getParameters(); + List parameters = new MethodParameters(method, Optional.of(PARAM_ANNOTATION)).getParameters(); if (parameters.isEmpty()) { return new Object[0]; } Object[] result = new Object[parameters.size()]; - Sort sortToUse = pageable == null ? sort : pageable.getSort(); + Sort sortToUse = pageable.getSortOr(sort); for (int i = 0; i < result.length; i++) { @@ -254,7 +258,7 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker { return conversionService.convert(id, idType); } - protected Iterable invokeFindAllReflectively(Pageable pageable) { + protected Iterable invokePagedFindAllReflectively(Pageable pageable) { Assert.state(hasFindAllMethod(), "Repository doesn't have a find-all-method declared!"); @@ -269,12 +273,10 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker { return invoke(method, pageable); } - Sort sort = pageable == null ? null : pageable.getSort(); - - return invokeFindAll(sort); + return invokeFindAll(pageable.getSort()); } - protected Iterable invokeFindAllReflectively(Sort sort) { + protected Iterable invokeSortedFindAllReflectively(Sort sort) { Assert.state(hasFindAllMethod(), "Repository doesn't have a find-all-method declared!"); diff --git a/src/main/java/org/springframework/data/repository/support/Repositories.java b/src/main/java/org/springframework/data/repository/support/Repositories.java index 4e77e4a35..4e5887638 100644 --- a/src/main/java/org/springframework/data/repository/support/Repositories.java +++ b/src/main/java/org/springframework/data/repository/support/Repositories.java @@ -183,15 +183,16 @@ public class Repositories implements Iterable> { * Returns the {@link RepositoryInformation} for the given domain class. * * @param domainClass must not be {@literal null}. - * @return the {@link RepositoryInformation} for the given domain class or {@literal null} if no repository registered - * for this domain class. + * @return the {@link RepositoryInformation} for the given domain class or {@literal Optional#empty()} if no + * repository registered for this domain class. */ - public RepositoryInformation getRepositoryInformationFor(Class domainClass) { + public Optional getRepositoryInformationFor(Class domainClass) { Assert.notNull(domainClass, DOMAIN_TYPE_MUST_NOT_BE_NULL); RepositoryFactoryInformation information = getRepositoryFactoryInfoFor(domainClass); - return information == EMPTY_REPOSITORY_FACTORY_INFO ? null : information.getRepositoryInformation(); + return information == EMPTY_REPOSITORY_FACTORY_INFO ? Optional.empty() + : Optional.of(information.getRepositoryInformation()); } /** @@ -270,7 +271,7 @@ public class Repositories implements Iterable> { @Override public List getQueryMethods() { - return Collections. emptyList(); + return Collections.emptyList(); } } } diff --git a/src/main/java/org/springframework/data/repository/support/RepositoryInvoker.java b/src/main/java/org/springframework/data/repository/support/RepositoryInvoker.java index 7f8b8f83a..facc1d232 100644 --- a/src/main/java/org/springframework/data/repository/support/RepositoryInvoker.java +++ b/src/main/java/org/springframework/data/repository/support/RepositoryInvoker.java @@ -82,8 +82,8 @@ public interface RepositoryInvoker extends RepositoryInvocationInformation { * Invokes the method equivalent to {@link org.springframework.data.repository.CrudRepository#delete(Serializable)}. * The given id is assumed to be of a type convertable into the actual identifier type of the backing repository. * - * @param id must not be {@literal null}. throws {@link IllegalStateException} if the repository does not expose a - * delete-method. + * @param id must not be {@literal null}. + * @throws {@link IllegalStateException} if the repository does not expose a delete-method. */ void invokeDelete(Serializable id); @@ -93,8 +93,8 @@ public interface RepositoryInvoker extends RepositoryInvocationInformation { * * @param method must not be {@literal null}. * @param parameters must not be {@literal null}. - * @param pageable can be {@literal null}. - * @param sort can be {@literal null}. + * @param pageable must not be {@literal null}. + * @param sort must not be {@literal null}. * @return the result of the invoked query method. * @since 1.11 */ diff --git a/src/main/java/org/springframework/data/repository/util/ClassUtils.java b/src/main/java/org/springframework/data/repository/util/ClassUtils.java index cd9915716..8befaa0cf 100644 --- a/src/main/java/org/springframework/data/repository/util/ClassUtils.java +++ b/src/main/java/org/springframework/data/repository/util/ClassUtils.java @@ -108,16 +108,12 @@ public abstract class ClassUtils { Assert.notNull(method, "Method must not be null!"); Assert.notEmpty(types, "Types must not be null or empty!"); - TypeInformation returnType = ClassTypeInformation.fromReturnTypeOf(method); - returnType = QueryExecutionConverters.supports(returnType.getType()) ? returnType.getComponentType() : returnType; - - for (Class type : types) { - if (type.isAssignableFrom(returnType.getType())) { - return; - } - } + TypeInformation returnType = getEffectivelyReturnedTypeFrom(method); - throw new IllegalStateException("Method has to have one of the following return types! " + Arrays.toString(types)); + Arrays.stream(types)// + .filter(it -> it.isAssignableFrom(returnType.getType()))// + .findAny().orElseThrow(() -> new IllegalStateException( + "Method has to have one of the following return types! " + Arrays.toString(types))); } /** @@ -133,13 +129,7 @@ public abstract class ClassUtils { return false; } - for (Class type : types) { - if (type.isAssignableFrom(object.getClass())) { - return true; - } - } - - return false; + return types.stream().anyMatch(it -> it.isAssignableFrom(object.getClass())); } /** @@ -150,7 +140,6 @@ public abstract class ClassUtils { * @return */ public static boolean hasParameterOfType(Method method, Class type) { - return Arrays.asList(method.getParameterTypes()).contains(type); } @@ -168,4 +157,10 @@ public abstract class ClassUtils { throw ex; } + + private static TypeInformation getEffectivelyReturnedTypeFrom(Method method) { + + TypeInformation returnType = ClassTypeInformation.fromReturnTypeOf(method); + return QueryExecutionConverters.supports(returnType.getType()) ? returnType.getRequiredComponentType() : returnType; + } } diff --git a/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java b/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java index b7309b727..9cff0cdf8 100644 --- a/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java +++ b/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java @@ -297,7 +297,7 @@ public abstract class QueryExecutionConverters { @Override public Set getConvertibleTypes() { - Set pairs = new HashSet(wrapperTypes.length); + Set pairs = new HashSet<>(wrapperTypes.length); for (Class wrapperType : wrapperTypes) { pairs.add(new ConvertiblePair(NullableWrapper.class, wrapperType)); @@ -402,7 +402,7 @@ public abstract class QueryExecutionConverters { * @param conversionService must not be {@literal null}. */ public NullableWrapperToFutureConverter(ConversionService conversionService) { - super(conversionService, new AsyncResult(null), Future.class, ListenableFuture.class); + super(conversionService, new AsyncResult<>(null), Future.class, ListenableFuture.class); } /* @@ -411,7 +411,7 @@ public abstract class QueryExecutionConverters { */ @Override protected Object wrap(Object source) { - return new AsyncResult(source); + return new AsyncResult<>(source); } } diff --git a/src/main/java/org/springframework/data/support/CachingIsNewStrategyFactory.java b/src/main/java/org/springframework/data/support/CachingIsNewStrategyFactory.java index 6ee9949a1..273c764b8 100644 --- a/src/main/java/org/springframework/data/support/CachingIsNewStrategyFactory.java +++ b/src/main/java/org/springframework/data/support/CachingIsNewStrategyFactory.java @@ -15,48 +15,29 @@ */ package org.springframework.data.support; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import org.springframework.util.Assert; - /** * {@link IsNewStrategyFactory} that caches resolved {@link IsNewStrategy} instances per type to avoid re-resolving them * on each and every request. * * @author Oliver Gierke */ +@RequiredArgsConstructor public class CachingIsNewStrategyFactory implements IsNewStrategyFactory { + private final @NonNull IsNewStrategyFactory delegate; private final Map, IsNewStrategy> cache = new ConcurrentHashMap, IsNewStrategy>(); - private final IsNewStrategyFactory delegate; - - /** - * Creates a new {@link CachingIsNewStrategyFactory} delegating to the given {@link IsNewStrategyFactory}. - * - * @param delegate must not be {@literal null}. - */ - public CachingIsNewStrategyFactory(IsNewStrategyFactory delegate) { - - Assert.notNull(delegate, "IsNewStrategyFactory delegate must not be null!"); - this.delegate = delegate; - } /* * (non-Javadoc) * @see org.springframework.data.mapping.model.IsNewStrategyFactory#getIsNewStrategy(java.lang.Class) */ public IsNewStrategy getIsNewStrategy(Class type) { - - IsNewStrategy strategy = cache.get(type); - - if (strategy != null) { - return strategy; - } - - IsNewStrategy isNewStrategy = delegate.getIsNewStrategy(type); - - cache.put(type, isNewStrategy); - return isNewStrategy; + return cache.computeIfAbsent(type, it -> delegate.getIsNewStrategy(it)); } } diff --git a/src/main/java/org/springframework/data/transaction/ChainedTransactionManager.java b/src/main/java/org/springframework/data/transaction/ChainedTransactionManager.java index 324ae5ee2..d47c21337 100644 --- a/src/main/java/org/springframework/data/transaction/ChainedTransactionManager.java +++ b/src/main/java/org/springframework/data/transaction/ChainedTransactionManager.java @@ -209,7 +209,7 @@ public class ChainedTransactionManager implements PlatformTransactionManager { private Iterable reverse(Collection collection) { - List list = new ArrayList(collection); + List list = new ArrayList<>(collection); Collections.reverse(list); return list; } diff --git a/src/main/java/org/springframework/data/util/CacheValue.java b/src/main/java/org/springframework/data/util/CacheValue.java deleted file mode 100644 index 3fc20fb0d..000000000 --- a/src/main/java/org/springframework/data/util/CacheValue.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2014-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.util; - -/** - * Wrapper to safely store {@literal null} values in the value cache. - * - * @author Patryk Wasik - * @author Oliver Gierke - * @author Thomas Darimont - */ -public class CacheValue { - - private static final CacheValue ABSENT = new CacheValue(null); - - private final T value; - - /** - * Creates a new {@link CacheValue} for the gven value. - * - * @param type can be {@literal null}. - */ - private CacheValue(T type) { - this.value = type; - } - - /** - * Returns the actual underlying value. - * - * @return - */ - public T getValue() { - return value; - } - - /** - * Returns whether the cached value has an actual value. - * - * @return - */ - public boolean isPresent() { - return value != null; - } - - /** - * Returns whether the cached value has the given actual value. - * - * @param value can be {@literal null}; - * @return - */ - public boolean hasValue(T value) { - return isPresent() ? this.value.equals(value) : value == null; - } - - /** - * Returns a new {@link CacheValue} for the given value. - * - * @param value can be {@literal null}. - * @return will never be {@literal null}. - */ - @SuppressWarnings("unchecked") - public static CacheValue ofNullable(T value) { - return value == null ? (CacheValue) ABSENT : new CacheValue(value); - } - - /* - * (non-Javadoc) - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - return isPresent() ? 0 : value.hashCode(); - } - - /* - * (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - - if (this == obj) { - return true; - } - - if (!(obj instanceof CacheValue)) { - return false; - } - - CacheValue that = (CacheValue) obj; - - return this.value == null ? false : this.value.equals(that.value); - } -} diff --git a/src/main/java/org/springframework/data/util/CastUtils.java b/src/main/java/org/springframework/data/util/CastUtils.java new file mode 100644 index 000000000..d0ee70f55 --- /dev/null +++ b/src/main/java/org/springframework/data/util/CastUtils.java @@ -0,0 +1,12 @@ +package org.springframework.data.util; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class CastUtils { + + @SuppressWarnings("unchecked") + public T cast(Object object) { + return (T) object; + } +} diff --git a/src/main/java/org/springframework/data/util/ClassTypeInformation.java b/src/main/java/org/springframework/data/util/ClassTypeInformation.java index 7ae71d7b8..013ccb948 100644 --- a/src/main/java/org/springframework/data/util/ClassTypeInformation.java +++ b/src/main/java/org/springframework/data/util/ClassTypeInformation.java @@ -78,7 +78,7 @@ public class ClassTypeInformation extends TypeDiscoverer { return (ClassTypeInformation) cachedTypeInfo; } - ClassTypeInformation result = new ClassTypeInformation(type); + ClassTypeInformation result = new ClassTypeInformation<>(type); CACHE.put(type, new WeakReference>(result)); return result; } @@ -113,7 +113,7 @@ public class ClassTypeInformation extends TypeDiscoverer { * @return */ private static Map, Type> getTypeVariableMap(Class type) { - return getTypeVariableMap(type, new HashSet()); + return getTypeVariableMap(type, new HashSet<>()); } @SuppressWarnings("deprecation") @@ -178,8 +178,8 @@ public class ClassTypeInformation extends TypeDiscoverer { * @see org.springframework.data.util.TypeDiscoverer#specialize(org.springframework.data.util.ClassTypeInformation) */ @Override - public TypeInformation specialize(ClassTypeInformation type) { - return type; + public TypeInformation specialize(ClassTypeInformation type) { + return (TypeInformation) type; } /* diff --git a/src/main/java/org/springframework/data/util/GenericArrayTypeInformation.java b/src/main/java/org/springframework/data/util/GenericArrayTypeInformation.java index b51ceb062..dad78db6c 100644 --- a/src/main/java/org/springframework/data/util/GenericArrayTypeInformation.java +++ b/src/main/java/org/springframework/data/util/GenericArrayTypeInformation.java @@ -20,6 +20,7 @@ import java.lang.reflect.GenericArrayType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.Map; +import java.util.Optional; /** * Special {@link TypeDiscoverer} handling {@link GenericArrayType}s. @@ -60,10 +61,10 @@ class GenericArrayTypeInformation extends ParentTypeAwareTypeInformation { * @see org.springframework.data.util.TypeDiscoverer#doGetComponentType() */ @Override - protected TypeInformation doGetComponentType() { + protected Optional> doGetComponentType() { Type componentType = type.getGenericComponentType(); - return createInfo(componentType); + return Optional.of(createInfo(componentType)); } /* diff --git a/src/main/java/org/springframework/data/util/Lazy.java b/src/main/java/org/springframework/data/util/Lazy.java index 3f1c7f669..e0c0be11d 100644 --- a/src/main/java/org/springframework/data/util/Lazy.java +++ b/src/main/java/org/springframework/data/util/Lazy.java @@ -22,7 +22,11 @@ import java.util.Optional; import java.util.function.Supplier; /** + * Simple value type to delay the creation of an object using a {@link Supplier} returning the produced object for + * subsequent lookups. + * * @author Oliver Gierke + * @since 2.0 */ @RequiredArgsConstructor @EqualsAndHashCode @@ -31,12 +35,20 @@ public class Lazy { private final Supplier supplier; private Optional value; + /** + * Creates a new {@link Lazy} to produce an object lazily. + * + * @param the type of which to produce an object of eventually. + * @param supplier the {@link Supplier} to create the object lazily. + * @return + */ public static Lazy of(Supplier supplier) { - return new Lazy(supplier); + return new Lazy<>(supplier); } /** - * Returns the value created by the configured {@link Supplier}. + * Returns the value created by the configured {@link Supplier}. Will return the calculated instance for subsequent + * lookups. * * @return */ diff --git a/src/main/java/org/springframework/data/util/Optionals.java b/src/main/java/org/springframework/data/util/Optionals.java index 9acfc758f..71aa24c3e 100644 --- a/src/main/java/org/springframework/data/util/Optionals.java +++ b/src/main/java/org/springframework/data/util/Optionals.java @@ -20,6 +20,7 @@ import lombok.experimental.UtilityClass; import java.util.Arrays; import java.util.Iterator; import java.util.Optional; +import java.util.function.Function; import java.util.stream.Stream; import org.springframework.util.Assert; @@ -56,10 +57,68 @@ public class Optionals { Assert.notNull(optionals, "Optional must not be null!"); - return Arrays.asList(optionals).stream().flatMap(it -> it.map(Stream::of).orElse(Stream.empty())); + return Arrays.asList(optionals).stream().flatMap(it -> it.map(Stream::of).orElseGet(() -> Stream.empty())); } + /** + * Applies the given function to the elements of the source and returns the first non-empty result. + * + * @param source must not be {@literal null}. + * @param function must not be {@literal null}. + * @return + */ + public static Optional firstNonEmpty(Iterable source, Function> function) { + + Assert.notNull(source, "Source must not be null!"); + Assert.notNull(function, "Function must not be null!"); + + return Streamable.of(source).stream()// + .map(it -> function.apply(it))// + .filter(it -> it.isPresent())// + .findFirst().orElseGet(() -> Optional.empty()); + } + + /** + * Applies the given function to the elements of the source and returns the first non-empty result. + * + * @param source must not be {@literal null}. + * @param function must not be {@literal null}. + * @return + */ + public static T firstNonEmpty(Iterable source, Function function, T defaultValue) { + + Assert.notNull(source, "Source must not be null!"); + Assert.notNull(function, "Function must not be null!"); + + return Streamable.of(source).stream()// + .map(it -> function.apply(it))// + .filter(it -> !it.equals(defaultValue))// + .findFirst().orElse(defaultValue); + } + + /** + * Returns the next element of the given {@link Iterator} or {@link Optional#empty()} in case there is no next + * element. + * + * @param iterator must not be {@literal null}. + * @return + */ public static Optional next(Iterator iterator) { + + Assert.notNull(iterator, "Iterator must not be null!"); + return iterator.hasNext() ? Optional.of(iterator.next()) : Optional.empty(); } + + /** + * Returns a {@link Pair} if both {@link Optional} instances have values or {@link Optional#empty()} if one or both + * are missing. + * + * @param left + * @param right + * @return + */ + public static Optional> withBoth(Optional left, Optional right) { + return left.flatMap(l -> right.map(r -> Pair.of(l, r))); + } } diff --git a/src/main/java/org/springframework/data/util/ParameterizedTypeInformation.java b/src/main/java/org/springframework/data/util/ParameterizedTypeInformation.java index 778a7cd89..86c536a2f 100644 --- a/src/main/java/org/springframework/data/util/ParameterizedTypeInformation.java +++ b/src/main/java/org/springframework/data/util/ParameterizedTypeInformation.java @@ -23,6 +23,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import org.springframework.util.StringUtils; @@ -57,36 +58,34 @@ class ParameterizedTypeInformation extends ParentTypeAwareTypeInformation * @see org.springframework.data.util.TypeDiscoverer#doGetMapValueType() */ @Override - protected TypeInformation doGetMapValueType() { + protected Optional> doGetMapValueType() { if (Map.class.isAssignableFrom(getType())) { Type[] arguments = type.getActualTypeArguments(); if (arguments.length > 1) { - return createInfo(arguments[1]); + return Optional.of(createInfo(arguments[1])); } } Class rawType = getType(); - Set supertypes = new HashSet(); - supertypes.add(rawType.getGenericSuperclass()); + Set supertypes = new HashSet<>(); + Optional.ofNullable(rawType.getGenericSuperclass()).ifPresent(it -> supertypes.add(it)); supertypes.addAll(Arrays.asList(rawType.getGenericInterfaces())); - for (Type supertype : supertypes) { + Optional> result = supertypes.stream()// + .map(it -> Pair.of(it, resolveType(it)))// + .filter(it -> Map.class.isAssignableFrom(it.getSecond()))// + .>map(it -> { - Class rawSuperType = resolveType(supertype); + ParameterizedType parameterizedSupertype = (ParameterizedType) it.getFirst(); + Type[] arguments = parameterizedSupertype.getActualTypeArguments(); + return createInfo(arguments[1]); + }).findFirst(); - if (Map.class.isAssignableFrom(rawSuperType)) { - - ParameterizedType parameterizedSupertype = (ParameterizedType) supertype; - Type[] arguments = parameterizedSupertype.getActualTypeArguments(); - return createInfo(arguments[1]); - } - } - - return super.doGetMapValueType(); + return result.isPresent() ? result : super.doGetMapValueType(); } /* @@ -123,8 +122,8 @@ class ParameterizedTypeInformation extends ParentTypeAwareTypeInformation return false; } - TypeInformation otherTypeInformation = rawType.equals(rawTargetType) ? target : target - .getSuperTypeInformation(rawType); + TypeInformation otherTypeInformation = rawType.equals(rawTargetType) ? target + : target.getSuperTypeInformation(rawType); List> myParameters = getTypeArguments(); List> typeParameters = otherTypeInformation.getTypeArguments(); @@ -147,8 +146,8 @@ class ParameterizedTypeInformation extends ParentTypeAwareTypeInformation * @see org.springframework.data.util.TypeDiscoverer#doGetComponentType() */ @Override - protected TypeInformation doGetComponentType() { - return createInfo(type.getActualTypeArguments()[0]); + protected Optional> doGetComponentType() { + return Optional.of(createInfo(type.getActualTypeArguments()[0])); } /* diff --git a/src/main/java/org/springframework/data/util/ParsingUtils.java b/src/main/java/org/springframework/data/util/ParsingUtils.java index f227c3677..011701527 100644 --- a/src/main/java/org/springframework/data/util/ParsingUtils.java +++ b/src/main/java/org/springframework/data/util/ParsingUtils.java @@ -81,7 +81,7 @@ public abstract class ParsingUtils { Assert.notNull(source, "Source string must not be null!"); String[] parts = CAMEL_CASE.split(source); - List result = new ArrayList(parts.length); + List result = new ArrayList<>(parts.length); for (String part : parts) { result.add(toLower ? part.toLowerCase() : part); diff --git a/src/main/java/org/springframework/data/util/ReflectionUtils.java b/src/main/java/org/springframework/data/util/ReflectionUtils.java index 6673aedb2..365943d01 100644 --- a/src/main/java/org/springframework/data/util/ReflectionUtils.java +++ b/src/main/java/org/springframework/data/util/ReflectionUtils.java @@ -24,10 +24,14 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; +import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import java.util.stream.Stream; import org.springframework.beans.BeanUtils; +import org.springframework.core.ResolvableType; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -271,6 +275,17 @@ public abstract class ReflectionUtils { return Stream.concat(returnType, parameterTypes); } + public static Optional getMethod(Class type, String name, ResolvableType... parameterTypes) { + + List> collect = Arrays.stream(parameterTypes).map(it -> it.getRawClass()).collect(Collectors.toList()); + + Optional method = Optional.ofNullable( + org.springframework.util.ReflectionUtils.findMethod(type, name, collect.toArray(new Class[collect.size()]))); + + return method.filter(it -> IntStream.range(0, it.getParameterCount())// + .allMatch(index -> ResolvableType.forMethodParameter(it, index).equals(parameterTypes[index]))); + } + private static final boolean argumentsMatch(Class[] parameterTypes, Object[] arguments) { if (parameterTypes.length != arguments.length) { diff --git a/src/main/java/org/springframework/data/util/Streamable.java b/src/main/java/org/springframework/data/util/Streamable.java index d3480abed..bfc381152 100644 --- a/src/main/java/org/springframework/data/util/Streamable.java +++ b/src/main/java/org/springframework/data/util/Streamable.java @@ -38,10 +38,21 @@ public interface Streamable extends Iterable { return StreamSupport.stream(spliterator(), false); } + /** + * Returns an empty {@link Streamable}. + * + * @return will never be {@literal null}. + */ public static Streamable empty() { return () -> Collections.emptyIterator(); } + /** + * Returns a {@link Streamable} with the given elements. + * + * @param t the elements to return. + * @return + */ @SafeVarargs public static Streamable of(T... t) { return () -> Arrays.asList(t).iterator(); diff --git a/src/main/java/org/springframework/data/util/TypeDiscoverer.java b/src/main/java/org/springframework/data/util/TypeDiscoverer.java index 8355db256..47443322f 100644 --- a/src/main/java/org/springframework/data/util/TypeDiscoverer.java +++ b/src/main/java/org/springframework/data/util/TypeDiscoverer.java @@ -15,11 +15,9 @@ */ package org.springframework.data.util; -import lombok.AccessLevel; import lombok.EqualsAndHashCode; import lombok.NonNull; import lombok.RequiredArgsConstructor; -import lombok.Value; import java.beans.PropertyDescriptor; import java.lang.reflect.Constructor; @@ -38,8 +36,10 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; import org.springframework.beans.BeanUtils; import org.springframework.core.GenericTypeResolver; @@ -72,19 +72,15 @@ class TypeDiscoverer implements TypeInformation { private final Type type; private final Map, Type> typeVariableMap; - private final Map fieldTypes = new ConcurrentHashMap(); + private final Map>> fieldTypes = new ConcurrentHashMap<>(); private final int hashCode; - private boolean componentTypeResolved = false; - private TypeInformation componentType; - - private boolean valueTypeResolved = false; - private TypeInformation valueType; - - private Class resolvedType; + private final Lazy> resolvedType; + private final Lazy>> componentType; + private final Lazy>> valueType; /** - * Creates a ne {@link TypeDiscoverer} for the given type, type variable map and parent. + * Creates a new {@link TypeDiscoverer} for the given type, type variable map and parent. * * @param type must not be {@literal null}. * @param typeVariableMap must not be {@literal null}. @@ -95,6 +91,9 @@ class TypeDiscoverer implements TypeInformation { Assert.notNull(typeVariableMap, "TypeVariableMap must not be null!"); this.type = type; + this.resolvedType = Lazy.of(() -> resolveType(type)); + this.componentType = Lazy.of(() -> doGetComponentType()); + this.valueType = Lazy.of(() -> doGetMapValueType()); this.typeVariableMap = typeVariableMap; this.hashCode = 17 + (31 * type.hashCode()) + (31 * typeVariableMap.hashCode()); } @@ -108,6 +107,10 @@ class TypeDiscoverer implements TypeInformation { return typeVariableMap; } + private TypeInformation createInfo(Optional fieldType) { + return fieldType.map(it -> createInfo(it)).orElseThrow(() -> new IllegalArgumentException()); + } + /** * Creates {@link TypeInformation} for the given {@link Type}. * @@ -208,25 +211,18 @@ class TypeDiscoverer implements TypeInformation { * (non-Javadoc) * @see org.springframework.data.util.TypeInformation#getProperty(java.lang.String) */ - public TypeInformation getProperty(String fieldname) { + public Optional> getProperty(String fieldname) { int separatorIndex = fieldname.indexOf('.'); if (separatorIndex == -1) { - - if (fieldTypes.containsKey(fieldname)) { - return fieldTypes.get(fieldname).getType(); - } - - TypeInformation propertyInformation = getPropertyInformation(fieldname); - fieldTypes.put(fieldname, ValueHolder.of(propertyInformation)); - - return propertyInformation; + return fieldTypes.computeIfAbsent(fieldname, it -> getPropertyInformation(it)); } String head = fieldname.substring(0, separatorIndex); - TypeInformation info = getProperty(head); - return info == null ? null : info.getProperty(fieldname.substring(separatorIndex + 1)); + Optional> info = getProperty(head); + + return info.map(it -> it.getProperty(fieldname.substring(separatorIndex + 1))).orElseGet(() -> Optional.empty()); } /** @@ -237,17 +233,17 @@ class TypeDiscoverer implements TypeInformation { * @param fieldname * @return */ - private TypeInformation getPropertyInformation(String fieldname) { + private Optional> getPropertyInformation(String fieldname) { Class rawType = getType(); Field field = ReflectionUtils.findField(rawType, fieldname); if (field != null) { - return createInfo(field.getGenericType()); + return Optional.of(createInfo(field.getGenericType())); } - PropertyDescriptor descriptor = findPropertyDescriptor(rawType, fieldname); - return descriptor == null ? null : createInfo(getGenericType(descriptor)); + return findPropertyDescriptor(rawType, fieldname).map(it -> createInfo(getGenericType(it))); + } /** @@ -257,26 +253,21 @@ class TypeDiscoverer implements TypeInformation { * @param fieldname must not be {@literal null} or empty. * @return */ - private static PropertyDescriptor findPropertyDescriptor(Class type, String fieldname) { + private static Optional findPropertyDescriptor(Class type, String fieldname) { PropertyDescriptor descriptor = BeanUtils.getPropertyDescriptor(type, fieldname); if (descriptor != null) { - return descriptor; + return Optional.of(descriptor); } List> superTypes = new ArrayList>(); superTypes.addAll(Arrays.asList(type.getInterfaces())); superTypes.add(type.getSuperclass()); - for (Class interfaceType : type.getInterfaces()) { - descriptor = findPropertyDescriptor(interfaceType, fieldname); - if (descriptor != null) { - return descriptor; - } - } - - return null; + return Streamable.of(type.getInterfaces()).stream()// + .flatMap(it -> Optionals.toStream(findPropertyDescriptor(it, fieldname)))// + .findFirst(); } /** @@ -286,22 +277,22 @@ class TypeDiscoverer implements TypeInformation { * @param descriptor must not be {@literal null} * @return */ - private static Type getGenericType(PropertyDescriptor descriptor) { + private static Optional getGenericType(PropertyDescriptor descriptor) { Method method = descriptor.getReadMethod(); if (method != null) { - return method.getGenericReturnType(); + return Optional.of(method.getGenericReturnType()); } method = descriptor.getWriteMethod(); if (method == null) { - return null; + return Optional.empty(); } Type[] parameterTypes = method.getGenericParameterTypes(); - return parameterTypes.length == 0 ? null : parameterTypes[0]; + return Optional.ofNullable(parameterTypes.length == 0 ? null : parameterTypes[0]); } /* @@ -309,12 +300,7 @@ class TypeDiscoverer implements TypeInformation { * @see org.springframework.data.util.TypeInformation#getType() */ public Class getType() { - - if (resolvedType == null) { - this.resolvedType = resolveType(type); - } - - return this.resolvedType; + return resolvedType.get(); } /* @@ -333,11 +319,11 @@ class TypeDiscoverer implements TypeInformation { public TypeInformation getActualType() { if (isMap()) { - return getMapValueType(); + return getMapValueType().orElse(null); } if (isCollectionLike()) { - return getComponentType(); + return getComponentType().orElse(null); } return this; @@ -362,29 +348,12 @@ class TypeDiscoverer implements TypeInformation { * (non-Javadoc) * @see org.springframework.data.util.TypeInformation#getMapValueType() */ - public TypeInformation getMapValueType() { - - if (!valueTypeResolved) { - this.valueType = doGetMapValueType(); - this.valueTypeResolved = true; - } - - return this.valueType; + public Optional> getMapValueType() { + return valueType.get(); } - protected TypeInformation doGetMapValueType() { - - if (isMap()) { - return getTypeArgument(getBaseType(MAP_TYPES), 1); - } - - List> arguments = getTypeArguments(); - - if (arguments.size() > 1) { - return arguments.get(1); - } - - return null; + protected Optional> doGetMapValueType() { + return isMap() ? getTypeArgument(getBaseType(MAP_TYPES), 1) : getTypeArguments().stream().skip(1).findFirst(); } /* @@ -395,33 +364,23 @@ class TypeDiscoverer implements TypeInformation { Class rawType = getType(); - if (rawType.isArray() || Iterable.class.equals(rawType)) { - return true; - } - - return Collection.class.isAssignableFrom(rawType); + return rawType.isArray() || Iterable.class.equals(rawType) || Collection.class.isAssignableFrom(rawType); } /* * (non-Javadoc) * @see org.springframework.data.util.TypeInformation#getComponentType() */ - public final TypeInformation getComponentType() { - - if (!componentTypeResolved) { - this.componentType = doGetComponentType(); - this.componentTypeResolved = true; - } - - return this.componentType; + public final Optional> getComponentType() { + return componentType.get(); } - protected TypeInformation doGetComponentType() { + protected Optional> doGetComponentType() { Class rawType = getType(); if (rawType.isArray()) { - return createInfo(rawType.getComponentType()); + return Optional.of(createInfo(rawType.getComponentType())); } if (isMap()) { @@ -434,11 +393,7 @@ class TypeDiscoverer implements TypeInformation { List> arguments = getTypeArguments(); - if (arguments.size() > 0) { - return arguments.get(0); - } - - return null; + return arguments.size() > 0 ? Optional.of(arguments.get(0)) : Optional.empty(); } /* @@ -459,14 +414,9 @@ class TypeDiscoverer implements TypeInformation { Assert.notNull(method, "Method most not be null!"); - Type[] types = method.getGenericParameterTypes(); - List> result = new ArrayList>(types.length); - - for (Type parameterType : types) { - result.add(createInfo(parameterType)); - } - - return result; + return Streamable.of(method.getGenericParameterTypes()).stream()// + .map(it -> createInfo(it))// + .collect(Collectors.toList()); } /* @@ -485,7 +435,7 @@ class TypeDiscoverer implements TypeInformation { return this; } - List candidates = new ArrayList(); + List candidates = new ArrayList<>(); Type genericSuperclass = rawType.getGenericSuperclass(); if (genericSuperclass != null) { @@ -530,25 +480,27 @@ class TypeDiscoverer implements TypeInformation { * @see org.springframework.data.util.TypeInformation#specialize(org.springframework.data.util.ClassTypeInformation) */ @Override - public TypeInformation specialize(ClassTypeInformation type) { + @SuppressWarnings("unchecked") + public TypeInformation specialize(ClassTypeInformation type) { Assert.isTrue(getType().isAssignableFrom(type.getType()), String.format("%s must be assignable from %s", getType(), type.getType())); List> arguments = getTypeArguments(); - return arguments.isEmpty() ? type : createInfo(new SyntheticParamterizedType(type, arguments)); + return (TypeInformation) (arguments.isEmpty() ? type + : createInfo(new SyntheticParamterizedType(type, arguments))); } - private TypeInformation getTypeArgument(Class bound, int index) { + private Optional> getTypeArgument(Class bound, int index) { Class[] arguments = GenericTypeResolver.resolveTypeArguments(getType(), bound); if (arguments == null) { - return getSuperTypeInformation(bound) instanceof ParameterizedTypeInformation ? ClassTypeInformation.OBJECT - : null; + return Optional.ofNullable( + getSuperTypeInformation(bound) instanceof ParameterizedTypeInformation ? ClassTypeInformation.OBJECT : null); } - return createInfo(arguments[index]); + return Optional.of(createInfo(arguments[index])); } private Class getBaseType(Iterable> candidates) { @@ -642,22 +594,4 @@ class TypeDiscoverer implements TypeInformation { return result; } } - - /** - * Simple wrapper to be able to store {@literal null} values in a {@link ConcurrentHashMap}. - * - * @author Oliver Gierke - */ - @Value - @RequiredArgsConstructor(access = AccessLevel.PRIVATE) - private static class ValueHolder { - - static ValueHolder NULL_HOLDER = new ValueHolder(null); - - TypeInformation type; - - public static ValueHolder of(TypeInformation type) { - return null == type ? NULL_HOLDER : new ValueHolder(type); - } - } } diff --git a/src/main/java/org/springframework/data/util/TypeInformation.java b/src/main/java/org/springframework/data/util/TypeInformation.java index 632b13b96..e04de66ba 100644 --- a/src/main/java/org/springframework/data/util/TypeInformation.java +++ b/src/main/java/org/springframework/data/util/TypeInformation.java @@ -18,6 +18,7 @@ package org.springframework.data.util; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.List; +import java.util.Optional; /** * Interface to access property types and resolving generics on the way. Starting with a {@link ClassTypeInformation} @@ -36,13 +37,18 @@ public interface TypeInformation { List> getParameterTypes(Constructor constructor); /** - * Returns the property information for the property with the given name. Supports proeprty traversal through dot + * Returns the property information for the property with the given name. Supports property traversal through dot * notation. * - * @param fieldname + * @param property * @return */ - TypeInformation getProperty(String fieldname); + Optional> getProperty(String property); + + default TypeInformation getRequiredProperty(String property) { + return getProperty(property).orElseThrow(() -> new IllegalArgumentException( + String.format("Could not find required property %s on %s!", property, getType()))); + } /** * Returns whether the type can be considered a collection, which means it's a container of elements, e.g. a @@ -58,7 +64,20 @@ public interface TypeInformation { * * @return */ - TypeInformation getComponentType(); + Optional> getComponentType(); + + /** + * Returns the component type for {@link java.util.Collection}s, the key type for {@link java.util.Map}s or the single + * generic type if available throwing an exception if it can't be resolved. + * + * @return + * @throws IllegalStateException if the component type cannot be resolved, e.g. if a raw type is used or the type is + * not generic in the first place. + */ + default TypeInformation getRequiredComponentType() { + return getComponentType().orElseThrow( + () -> new IllegalStateException(String.format("Can't resolve required component type for %s!", getType()))); + } /** * Returns whether the property is a {@link java.util.Map}. If this returns {@literal true} you can expect @@ -73,7 +92,12 @@ public interface TypeInformation { * * @return */ - TypeInformation getMapValueType(); + Optional> getMapValueType(); + + default TypeInformation getRequiredMapValueType() { + return getMapValueType().orElseThrow( + () -> new IllegalStateException(String.format("Can't resolve required map value type for %s!", getType()))); + } /** * Returns the type of the property. Will resolve generics and the generic context of @@ -149,5 +173,5 @@ public interface TypeInformation { * @param type must not be {@literal null}. * @return will never be {@literal null}. */ - TypeInformation specialize(ClassTypeInformation type); + TypeInformation specialize(ClassTypeInformation type); } diff --git a/src/main/java/org/springframework/data/util/Version.java b/src/main/java/org/springframework/data/util/Version.java index ee2272f54..651edaa22 100644 --- a/src/main/java/org/springframework/data/util/Version.java +++ b/src/main/java/org/springframework/data/util/Version.java @@ -207,7 +207,7 @@ public class Version implements Comparable { @Override public String toString() { - List digits = new ArrayList(); + List digits = new ArrayList<>(); digits.add(major); digits.add(minor); diff --git a/src/main/java/org/springframework/data/web/HateoasPageableHandlerMethodArgumentResolver.java b/src/main/java/org/springframework/data/web/HateoasPageableHandlerMethodArgumentResolver.java index 886ddf088..b43995416 100644 --- a/src/main/java/org/springframework/data/web/HateoasPageableHandlerMethodArgumentResolver.java +++ b/src/main/java/org/springframework/data/web/HateoasPageableHandlerMethodArgumentResolver.java @@ -77,7 +77,7 @@ public class HateoasPageableHandlerMethodArgumentResolver extends PageableHandle String pagePropertyName = getParameterNameToUse(getPageParameterName(), parameter); String sizePropertyName = getParameterNameToUse(getSizeParameterName(), parameter); - List names = new ArrayList(); + List names = new ArrayList<>(); MultiValueMap queryParameters = template.getQueryParams(); boolean append = !queryParameters.isEmpty(); diff --git a/src/main/java/org/springframework/data/web/MapDataBinder.java b/src/main/java/org/springframework/data/web/MapDataBinder.java index 26c63fe9f..6e4719c75 100644 --- a/src/main/java/org/springframework/data/web/MapDataBinder.java +++ b/src/main/java/org/springframework/data/web/MapDataBinder.java @@ -185,14 +185,14 @@ class MapDataBinder extends WebDataBinder { PropertyPath leafProperty = getPropertyPath(propertyName).getLeafProperty(); TypeInformation owningType = leafProperty.getOwningType(); - TypeInformation propertyType = owningType.getProperty(leafProperty.getSegment()); + TypeInformation propertyType = leafProperty.getTypeInformation(); propertyType = propertyName.endsWith("]") ? propertyType.getActualType() : propertyType; if (conversionRequired(value, propertyType.getType())) { - PropertyDescriptor descriptor = BeanUtils - .getPropertyDescriptor(owningType.getType(), leafProperty.getSegment()); + PropertyDescriptor descriptor = BeanUtils.getPropertyDescriptor(owningType.getType(), + leafProperty.getSegment()); MethodParameter methodParameter = new MethodParameter(descriptor.getReadMethod(), -1); TypeDescriptor typeDescriptor = TypeDescriptor.nested(methodParameter, 0); @@ -289,11 +289,11 @@ class MapDataBinder extends WebDataBinder { Class actualPropertyType = path.getType(); - TypeDescriptor valueDescriptor = conversionService.canConvert(String.class, actualPropertyType) ? TypeDescriptor - .valueOf(String.class) : TypeDescriptor.valueOf(HashMap.class); + TypeDescriptor valueDescriptor = conversionService.canConvert(String.class, actualPropertyType) + ? TypeDescriptor.valueOf(String.class) : TypeDescriptor.valueOf(HashMap.class); - return path.isCollection() ? TypeDescriptor.collection(emptyValue.getClass(), valueDescriptor) : TypeDescriptor - .map(emptyValue.getClass(), TypeDescriptor.valueOf(String.class), valueDescriptor); + return path.isCollection() ? TypeDescriptor.collection(emptyValue.getClass(), valueDescriptor) + : TypeDescriptor.map(emptyValue.getClass(), TypeDescriptor.valueOf(String.class), valueDescriptor); } } diff --git a/src/main/java/org/springframework/data/web/PageableHandlerMethodArgumentResolver.java b/src/main/java/org/springframework/data/web/PageableHandlerMethodArgumentResolver.java index 8d0b8c6c0..fb1fd6f22 100644 --- a/src/main/java/org/springframework/data/web/PageableHandlerMethodArgumentResolver.java +++ b/src/main/java/org/springframework/data/web/PageableHandlerMethodArgumentResolver.java @@ -18,6 +18,7 @@ package org.springframework.data.web; import static org.springframework.data.web.SpringDataAnnotationUtils.*; import java.lang.reflect.Method; +import java.util.Optional; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.MethodParameter; @@ -50,9 +51,9 @@ public class PageableHandlerMethodArgumentResolver implements PageableArgumentRe private static final String DEFAULT_PREFIX = ""; private static final String DEFAULT_QUALIFIER_DELIMITER = "_"; private static final int DEFAULT_MAX_PAGE_SIZE = 2000; - static final Pageable DEFAULT_PAGE_REQUEST = new PageRequest(0, 20); + static final Pageable DEFAULT_PAGE_REQUEST = PageRequest.of(0, 20); - private Pageable fallbackPageable = DEFAULT_PAGE_REQUEST; + private Optional fallbackPageable = Optional.of(DEFAULT_PAGE_REQUEST); private SortArgumentResolver sortResolver; private String pageParameterName = DEFAULT_PAGE_PARAMETER; private String sizeParameterName = DEFAULT_SIZE_PARAMETER; @@ -92,14 +93,17 @@ public class PageableHandlerMethodArgumentResolver implements PageableArgumentRe * {@link PageableDefaults} (the latter only supported in legacy mode) can be found at the method parameter to be * resolved. *

- * If you set this to {@literal null}, be aware that you controller methods will get {@literal null} handed into them - * in case no {@link Pageable} data can be found in the request. Note, that doing so will require you supply bot the - * page and the size parameter with the requests as there will be no default for any of the parameters - * available. + * If you set this to {@literal Optional#empty()}, be aware that you controller methods will get {@literal null} + * handed into them in case no {@link Pageable} data can be found in the request. Note, that doing so will require you + * supply bot the page and the size parameter with the requests as there will be no default for any of the + * parameters available. * * @param fallbackPageable the {@link Pageable} to be used as general fallback. */ - public void setFallbackPageable(Pageable fallbackPageable) { + public void setFallbackPageable(Optional fallbackPageable) { + + Assert.notNull(fallbackPageable, "Fallback Pageable must not be null!"); + this.fallbackPageable = fallbackPageable; } @@ -235,33 +239,32 @@ public class PageableHandlerMethodArgumentResolver implements PageableArgumentRe assertPageableUniqueness(methodParameter); - Pageable defaultOrFallback = getDefaultFromAnnotationOrFallback(methodParameter); + Optional defaultOrFallback = getDefaultFromAnnotationOrFallback(methodParameter); String pageString = webRequest.getParameter(getParameterNameToUse(pageParameterName, methodParameter)); String pageSizeString = webRequest.getParameter(getParameterNameToUse(sizeParameterName, methodParameter)); - boolean pageAndSizeGiven = StringUtils.hasText(pageString) && StringUtils.hasText(pageSizeString); + Optional page = parseAndApplyBoundaries(pageString, Integer.MAX_VALUE, true); + Optional pageSize = parseAndApplyBoundaries(pageSizeString, maxPageSize, false); - if (!pageAndSizeGiven && defaultOrFallback == null) { + if (!(page.isPresent() && pageSize.isPresent()) && !defaultOrFallback.isPresent()) { return null; } - int page = StringUtils.hasText(pageString) ? parseAndApplyBoundaries(pageString, Integer.MAX_VALUE, true) - : defaultOrFallback.getPageNumber(); - int pageSize = StringUtils.hasText(pageSizeString) ? parseAndApplyBoundaries(pageSizeString, maxPageSize, false) - : defaultOrFallback.getPageSize(); + int p = page.orElseGet( + () -> defaultOrFallback.map(it -> it.getPageNumber()).orElseThrow(() -> new IllegalStateException())); + int ps = pageSize + .orElseGet(() -> defaultOrFallback.map(it -> it.getPageSize()).orElseThrow(() -> new IllegalStateException())); // Limit lower bound - pageSize = pageSize < 1 ? defaultOrFallback.getPageSize() : pageSize; + ps = ps < 1 ? defaultOrFallback.map(it -> it.getPageSize()).orElseThrow(() -> new IllegalStateException()) : ps; // Limit upper bound - pageSize = pageSize > maxPageSize ? maxPageSize : pageSize; + ps = ps > maxPageSize ? maxPageSize : ps; Sort sort = sortResolver.resolveArgument(methodParameter, mavContainer, webRequest, binderFactory); - // Default if necessary and default configured - sort = sort == null && defaultOrFallback != null ? defaultOrFallback.getSort() : sort; - - return new PageRequest(page, pageSize, sort); + return PageRequest.of(p, ps, + sort.isSorted() ? sort : defaultOrFallback.map(it -> it.getSort()).orElseGet(() -> Sort.unsorted())); } /** @@ -284,10 +287,10 @@ public class PageableHandlerMethodArgumentResolver implements PageableArgumentRe return builder.append(source).toString(); } - private Pageable getDefaultFromAnnotationOrFallback(MethodParameter methodParameter) { + private Optional getDefaultFromAnnotationOrFallback(MethodParameter methodParameter) { if (methodParameter.hasParameterAnnotation(PageableDefault.class)) { - return getDefaultPageRequestFrom(methodParameter); + return Optional.of(getDefaultPageRequestFrom(methodParameter)); } return fallbackPageable; @@ -306,10 +309,10 @@ public class PageableHandlerMethodArgumentResolver implements PageableArgumentRe } if (defaults.sort().length == 0) { - return new PageRequest(defaultPageNumber, defaultPageSize); + return PageRequest.of(defaultPageNumber, defaultPageSize); } - return new PageRequest(defaultPageNumber, defaultPageSize, defaults.direction(), defaults.sort()); + return PageRequest.of(defaultPageNumber, defaultPageSize, defaults.direction(), defaults.sort()); } /** @@ -321,13 +324,17 @@ public class PageableHandlerMethodArgumentResolver implements PageableArgumentRe * @param shiftIndex whether to shift the index if {@link #oneIndexedParameters} is set to true. * @return */ - private int parseAndApplyBoundaries(String parameter, int upper, boolean shiftIndex) { + private Optional parseAndApplyBoundaries(String parameter, int upper, boolean shiftIndex) { + + if (!StringUtils.hasText(parameter)) { + return Optional.empty(); + } try { int parsed = Integer.parseInt(parameter) - (oneIndexedParameters && shiftIndex ? 1 : 0); - return parsed < 0 ? 0 : parsed > upper ? upper : parsed; + return Optional.of(parsed < 0 ? 0 : parsed > upper ? upper : parsed); } catch (NumberFormatException e) { - return 0; + return Optional.of(0); } } } diff --git a/src/main/java/org/springframework/data/web/PagedResourcesAssembler.java b/src/main/java/org/springframework/data/web/PagedResourcesAssembler.java index 4c8c118d9..25c4642fe 100644 --- a/src/main/java/org/springframework/data/web/PagedResourcesAssembler.java +++ b/src/main/java/org/springframework/data/web/PagedResourcesAssembler.java @@ -87,7 +87,7 @@ public class PagedResourcesAssembler implements ResourceAssembler, Pa */ @Override public PagedResources> toResource(Page entity) { - return toResource(entity, new SimplePagedResourceAssembler()); + return toResource(entity, new SimplePagedResourceAssembler<>()); } /** @@ -100,7 +100,7 @@ public class PagedResourcesAssembler implements ResourceAssembler, Pa * @return */ public PagedResources> toResource(Page page, Link selfLink) { - return toResource(page, new SimplePagedResourceAssembler(), selfLink); + return toResource(page, new SimplePagedResourceAssembler<>(), selfLink); } /** @@ -152,7 +152,7 @@ public class PagedResourcesAssembler implements ResourceAssembler, Pa EmbeddedWrapper wrapper = wrappers.emptyCollectionOf(type); List embedded = Collections.singletonList(wrapper); - return addPaginationLinks(new PagedResources(embedded, metadata), page, link); + return addPaginationLinks(new PagedResources<>(embedded, metadata), page, link); } /** @@ -185,7 +185,7 @@ public class PagedResourcesAssembler implements ResourceAssembler, Pa Assert.notNull(metadata, "PageMetadata must not be null!"); Assert.notNull(page, "Page must not be null!"); - return new PagedResources(resources, metadata); + return new PagedResources<>(resources, metadata); } private PagedResources createResource(Page page, @@ -194,7 +194,7 @@ public class PagedResourcesAssembler implements ResourceAssembler, Pa Assert.notNull(page, "Page must not be null!"); Assert.notNull(assembler, "ResourceAssembler must not be null!"); - List resources = new ArrayList(page.getNumberOfElements()); + List resources = new ArrayList<>(page.getNumberOfElements()); for (S element : page) { resources.add(assembler.toResource(element)); @@ -212,7 +212,7 @@ public class PagedResourcesAssembler implements ResourceAssembler, Pa boolean isNavigable = page.hasPrevious() || page.hasNext(); if (isNavigable || forceFirstAndLastRels) { - resources.add(createLink(base, new PageRequest(0, page.getSize(), page.getSort()), Link.REL_FIRST)); + resources.add(createLink(base, PageRequest.of(0, page.getSize(), page.getSort()), Link.REL_FIRST)); } if (page.hasPrevious()) { @@ -229,7 +229,7 @@ public class PagedResourcesAssembler implements ResourceAssembler, Pa int lastIndex = page.getTotalPages() == 0 ? 0 : page.getTotalPages() - 1; - resources.add(createLink(base, new PageRequest(lastIndex, page.getSize(), page.getSort()), Link.REL_LAST)); + resources.add(createLink(base, PageRequest.of(lastIndex, page.getSize(), page.getSort()), Link.REL_LAST)); } return resources; @@ -293,7 +293,7 @@ public class PagedResourcesAssembler implements ResourceAssembler, Pa @Override public Resource toResource(T entity) { - return new Resource(entity); + return new Resource<>(entity); } } } diff --git a/src/main/java/org/springframework/data/web/PagedResourcesAssemblerArgumentResolver.java b/src/main/java/org/springframework/data/web/PagedResourcesAssemblerArgumentResolver.java index c9c4f79db..d5b0be120 100644 --- a/src/main/java/org/springframework/data/web/PagedResourcesAssemblerArgumentResolver.java +++ b/src/main/java/org/springframework/data/web/PagedResourcesAssemblerArgumentResolver.java @@ -86,9 +86,9 @@ public class PagedResourcesAssemblerArgumentResolver implements HandlerMethodArg MethodParameter pageableParameter = findMatchingPageableParameter(parameter); if (pageableParameter != null) { - return new MethodParameterAwarePagedResourcesAssembler(pageableParameter, resolver, fromUriString); + return new MethodParameterAwarePagedResourcesAssembler<>(pageableParameter, resolver, fromUriString); } else { - return new PagedResourcesAssembler(resolver, fromUriString); + return new PagedResourcesAssembler<>(resolver, fromUriString); } } diff --git a/src/main/java/org/springframework/data/web/SortHandlerMethodArgumentResolver.java b/src/main/java/org/springframework/data/web/SortHandlerMethodArgumentResolver.java index 2c06a081a..21edda6ad 100644 --- a/src/main/java/org/springframework/data/web/SortHandlerMethodArgumentResolver.java +++ b/src/main/java/org/springframework/data/web/SortHandlerMethodArgumentResolver.java @@ -18,6 +18,7 @@ package org.springframework.data.web; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Optional; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.MethodParameter; @@ -47,7 +48,7 @@ public class SortHandlerMethodArgumentResolver implements SortArgumentResolver { private static final String DEFAULT_PARAMETER = "sort"; private static final String DEFAULT_PROPERTY_DELIMITER = ","; private static final String DEFAULT_QUALIFIER_DELIMITER = "_"; - private static final Sort DEFAULT_SORT = null; + private static final Sort DEFAULT_SORT = Sort.unsorted(); private static final String SORT_DEFAULTS_NAME = SortDefaults.class.getSimpleName(); private static final String SORT_DEFAULT_NAME = SortDefault.class.getSimpleName(); @@ -143,14 +144,17 @@ public class SortHandlerMethodArgumentResolver implements SortArgumentResolver { } if (annotatedDefault != null) { - return appendOrCreateSortTo(annotatedDefault, null); + return appendOrCreateSortTo(annotatedDefault, Sort.unsorted()); } if (annotatedDefaults != null) { - Sort sort = null; + + Sort sort = Sort.unsorted(); + for (SortDefault currentAnnotatedDefault : annotatedDefaults.value()) { sort = appendOrCreateSortTo(currentAnnotatedDefault, sort); } + return sort; } @@ -170,11 +174,10 @@ public class SortHandlerMethodArgumentResolver implements SortArgumentResolver { String[] fields = SpringDataAnnotationUtils.getSpecificPropertyOrDefaultFromValue(sortDefault, "sort"); if (fields.length == 0) { - return null; + return Sort.unsorted(); } - Sort sort = new Sort(sortDefault.direction(), fields); - return sortOrNull == null ? sort : sortOrNull.and(sort); + return sortOrNull.and(new Sort(sortDefault.direction(), fields)); } /** @@ -214,25 +217,27 @@ public class SortHandlerMethodArgumentResolver implements SortArgumentResolver { } String[] elements = part.split(delimiter); - Direction direction = elements.length == 0 ? null : Direction.fromStringOrNull(elements[elements.length - 1]); - for (int i = 0; i < elements.length; i++) { + Optional direction = elements.length == 0 ? Optional.empty() + : Direction.fromOptionalString(elements[elements.length - 1]); + + int lastIndex = direction.map(it -> elements.length - 1).orElseGet(() -> elements.length); - if (i == elements.length - 1 && direction != null) { - continue; - } + for (int i = 0; i < lastIndex; i++) { + toOrder(elements[i], direction).ifPresent(it -> allOrders.add(it)); + } + } - String property = elements[i]; + return allOrders.isEmpty() ? Sort.unsorted() : Sort.by(allOrders); + } - if (!StringUtils.hasText(property)) { - continue; - } + private static Optional toOrder(String property, Optional direction) { - allOrders.add(new Order(direction, property)); - } + if (!StringUtils.hasText(property)) { + return Optional.empty(); } - return allOrders.isEmpty() ? null : new Sort(allOrders); + return Optional.of(direction.map(it -> new Order(it, property)).orElseGet(() -> new Order(property))); } /** @@ -244,7 +249,7 @@ public class SortHandlerMethodArgumentResolver implements SortArgumentResolver { */ protected List foldIntoExpressions(Sort sort) { - List expressions = new ArrayList(); + List expressions = new ArrayList<>(); ExpressionBuilder builder = null; for (Order order : sort) { @@ -274,7 +279,7 @@ public class SortHandlerMethodArgumentResolver implements SortArgumentResolver { */ protected List legacyFoldExpressions(Sort sort) { - List expressions = new ArrayList(); + List expressions = new ArrayList<>(); ExpressionBuilder builder = null; for (Order order : sort) { @@ -301,7 +306,7 @@ public class SortHandlerMethodArgumentResolver implements SortArgumentResolver { */ class ExpressionBuilder { - private final List elements = new ArrayList(); + private final List elements = new ArrayList<>(); private final Direction direction; /** diff --git a/src/main/java/org/springframework/data/web/SpringDataAnnotationUtils.java b/src/main/java/org/springframework/data/web/SpringDataAnnotationUtils.java index 0a4905913..cb6eac4d6 100644 --- a/src/main/java/org/springframework/data/web/SpringDataAnnotationUtils.java +++ b/src/main/java/org/springframework/data/web/SpringDataAnnotationUtils.java @@ -102,7 +102,7 @@ abstract class SpringDataAnnotationUtils { */ public static void assertQualifiersFor(Class[] parameterTypes, Annotation[][] annotations) { - Set values = new HashSet(); + Set values = new HashSet<>(); for (int i = 0; i < annotations.length; i++) { diff --git a/src/main/java/org/springframework/data/web/config/EnableSpringDataWebSupport.java b/src/main/java/org/springframework/data/web/config/EnableSpringDataWebSupport.java index d895f8d8a..42dafb695 100644 --- a/src/main/java/org/springframework/data/web/config/EnableSpringDataWebSupport.java +++ b/src/main/java/org/springframework/data/web/config/EnableSpringDataWebSupport.java @@ -116,7 +116,7 @@ public @interface EnableSpringDataWebSupport { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { - List imports = new ArrayList(); + List imports = new ArrayList<>(); imports.add(HATEOAS_PRESENT ? HateoasAwareSpringDataWebConfiguration.class.getName() : SpringDataWebConfiguration.class.getName()); diff --git a/src/main/java/org/springframework/data/web/config/HateoasAwareSpringDataWebConfiguration.java b/src/main/java/org/springframework/data/web/config/HateoasAwareSpringDataWebConfiguration.java index c64d6eece..ef9351a30 100644 --- a/src/main/java/org/springframework/data/web/config/HateoasAwareSpringDataWebConfiguration.java +++ b/src/main/java/org/springframework/data/web/config/HateoasAwareSpringDataWebConfiguration.java @@ -71,7 +71,7 @@ public class HateoasAwareSpringDataWebConfiguration extends SpringDataWebConfigu @Bean public PagedResourcesAssembler pagedResourcesAssembler() { - return new PagedResourcesAssembler(pageableResolver(), null); + return new PagedResourcesAssembler<>(pageableResolver(), null); } @Bean diff --git a/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java b/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java index 138ccefcd..93e6190dc 100644 --- a/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java +++ b/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java @@ -95,7 +95,7 @@ public class SpringDataWebConfiguration extends WebMvcConfigurerAdapter { FormattingConversionService conversionService = (FormattingConversionService) registry; - DomainClassConverter converter = new DomainClassConverter( + DomainClassConverter converter = new DomainClassConverter<>( conversionService); converter.setApplicationContext(context); } diff --git a/src/main/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolver.java b/src/main/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolver.java index cd7211aea..f9a7dc87e 100644 --- a/src/main/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolver.java +++ b/src/main/java/org/springframework/data/web/querydsl/QuerydslPredicateArgumentResolver.java @@ -61,7 +61,7 @@ public class QuerydslPredicateArgumentResolver implements HandlerMethodArgumentR Optional conversionService) { this.bindingsFactory = factory; - this.predicateBuilder = new QuerydslPredicateBuilder(conversionService.orElse(new DefaultConversionService()), + this.predicateBuilder = new QuerydslPredicateBuilder(conversionService.orElseGet(DefaultConversionService::new), factory.getEntityPathResolver()); } @@ -104,7 +104,7 @@ public class QuerydslPredicateArgumentResolver implements HandlerMethodArgumentR TypeInformation domainType = extractTypeInfo(parameter).getActualType(); Optional> map = annotation - .> map(it -> it.bindings()); + .>map(it -> it.bindings()); QuerydslBindings bindings = bindingsFactory.createBindingsFor(domainType, (Optional>>) map); @@ -125,7 +125,7 @@ public class QuerydslPredicateArgumentResolver implements HandlerMethodArgumentR .ofNullable(parameter.getParameterAnnotation(QuerydslPredicate.class)); return annotation.filter(it -> !Object.class.equals(it.root()))// - .> map(it -> ClassTypeInformation.from(it.root()))// + .>map(it -> ClassTypeInformation.from(it.root()))// .orElseGet(() -> detectDomainType(ClassTypeInformation.fromReturnTypeOf(parameter.getMethod()))); } @@ -145,6 +145,6 @@ public class QuerydslPredicateArgumentResolver implements HandlerMethodArgumentR return source; } - return detectDomainType(source.getComponentType()); + return detectDomainType(source.getRequiredComponentType()); } } diff --git a/src/test/java/org/springframework/data/auditing/config/AuditingBeanDefinitionRegistrarSupportUnitTests.java b/src/test/java/org/springframework/data/auditing/config/AuditingBeanDefinitionRegistrarSupportUnitTests.java index 0b7975d76..cada992ef 100755 --- a/src/test/java/org/springframework/data/auditing/config/AuditingBeanDefinitionRegistrarSupportUnitTests.java +++ b/src/test/java/org/springframework/data/auditing/config/AuditingBeanDefinitionRegistrarSupportUnitTests.java @@ -14,7 +14,7 @@ */ package org.springframework.data.auditing.config; -import static org.mockito.Matchers.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.lang.annotation.Annotation; diff --git a/src/test/java/org/springframework/data/convert/ClassGeneratingEntityInstantiatorUnitTests.java b/src/test/java/org/springframework/data/convert/ClassGeneratingEntityInstantiatorUnitTests.java index 6a1d22d82..49eb90f1b 100755 --- a/src/test/java/org/springframework/data/convert/ClassGeneratingEntityInstantiatorUnitTests.java +++ b/src/test/java/org/springframework/data/convert/ClassGeneratingEntityInstantiatorUnitTests.java @@ -16,7 +16,7 @@ package org.springframework.data.convert; import static org.assertj.core.api.Assertions.*; -import static org.mockito.Matchers.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import static org.springframework.data.util.ClassTypeInformation.*; @@ -24,9 +24,7 @@ import java.lang.reflect.Constructor; import java.util.Arrays; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; import java.util.stream.IntStream; -import java.util.stream.Stream; import org.junit.Before; import org.junit.Test; @@ -279,12 +277,6 @@ public class ClassGeneratingEntityInstantiatorUnitTests

result = Stream.of("1", null).map(it -> (String) null).collect(Collectors.toList()); - } - static class Foo { Foo(String foo) { diff --git a/src/test/java/org/springframework/data/convert/ConfigurableTypeInformationMapperUnitTests.java b/src/test/java/org/springframework/data/convert/ConfigurableTypeInformationMapperUnitTests.java index 8721c54a4..4880d44c7 100755 --- a/src/test/java/org/springframework/data/convert/ConfigurableTypeInformationMapperUnitTests.java +++ b/src/test/java/org/springframework/data/convert/ConfigurableTypeInformationMapperUnitTests.java @@ -25,9 +25,9 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.data.mapping.Alias; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.util.ClassTypeInformation; -import org.springframework.data.util.TypeInformation; /** * Unit tests for {@link ConfigurableTypeMapper}. @@ -62,15 +62,14 @@ public class ConfigurableTypeInformationMapperUnitTests STRING_TYPE_INFO = ClassTypeInformation.from(String.class); - static final String STRING = String.class.getName(); + static final Alias ALIAS = Alias.of(String.class.getName()); @Mock TypeAliasAccessor> accessor; - @Mock TypeInformationMapper mapper; DefaultTypeMapper> typeMapper; @@ -52,29 +54,28 @@ public class DefaultTypeMapperUnitTests { public void setUp() { this.typeMapper = new DefaultTypeMapper>(accessor, Arrays.asList(mapper)); - this.source = Collections.singletonMap("key", STRING); + this.source = Collections.singletonMap("key", ALIAS.toString()); - doReturn(STRING).when(accessor).readAliasFrom(source); - doReturn(STRING_TYPE_INFO).when(mapper).resolveTypeFrom(STRING); + doReturn(ALIAS).when(accessor).readAliasFrom(source); + doReturn(Optional.of(STRING_TYPE_INFO)).when(mapper).resolveTypeFrom(ALIAS); } @Test - @SuppressWarnings("rawtypes") public void cachesResolvedTypeInformation() { - TypeInformation information = typeMapper.readType(source); - assertThat(information).isEqualTo((TypeInformation) STRING_TYPE_INFO); - verify(mapper, times(1)).resolveTypeFrom(STRING); + Optional> information = typeMapper.readType(source); + assertThat(information).hasValue(STRING_TYPE_INFO); + verify(mapper, times(1)).resolveTypeFrom(ALIAS); typeMapper.readType(source); - verify(mapper, times(1)).resolveTypeFrom(STRING); + verify(mapper, times(1)).resolveTypeFrom(ALIAS); } @Test // DATACMNS-349 public void returnsTypeAliasForInformation() { - Object alias = "alias"; - when(mapper.createAliasFor(STRING_TYPE_INFO)).thenReturn(alias); + Alias alias = Alias.of("alias"); + doReturn(alias).when(mapper).createAliasFor(STRING_TYPE_INFO); assertThat(this.typeMapper.getAliasFor(STRING_TYPE_INFO)).isEqualTo(alias); } @@ -83,16 +84,22 @@ public class DefaultTypeMapperUnitTests { public void specializesRawSourceTypeUsingGenericContext() { ClassTypeInformation root = ClassTypeInformation.from(Foo.class); - TypeInformation propertyType = root.getProperty("abstractBar"); + TypeInformation propertyType = root.getProperty("abstractBar") + .orElseThrow(() -> new IllegalStateException("Property abstractBar not found!")); TypeInformation barType = ClassTypeInformation.from(Bar.class); - doReturn(barType).when(accessor).readAliasFrom(source); - doReturn(barType).when(mapper).resolveTypeFrom(barType); + doReturn(Alias.of(barType)).when(accessor).readAliasFrom(source); + doReturn(Optional.of(barType)).when(mapper).resolveTypeFrom(Alias.of(barType)); TypeInformation result = typeMapper.readType(source, propertyType); - assertThat(result.getType()).isEqualTo(Bar.class); - assertThat(result.getProperty("field").getType()).isEqualTo(Character.class); + assertThat(result).isInstanceOf(TypeInformation.class); + + TypeInformation typeInformation = TypeInformation.class.cast(result); + + assertThat(typeInformation.getType()).isEqualTo(Bar.class); + OptionalAssert.assertOptional(typeInformation.getProperty("field")).value(nested -> nested.getType()) + .isEqualTo(Character.class); } static class TypeWithAbstractGenericType { diff --git a/src/test/java/org/springframework/data/convert/MappingContextTypeInformationMapperUnitTests.java b/src/test/java/org/springframework/data/convert/MappingContextTypeInformationMapperUnitTests.java index 30cd73771..6debca203 100755 --- a/src/test/java/org/springframework/data/convert/MappingContextTypeInformationMapperUnitTests.java +++ b/src/test/java/org/springframework/data/convert/MappingContextTypeInformationMapperUnitTests.java @@ -23,12 +23,12 @@ import java.util.Collections; import org.junit.Before; import org.junit.Test; import org.springframework.data.annotation.TypeAlias; +import org.springframework.data.mapping.Alias; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.context.SampleMappingContext; import org.springframework.data.mapping.context.SamplePersistentProperty; import org.springframework.data.util.AnnotatedTypeScanner; import org.springframework.data.util.ClassTypeInformation; -import org.springframework.data.util.TypeInformation; /** * Unit tests for {@link MappingContextTypeInformationMapper}. @@ -58,7 +58,7 @@ public class MappingContextTypeInformationMapperUnitTests { mapper = new MappingContextTypeInformationMapper(mappingContext); - assertThat(mapper.createAliasFor(ClassTypeInformation.from(Entity.class))).isEqualTo("foo"); + assertThat(mapper.createAliasFor(ClassTypeInformation.from(Entity.class)).hasValue("foo")).isTrue(); } @Test @@ -69,7 +69,7 @@ public class MappingContextTypeInformationMapperUnitTests { mapper = new MappingContextTypeInformationMapper(mappingContext); - assertThat(mapper.createAliasFor(from(Entity.class))).isEqualTo("foo"); + assertThat(mapper.createAliasFor(from(Entity.class)).hasValue("foo")).isTrue(); } @Test @@ -79,23 +79,22 @@ public class MappingContextTypeInformationMapperUnitTests { mappingContext.initialize(); mapper = new MappingContextTypeInformationMapper(mappingContext); - assertThat(mapper.createAliasFor(from(String.class))).isNull(); + assertThat(mapper.createAliasFor(from(String.class)).isPresent()).isFalse(); } @Test - @SuppressWarnings("rawtypes") public void detectsTypeForUnknownEntity() { SampleMappingContext mappingContext = new SampleMappingContext(); mappingContext.initialize(); mapper = new MappingContextTypeInformationMapper(mappingContext); - assertThat(mapper.resolveTypeFrom("foo")).isNull(); + assertThat(mapper.resolveTypeFrom(Alias.of("foo"))).isEmpty(); - PersistentEntity entity = mappingContext.getPersistentEntity(Entity.class); + PersistentEntity entity = mappingContext.getRequiredPersistentEntity(Entity.class); assertThat(entity).isNotNull(); - assertThat(mapper.resolveTypeFrom("foo")).isEqualTo((TypeInformation) from(Entity.class)); + assertThat(mapper.resolveTypeFrom(Alias.of("foo"))).hasValue(from(Entity.class)); } @Test // DATACMNS-485 diff --git a/src/test/java/org/springframework/data/convert/ReflectionEntityInstantiatorUnitTests.java b/src/test/java/org/springframework/data/convert/ReflectionEntityInstantiatorUnitTests.java index 4e5a3563f..6fbecce23 100755 --- a/src/test/java/org/springframework/data/convert/ReflectionEntityInstantiatorUnitTests.java +++ b/src/test/java/org/springframework/data/convert/ReflectionEntityInstantiatorUnitTests.java @@ -16,7 +16,7 @@ package org.springframework.data.convert; import static org.assertj.core.api.Assertions.*; -import static org.mockito.Matchers.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import static org.springframework.data.convert.ReflectionEntityInstantiator.*; import static org.springframework.data.util.ClassTypeInformation.*; @@ -81,7 +81,6 @@ public class ReflectionEntityInstantiatorUnitTests

> constructor = new PreferredConstructorDiscoverer(Foo.class) .getConstructor(); - doReturn(Foo.class).when(entity).getType(); doReturn(constructor).when(entity).getPersistenceConstructor(); doReturn(Optional.empty()).when(provider).getParameterValue(any()); diff --git a/src/test/java/org/springframework/data/convert/SimpleTypeInformationMapperUnitTests.java b/src/test/java/org/springframework/data/convert/SimpleTypeInformationMapperUnitTests.java index 40b1980a7..6fc744ac3 100755 --- a/src/test/java/org/springframework/data/convert/SimpleTypeInformationMapperUnitTests.java +++ b/src/test/java/org/springframework/data/convert/SimpleTypeInformationMapperUnitTests.java @@ -17,7 +17,10 @@ package org.springframework.data.convert; import static org.assertj.core.api.Assertions.*; +import java.util.Optional; + import org.junit.Test; +import org.springframework.data.mapping.Alias; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; @@ -28,46 +31,38 @@ import org.springframework.data.util.TypeInformation; */ public class SimpleTypeInformationMapperUnitTests { + TypeInformationMapper mapper = new SimpleTypeInformationMapper(); + @Test - @SuppressWarnings({ "rawtypes" }) public void resolvesTypeByLoadingClass() { - TypeInformationMapper mapper = new SimpleTypeInformationMapper(); - TypeInformation type = mapper.resolveTypeFrom("java.lang.String"); + Optional> type = mapper.resolveTypeFrom(Alias.of("java.lang.String")); - TypeInformation expected = ClassTypeInformation.from(String.class); + TypeInformation expected = ClassTypeInformation.from(String.class); - assertThat(type).isEqualTo(expected); + assertThat(type).hasValue(expected); } @Test public void returnsNullForNonStringKey() { - - TypeInformationMapper mapper = new SimpleTypeInformationMapper(); - assertThat(mapper.resolveTypeFrom(new Object())).isNull(); + assertThat(mapper.resolveTypeFrom(Alias.of(new Object()))).isEmpty(); } @Test public void returnsNullForEmptyTypeKey() { - - TypeInformationMapper mapper = new SimpleTypeInformationMapper(); - assertThat(mapper.resolveTypeFrom("")).isNull(); + assertThat(mapper.resolveTypeFrom(Alias.of(""))).isEmpty(); } @Test public void returnsNullForUnloadableClass() { - TypeInformationMapper mapper = new SimpleTypeInformationMapper(); - assertThat(mapper.resolveTypeFrom("Foo")).isNull(); + assertThat(mapper.resolveTypeFrom(Alias.of("Foo"))).isEmpty(); } @Test public void usesFullyQualifiedClassNameAsTypeKey() { - TypeInformationMapper mapper = new SimpleTypeInformationMapper(); - Object alias = mapper.createAliasFor(ClassTypeInformation.from(String.class)); - - assertThat(alias).isInstanceOf(String.class); - assertThat(alias).isEqualTo(String.class.getName()); + assertThat(mapper.createAliasFor(ClassTypeInformation.from(String.class))) + .isEqualTo(Alias.of(String.class.getName())); } } diff --git a/src/test/java/org/springframework/data/domain/PageImplUnitTests.java b/src/test/java/org/springframework/data/domain/PageImplUnitTests.java index 381f4dc91..b0b22a32d 100755 --- a/src/test/java/org/springframework/data/domain/PageImplUnitTests.java +++ b/src/test/java/org/springframework/data/domain/PageImplUnitTests.java @@ -23,7 +23,6 @@ import java.util.Collections; import java.util.List; import org.junit.Test; -import org.springframework.core.convert.converter.Converter; /** * Unit test for {@link PageImpl}. @@ -35,76 +34,76 @@ public class PageImplUnitTests { @Test public void assertEqualsForSimpleSetup() throws Exception { - PageImpl page = new PageImpl(Arrays.asList("Foo")); + PageImpl page = new PageImpl<>(Arrays.asList("Foo")); assertEqualsAndHashcode(page, page); - assertEqualsAndHashcode(page, new PageImpl(Arrays.asList("Foo"))); + assertEqualsAndHashcode(page, new PageImpl<>(Arrays.asList("Foo"))); } @Test public void assertEqualsForComplexSetup() throws Exception { - Pageable pageable = new PageRequest(0, 10); + Pageable pageable = PageRequest.of(0, 10); List content = Arrays.asList("Foo"); - PageImpl page = new PageImpl(content, pageable, 100); + PageImpl page = new PageImpl<>(content, pageable, 100); assertEqualsAndHashcode(page, page); - assertEqualsAndHashcode(page, new PageImpl(content, pageable, 100)); - assertNotEqualsAndHashcode(page, new PageImpl(content, pageable, 90)); - assertNotEqualsAndHashcode(page, new PageImpl(content, new PageRequest(1, 10), 100)); - assertNotEqualsAndHashcode(page, new PageImpl(content, new PageRequest(0, 15), 100)); + assertEqualsAndHashcode(page, new PageImpl<>(content, pageable, 100)); + assertNotEqualsAndHashcode(page, new PageImpl<>(content, pageable, 90)); + assertNotEqualsAndHashcode(page, new PageImpl<>(content, PageRequest.of(1, 10), 100)); + assertNotEqualsAndHashcode(page, new PageImpl<>(content, PageRequest.of(0, 15), 100)); } @Test(expected = IllegalArgumentException.class) public void preventsNullContentForSimpleSetup() throws Exception { - new PageImpl(null); + new PageImpl<>(null); } @Test(expected = IllegalArgumentException.class) public void preventsNullContentForAdvancedSetup() throws Exception { - new PageImpl(null, null, 0); + new PageImpl<>(null, null, 0); } @Test public void returnsNextPageable() { - Page page = new PageImpl(Arrays.asList(new Object()), new PageRequest(0, 1), 10); + Page page = new PageImpl<>(Arrays.asList(new Object()), PageRequest.of(0, 1), 10); assertThat(page.isFirst()).isTrue(); assertThat(page.hasPrevious()).isFalse(); - assertThat(page.previousPageable()).isNull(); + assertThat(page.previousPageable()).isEqualTo(Pageable.NONE); assertThat(page.isLast()).isFalse(); assertThat(page.hasNext()).isTrue(); - assertThat(page.nextPageable()).isEqualTo((Pageable) new PageRequest(1, 1)); + assertThat(page.nextPageable()).isEqualTo((Pageable) PageRequest.of(1, 1)); } @Test public void returnsPreviousPageable() { - Page page = new PageImpl(Arrays.asList(new Object()), new PageRequest(1, 1), 2); + Page page = new PageImpl<>(Arrays.asList(new Object()), PageRequest.of(1, 1), 2); assertThat(page.isFirst()).isFalse(); assertThat(page.hasPrevious()).isTrue(); - assertThat(page.previousPageable()).isEqualTo((Pageable) new PageRequest(0, 1)); + assertThat(page.previousPageable()).isEqualTo((Pageable) PageRequest.of(0, 1)); assertThat(page.isLast()).isTrue(); assertThat(page.hasNext()).isFalse(); - assertThat(page.nextPageable()).isNull(); + assertThat(page.nextPageable()).isEqualTo(Pageable.NONE); } @Test public void createsPageForEmptyContentCorrectly() { List list = Collections.emptyList(); - Page page = new PageImpl(list); + Page page = new PageImpl<>(list); assertThat(page.getContent()).isEqualTo(list); assertThat(page.getNumber()).isEqualTo(0); assertThat(page.getNumberOfElements()).isEqualTo(0); assertThat(page.getSize()).isEqualTo(0); - assertThat(page.getSort()).isEqualTo((Sort) null); + assertThat(page.getSort()).isEqualTo(Sort.unsorted()); assertThat(page.getTotalElements()).isEqualTo(0L); assertThat(page.getTotalPages()).isEqualTo(1); assertThat(page.hasNext()).isFalse(); @@ -117,7 +116,7 @@ public class PageImplUnitTests { @Test // DATACMNS-323 public void returnsCorrectTotalPages() { - Page page = new PageImpl(Arrays.asList("a")); + Page page = new PageImpl<>(Arrays.asList("a")); assertThat(page.getTotalPages()).isEqualTo(1); assertThat(page.hasNext()).isFalse(); @@ -127,13 +126,8 @@ public class PageImplUnitTests { @Test // DATACMNS-635 public void transformsPageCorrectly() { - Page transformed = new PageImpl(Arrays.asList("foo", "bar"), new PageRequest(0, 2), 10) - .map(new Converter() { - @Override - public Integer convert(String source) { - return source.length(); - } - }); + Page transformed = new PageImpl<>(Arrays.asList("foo", "bar"), PageRequest.of(0, 2), 10) + .map(source -> source.length()); assertThat(transformed.getContent()).hasSize(2); assertThat(transformed.getContent()).contains(3, 3); @@ -141,32 +135,30 @@ public class PageImplUnitTests { @Test // DATACMNS-713 public void adaptsTotalForLastPageOnIntermediateDeletion() { - assertThat(new PageImpl(Arrays.asList("foo", "bar"), new PageRequest(0, 5), 3).getTotalElements()) - .isEqualTo(2L); + assertThat(new PageImpl<>(Arrays.asList("foo", "bar"), PageRequest.of(0, 5), 3).getTotalElements()).isEqualTo(2L); } @Test // DATACMNS-713 public void adaptsTotalForLastPageOnIntermediateInsertion() { - assertThat(new PageImpl(Arrays.asList("foo", "bar"), new PageRequest(0, 5), 1).getTotalElements()) - .isEqualTo(2L); + assertThat(new PageImpl<>(Arrays.asList("foo", "bar"), PageRequest.of(0, 5), 1).getTotalElements()).isEqualTo(2L); } @Test // DATACMNS-713 public void adaptsTotalForLastPageOnIntermediateDeletionOnLastPate() { - assertThat(new PageImpl(Arrays.asList("foo", "bar"), new PageRequest(1, 10), 13).getTotalElements()) + assertThat(new PageImpl<>(Arrays.asList("foo", "bar"), PageRequest.of(1, 10), 13).getTotalElements()) .isEqualTo(12L); } @Test // DATACMNS-713 public void adaptsTotalForLastPageOnIntermediateInsertionOnLastPate() { - assertThat(new PageImpl(Arrays.asList("foo", "bar"), new PageRequest(1, 10), 11).getTotalElements()) + assertThat(new PageImpl<>(Arrays.asList("foo", "bar"), PageRequest.of(1, 10), 11).getTotalElements()) .isEqualTo(12L); } @Test // DATACMNS-713 public void doesNotAdapttotalIfPageIsEmpty() { - assertThat(new PageImpl(Collections. emptyList(), new PageRequest(1, 10), 0).getTotalElements()) + assertThat(new PageImpl<>(Collections.emptyList(), PageRequest.of(1, 10), 0).getTotalElements()) .isEqualTo(0L); } } diff --git a/src/test/java/org/springframework/data/domain/PageRequestUnitTests.java b/src/test/java/org/springframework/data/domain/PageRequestUnitTests.java index 6daae8a62..09f743105 100755 --- a/src/test/java/org/springframework/data/domain/PageRequestUnitTests.java +++ b/src/test/java/org/springframework/data/domain/PageRequestUnitTests.java @@ -33,32 +33,32 @@ public class PageRequestUnitTests extends AbstractPageRequestUnitTests { */ @Override public AbstractPageRequest newPageRequest(int page, int size) { - return this.newPageRequest(page, size, null); + return PageRequest.of(page, size); } public AbstractPageRequest newPageRequest(int page, int size, Sort sort) { - return new PageRequest(page, size, sort); + return PageRequest.of(page, size, sort); } @Test public void equalsRegardsSortCorrectly() { Sort sort = new Sort(Direction.DESC, "foo"); - AbstractPageRequest request = new PageRequest(0, 10, sort); + AbstractPageRequest request = PageRequest.of(0, 10, sort); // Equals itself assertEqualsAndHashcode(request, request); // Equals another instance with same setup - assertEqualsAndHashcode(request, new PageRequest(0, 10, sort)); + assertEqualsAndHashcode(request, PageRequest.of(0, 10, sort)); // Equals without sort entirely - assertEqualsAndHashcode(new PageRequest(0, 10), new PageRequest(0, 10)); + assertEqualsAndHashcode(PageRequest.of(0, 10), PageRequest.of(0, 10)); // Is not equal to instance without sort - assertNotEqualsAndHashcode(request, new PageRequest(0, 10)); + assertNotEqualsAndHashcode(request, PageRequest.of(0, 10)); // Is not equal to instance with another sort - assertNotEqualsAndHashcode(request, new PageRequest(0, 10, Direction.ASC, "foo")); + assertNotEqualsAndHashcode(request, PageRequest.of(0, 10, Direction.ASC, "foo")); } } diff --git a/src/test/java/org/springframework/data/domain/RangeUnitTests.java b/src/test/java/org/springframework/data/domain/RangeUnitTests.java index eb82ebde0..42a836978 100755 --- a/src/test/java/org/springframework/data/domain/RangeUnitTests.java +++ b/src/test/java/org/springframework/data/domain/RangeUnitTests.java @@ -29,13 +29,13 @@ public class RangeUnitTests { @Test(expected = IllegalArgumentException.class) // DATACMNS-651 public void rejectsNullReferenceValuesForContains() { - new Range(10L, 20L).contains(null); + new Range<>(10L, 20L).contains(null); } @Test // DATACMNS-651 public void usesBoundsInclusivelyByDefault() { - Range range = new Range(10L, 20L); + Range range = new Range<>(10L, 20L); assertThat(range.contains(10L)).isTrue(); assertThat(range.contains(20L)).isTrue(); @@ -47,7 +47,7 @@ public class RangeUnitTests { @Test // DATACMNS-651 public void excludesLowerBoundIfConfigured() { - Range range = new Range(10L, 20L, false, true); + Range range = new Range<>(10L, 20L, false, true); assertThat(range.contains(10L)).isFalse(); assertThat(range.contains(20L)).isTrue(); @@ -59,7 +59,7 @@ public class RangeUnitTests { @Test // DATACMNS-651 public void excludesUpperBoundIfConfigured() { - Range range = new Range(10L, 20L, true, false); + Range range = new Range<>(10L, 20L, true, false); assertThat(range.contains(10L)).isTrue(); assertThat(range.contains(20L)).isFalse(); @@ -71,7 +71,7 @@ public class RangeUnitTests { @Test // DATACMNS-651 public void handlesOpenUpperBoundCorrectly() { - Range range = new Range(10L, null); + Range range = new Range<>(10L, null); assertThat(range.contains(10L)).isTrue(); assertThat(range.contains(20L)).isTrue(); @@ -83,7 +83,7 @@ public class RangeUnitTests { @Test // DATACMNS-651 public void handlesOpenLowerBoundCorrectly() { - Range range = new Range(null, 20L); + Range range = new Range<>(null, 20L); assertThat(range.contains(10L)).isTrue(); assertThat(range.contains(20L)).isTrue(); diff --git a/src/test/java/org/springframework/data/domain/SortUnitTests.java b/src/test/java/org/springframework/data/domain/SortUnitTests.java index 62529da5b..0a27fb70d 100755 --- a/src/test/java/org/springframework/data/domain/SortUnitTests.java +++ b/src/test/java/org/springframework/data/domain/SortUnitTests.java @@ -39,7 +39,7 @@ public class SortUnitTests { @Test public void appliesDefaultForOrder() throws Exception { - assertThat(new Sort("foo").iterator().next().getDirection()).isEqualTo(Sort.DEFAULT_DIRECTION); + assertThat(Sort.by("foo").iterator().next().getDirection()).isEqualTo(Sort.DEFAULT_DIRECTION); assertThat(new Sort((Direction) null, "foo").iterator().next().getDirection()).isEqualTo(Sort.DEFAULT_DIRECTION); } @@ -90,14 +90,14 @@ public class SortUnitTests { @Test public void allowsCombiningSorts() { - Sort sort = new Sort("foo").and(new Sort("bar")); + Sort sort = Sort.by("foo").and(Sort.by("bar")); assertThat(sort).containsExactly(new Sort.Order("foo"), new Sort.Order("bar")); } @Test public void handlesAdditionalNullSort() { - Sort sort = new Sort("foo").and(null); + Sort sort = Sort.by("foo").and(null); assertThat(sort).containsExactly(new Sort.Order("foo")); } @@ -147,9 +147,9 @@ public class SortUnitTests { Order source = new Order(Direction.DESC, "foo").nullsFirst().ignoreCase(); Order result = source.withProperty("bar"); - assertThat(result.getProperty(), is("bar")); - assertThat(result.getDirection(), is(source.getDirection())); - assertThat(result.getNullHandling(), is(source.getNullHandling())); - assertThat(result.isIgnoreCase(), is(source.isIgnoreCase())); + assertThat(result.getProperty()).isEqualTo("bar"); + assertThat(result.getDirection()).isEqualTo(source.getDirection()); + assertThat(result.getNullHandling()).isEqualTo(source.getNullHandling()); + assertThat(result.isIgnoreCase()).isEqualTo(source.isIgnoreCase()); } } diff --git a/src/test/java/org/springframework/data/domain/jaxb/SpringDataJaxbUnitTests.java b/src/test/java/org/springframework/data/domain/jaxb/SpringDataJaxbUnitTests.java index 238f02d72..547e1973c 100755 --- a/src/test/java/org/springframework/data/domain/jaxb/SpringDataJaxbUnitTests.java +++ b/src/test/java/org/springframework/data/domain/jaxb/SpringDataJaxbUnitTests.java @@ -57,7 +57,7 @@ public class SpringDataJaxbUnitTests { Unmarshaller unmarshaller; Sort sort = new Sort(Direction.ASC, "firstname", "lastname"); - Pageable pageable = new PageRequest(2, 15, sort); + Pageable pageable = PageRequest.of(2, 15, sort); Resource resource = new ClassPathResource("pageable.xml", this.getClass()); Resource schemaFile = new ClassPathResource("spring-data-jaxb.xsd", this.getClass()); @@ -81,7 +81,7 @@ public class SpringDataJaxbUnitTests { Wrapper wrapper = new Wrapper(); wrapper.pageable = pageable; wrapper.sort = sort; - wrapper.pageableWithoutSort = new PageRequest(10, 20); + wrapper.pageableWithoutSort = PageRequest.of(10, 20); marshaller.marshal(wrapper, writer); assertThat(new Diff(reference, writer.toString()).similar()).isTrue(); @@ -103,8 +103,8 @@ public class SpringDataJaxbUnitTests { PageWrapper wrapper = new PageWrapper(); Content content = new Content(); content.name = "Foo"; - wrapper.page = new PageImpl(Arrays.asList(content)); - wrapper.pageWithLinks = new PageImpl(Arrays.asList(content)); + wrapper.page = new PageImpl<>(Arrays.asList(content)); + wrapper.pageWithLinks = new PageImpl<>(Arrays.asList(content)); marshaller.marshal(wrapper, new StringWriter()); } diff --git a/src/test/java/org/springframework/data/geo/GeoResultUnitTests.java b/src/test/java/org/springframework/data/geo/GeoResultUnitTests.java index 8c70f853b..bd29f9300 100755 --- a/src/test/java/org/springframework/data/geo/GeoResultUnitTests.java +++ b/src/test/java/org/springframework/data/geo/GeoResultUnitTests.java @@ -28,10 +28,10 @@ import org.springframework.util.SerializationUtils; */ public class GeoResultUnitTests { - GeoResult first = new GeoResult("Foo", new Distance(2.5)); - GeoResult second = new GeoResult("Foo", new Distance(2.5)); - GeoResult third = new GeoResult("Bar", new Distance(2.5)); - GeoResult fourth = new GeoResult("Foo", new Distance(5.2)); + GeoResult first = new GeoResult<>("Foo", new Distance(2.5)); + GeoResult second = new GeoResult<>("Foo", new Distance(2.5)); + GeoResult third = new GeoResult<>("Bar", new Distance(2.5)); + GeoResult fourth = new GeoResult<>("Foo", new Distance(5.2)); @Test // DATACMNS-437 public void considersSameInstanceEqual() { @@ -59,7 +59,7 @@ public class GeoResultUnitTests { @Test // DATACMNS-482 public void testSerialization() { - GeoResult result = new GeoResult("test", new Distance(2)); + GeoResult result = new GeoResult<>("test", new Distance(2)); @SuppressWarnings("unchecked") GeoResult serialized = (GeoResult) SerializationUtils.deserialize(SerializationUtils.serialize(result)); diff --git a/src/test/java/org/springframework/data/mapping/MappingMetadataTests.java b/src/test/java/org/springframework/data/mapping/MappingMetadataTests.java index 46a88bcd4..7be4bc1b3 100755 --- a/src/test/java/org/springframework/data/mapping/MappingMetadataTests.java +++ b/src/test/java/org/springframework/data/mapping/MappingMetadataTests.java @@ -40,7 +40,7 @@ public class MappingMetadataTests { @Test public void testPojoWithId() { - PersistentEntity person = ctx.getPersistentEntity(PersonWithId.class); + PersistentEntity person = ctx.getRequiredPersistentEntity(PersonWithId.class); assertThat(person.getIdProperty()).hasValueSatisfying(it -> assertThat(it.getType()).isEqualTo(String.class)); } @@ -48,7 +48,7 @@ public class MappingMetadataTests { @Test public void testAssociations() { - PersistentEntity person = ctx.getPersistentEntity(PersonWithChildren.class); + PersistentEntity person = ctx.getRequiredPersistentEntity(PersonWithChildren.class); person.doWithAssociations((AssociationHandler) association -> assertThat( association.getInverse().getComponentType()).isEqualTo(Child.class)); diff --git a/src/test/java/org/springframework/data/mapping/context/AbstractMappingContextIntegrationTests.java b/src/test/java/org/springframework/data/mapping/context/AbstractMappingContextIntegrationTests.java index 4d4b23eb4..a0b0a1d56 100755 --- a/src/test/java/org/springframework/data/mapping/context/AbstractMappingContextIntegrationTests.java +++ b/src/test/java/org/springframework/data/mapping/context/AbstractMappingContextIntegrationTests.java @@ -18,10 +18,7 @@ package org.springframework.data.mapping.context; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; import java.util.Collections; -import java.util.Optional; import org.junit.Test; import org.springframework.data.annotation.Id; @@ -29,6 +26,7 @@ import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.model.BasicPersistentEntity; +import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; @@ -64,7 +62,8 @@ public class AbstractMappingContextIntegrationTests entity = context.getPersistentEntity(InterfaceOnly.class); + PersistentEntity entity = context + .getRequiredPersistentEntity(InterfaceOnly.class); assertThat(entity.getIdProperty()).isNotNull(); } @@ -74,25 +73,19 @@ public class AbstractMappingContextIntegrationTests context.getPersistentEntity(Person.class)); Thread b = new Thread(new Runnable() { public void run() { - PersistentEntity entity = context.getPersistentEntity(Person.class); + PersistentEntity entity = context.getRequiredPersistentEntity(Person.class); - entity.doWithProperties(new PropertyHandler() { - public void doWithPersistentProperty(T persistentProperty) { - try { - Thread.sleep(250); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + entity.doWithProperties((PropertyHandler) persistentProperty -> { + try { + Thread.sleep(250); + } catch (InterruptedException e) { + throw new RuntimeException(e); } }); } @@ -116,13 +109,13 @@ public class AbstractMappingContextIntegrationTests field, PropertyDescriptor descriptor, - final BasicPersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { + protected T createPersistentProperty(Property property, BasicPersistentEntity owner, + SimpleTypeHolder simpleTypeHolder) { PersistentProperty prop = mock(PersistentProperty.class); when(prop.getTypeInformation()).thenReturn(owner.getTypeInformation()); - when(prop.getName()).thenReturn(field.map(Field::getName).orElse(descriptor.getName())); + when(prop.getName()).thenReturn(property.getName()); when(prop.getPersistentEntityType()).thenReturn(Collections.EMPTY_SET); try { diff --git a/src/test/java/org/springframework/data/mapping/context/AbstractMappingContextUnitTests.java b/src/test/java/org/springframework/data/mapping/context/AbstractMappingContextUnitTests.java index cff9faf15..a3967957d 100755 --- a/src/test/java/org/springframework/data/mapping/context/AbstractMappingContextUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/context/AbstractMappingContextUnitTests.java @@ -111,7 +111,7 @@ public class AbstractMappingContextUnitTests { public void returnsNullPersistentEntityForSimpleTypes() { SampleMappingContext context = new SampleMappingContext(); - assertThat(context.getPersistentEntity(String.class)).isNull(); + assertThat(context.getPersistentEntity(String.class)).isEmpty(); } @Test(expected = IllegalArgumentException.class) // DATACMNS-214 @@ -130,7 +130,8 @@ public class AbstractMappingContextUnitTests { SampleMappingContext mappingContext = new SampleMappingContext(); mappingContext.initialize(); - PersistentEntity entity = mappingContext.getPersistentEntity(Sample.class); + PersistentEntity entity = mappingContext + .getRequiredPersistentEntity(Sample.class); assertThat(entity.getPersistentProperty("metaClass")).isNotPresent(); } @@ -138,7 +139,8 @@ public class AbstractMappingContextUnitTests { public void usesMostConcreteProperty() { SampleMappingContext mappingContext = new SampleMappingContext(); - PersistentEntity entity = mappingContext.getPersistentEntity(Extension.class); + PersistentEntity entity = mappingContext + .getRequiredPersistentEntity(Extension.class); assertThat(entity.getPersistentProperty("foo")).hasValueSatisfying(it -> { assertThat(it.isIdProperty()).isTrue(); @@ -150,16 +152,14 @@ public class AbstractMappingContextUnitTests { public void returnsEntityForComponentType() { SampleMappingContext mappingContext = new SampleMappingContext(); - PersistentEntity entity = mappingContext.getPersistentEntity(Sample.class); + PersistentEntity entity = mappingContext + .getRequiredPersistentEntity(Sample.class); assertThat(entity.getPersistentProperty("persons")).hasValueSatisfying(it -> { - - PersistentEntity propertyEntity = mappingContext.getPersistentEntity(it); - - assertThat(propertyEntity).isNotNull(); - assertThat(propertyEntity.getType()).isEqualTo(Person.class); + assertThat(mappingContext.getPersistentEntity(it)).hasValueSatisfying(inner -> { + assertThat(inner.getType()).isEqualTo(Person.class); + }); }); - } @Test // DATACMNS-380 @@ -197,7 +197,7 @@ public class AbstractMappingContextUnitTests { public void shouldReturnNullForSimpleTypesIfInStrictIsEnabled() { context.setStrict(true); - assertThat(context.getPersistentEntity(Integer.class)).isNull(); + assertThat(context.getPersistentEntity(Integer.class)).isEmpty(); } @Test // DATACMNS-462 diff --git a/src/test/java/org/springframework/data/mapping/context/DefaultPersistenPropertyPathUnitTests.java b/src/test/java/org/springframework/data/mapping/context/DefaultPersistenPropertyPathUnitTests.java index 4c4b80692..c1c862539 100755 --- a/src/test/java/org/springframework/data/mapping/context/DefaultPersistenPropertyPathUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/context/DefaultPersistenPropertyPathUnitTests.java @@ -16,7 +16,7 @@ package org.springframework.data.mapping.context; import static org.assertj.core.api.Assertions.*; -import static org.mockito.Matchers.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.Arrays; diff --git a/src/test/java/org/springframework/data/mapping/context/MappingContextIsNewStrategyFactoryUnitTests.java b/src/test/java/org/springframework/data/mapping/context/MappingContextIsNewStrategyFactoryUnitTests.java index ca787ef6f..6fe1408c3 100755 --- a/src/test/java/org/springframework/data/mapping/context/MappingContextIsNewStrategyFactoryUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/context/MappingContextIsNewStrategyFactoryUnitTests.java @@ -27,8 +27,6 @@ import org.junit.Test; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; import org.springframework.data.domain.Persistable; -import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory.PropertyIsNullIsNewStrategy; -import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory.PropertyIsNullOrZeroNumberIsNewStrategy; import org.springframework.data.support.IsNewStrategy; import org.springframework.data.support.IsNewStrategyFactory; @@ -55,7 +53,6 @@ public class MappingContextIsNewStrategyFactoryUnitTests { public void returnsPropertyIsNullOrZeroIsNewStrategyForVersionedEntity() { IsNewStrategy strategy = factory.getIsNewStrategy(VersionedEntity.class); - assertThat(strategy).isInstanceOf(PropertyIsNullOrZeroNumberIsNewStrategy.class); Optional entity = Optional.of(new VersionedEntity()); assertThat(strategy.isNew(entity)).isTrue(); @@ -74,7 +71,6 @@ public class MappingContextIsNewStrategyFactoryUnitTests { public void returnsPropertyIsNullOrZeroIsNewStrategyForPrimitiveVersionedEntity() { IsNewStrategy strategy = factory.getIsNewStrategy(VersionedEntity.class); - assertThat(strategy).isInstanceOf(PropertyIsNullOrZeroNumberIsNewStrategy.class); Optional entity = Optional.of(new VersionedEntity()); assertThat(strategy.isNew(entity)).isTrue(); @@ -90,7 +86,6 @@ public class MappingContextIsNewStrategyFactoryUnitTests { public void returnsPropertyIsNullIsNewStrategyForEntity() { IsNewStrategy strategy = factory.getIsNewStrategy(Entity.class); - assertThat(strategy).isInstanceOf(PropertyIsNullIsNewStrategy.class); Optional entity = Optional.of(new Entity()); assertThat(strategy.isNew(entity)).isTrue(); diff --git a/src/test/java/org/springframework/data/mapping/context/PersistentEntitiesUnitTests.java b/src/test/java/org/springframework/data/mapping/context/PersistentEntitiesUnitTests.java index 9bec1b148..00bf40ca0 100755 --- a/src/test/java/org/springframework/data/mapping/context/PersistentEntitiesUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/context/PersistentEntitiesUnitTests.java @@ -52,10 +52,10 @@ public class PersistentEntitiesUnitTests { new PersistentEntities(Arrays.asList(first, second)).getPersistentEntity(Sample.class); verify(first, times(1)).hasPersistentEntityFor(Sample.class); - verify(first, times(0)).getPersistentEntity(Sample.class); + verify(first, times(0)).getRequiredPersistentEntity(Sample.class); verify(second, times(1)).hasPersistentEntityFor(Sample.class); - verify(second, times(1)).getPersistentEntity(Sample.class); + verify(second, times(1)).getRequiredPersistentEntity(Sample.class); } @Test // DATACMNS-458 @@ -67,10 +67,14 @@ public class PersistentEntitiesUnitTests { PersistentEntities entities = new PersistentEntities(Arrays.asList(context)); - assertThat(entities.getPersistentEntity(Sample.class)).isNotNull(); - assertThat(entities.getPersistentEntity(Object.class)).isNull(); + assertThat(entities.getPersistentEntity(Sample.class)).isPresent(); + assertThat(entities.getPersistentEntity(Object.class)).isNotPresent(); assertThat(entities.getManagedTypes()).contains(ClassTypeInformation.from(Sample.class)); - assertThat(entities).contains(entities.getPersistentEntity(Sample.class)); + + assertThat(entities.getPersistentEntity(Sample.class)).hasValueSatisfying(it -> { + assertThat(entities).contains(it); + }); + } static class Sample { diff --git a/src/test/java/org/springframework/data/mapping/context/SampleMappingContext.java b/src/test/java/org/springframework/data/mapping/context/SampleMappingContext.java index f7071dfe8..e3870dfaa 100644 --- a/src/test/java/org/springframework/data/mapping/context/SampleMappingContext.java +++ b/src/test/java/org/springframework/data/mapping/context/SampleMappingContext.java @@ -1,10 +1,7 @@ package org.springframework.data.mapping.context; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; -import java.util.Optional; - import org.springframework.data.mapping.model.BasicPersistentEntity; +import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.TypeInformation; @@ -19,9 +16,9 @@ public class SampleMappingContext } @Override - protected SamplePersistentProperty createPersistentProperty(Optional field, PropertyDescriptor descriptor, + protected SamplePersistentProperty createPersistentProperty(Property property, BasicPersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { - return new SamplePersistentProperty(field, descriptor, owner, simpleTypeHolder); + return new SamplePersistentProperty(property, owner, simpleTypeHolder); } } diff --git a/src/test/java/org/springframework/data/mapping/context/SamplePersistentProperty.java b/src/test/java/org/springframework/data/mapping/context/SamplePersistentProperty.java index e9aebeb58..0651ef030 100644 --- a/src/test/java/org/springframework/data/mapping/context/SamplePersistentProperty.java +++ b/src/test/java/org/springframework/data/mapping/context/SamplePersistentProperty.java @@ -15,24 +15,21 @@ */ package org.springframework.data.mapping.context; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; -import java.util.Optional; - import org.springframework.data.mapping.Association; import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty; import org.springframework.data.mapping.model.BasicPersistentEntity; +import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; public class SamplePersistentProperty extends AnnotationBasedPersistentProperty { - public SamplePersistentProperty(Optional field, PropertyDescriptor propertyDescriptor, - BasicPersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { - super(field, propertyDescriptor, owner, simpleTypeHolder); + public SamplePersistentProperty(Property property, BasicPersistentEntity owner, + SimpleTypeHolder simpleTypeHolder) { + super(property, owner, simpleTypeHolder); } @Override protected Association createAssociation() { - return new Association(this, null); + return new Association<>(this, null); } } diff --git a/src/test/java/org/springframework/data/mapping/model/AbstractPersistentPropertyUnitTests.java b/src/test/java/org/springframework/data/mapping/model/AbstractPersistentPropertyUnitTests.java index 6ba389f50..5efd9ce0c 100755 --- a/src/test/java/org/springframework/data/mapping/model/AbstractPersistentPropertyUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/model/AbstractPersistentPropertyUnitTests.java @@ -54,53 +54,35 @@ public class AbstractPersistentPropertyUnitTests { public void setUp() { typeInfo = ClassTypeInformation.from(TestClassComplex.class); - entity = new BasicPersistentEntity(typeInfo); + entity = new BasicPersistentEntity<>(typeInfo); typeHolder = new SimpleTypeHolder(); } @Test // DATACMNS-68 public void discoversComponentTypeCorrectly() throws Exception { - - Field field = ReflectionUtils.findField(TestClassComplex.class, "testClassSet"); - - SamplePersistentProperty property = new SamplePersistentProperty(Optional.of(field), null, entity, typeHolder); - property.getComponentType(); + assertThat(getProperty(TestClassComplex.class, "testClassSet").getComponentType()).isEqualTo(Object.class); } @Test // DATACMNS-101 public void returnsNestedEntityTypeCorrectly() { - - Field field = ReflectionUtils.findField(TestClassComplex.class, "testClassSet"); - - SamplePersistentProperty property = new SamplePersistentProperty(Optional.of(field), null, entity, typeHolder); - assertThat(property.getPersistentEntityType().iterator().hasNext()).isFalse(); + assertThat(getProperty(TestClassComplex.class, "testClassSet").getPersistentEntityType()).isEmpty(); } @Test // DATACMNS-132 public void isEntityWorksForUntypedMaps() throws Exception { - - Field field = ReflectionUtils.findField(TestClassComplex.class, "map"); - SamplePersistentProperty property = new SamplePersistentProperty(Optional.of(field), null, entity, typeHolder); - assertThat(property.isEntity()).isFalse(); + assertThat(getProperty(TestClassComplex.class, "map").isEntity()).isFalse(); } @Test // DATACMNS-132 public void isEntityWorksForUntypedCollection() throws Exception { - - Field field = ReflectionUtils.findField(TestClassComplex.class, "collection"); - SamplePersistentProperty property = new SamplePersistentProperty(Optional.of(field), null, entity, typeHolder); - assertThat(property.isEntity()).isFalse(); + assertThat(getProperty(TestClassComplex.class, "collection").isEntity()).isFalse(); } @Test // DATACMNS-121 public void considersPropertiesEqualIfFieldEquals() { - Field first = ReflectionUtils.findField(FirstConcrete.class, "genericField"); - Field second = ReflectionUtils.findField(SecondConcrete.class, "genericField"); - - SamplePersistentProperty firstProperty = new SamplePersistentProperty(Optional.of(first), null, entity, typeHolder); - SamplePersistentProperty secondProperty = new SamplePersistentProperty(Optional.of(second), null, entity, - typeHolder); + SamplePersistentProperty firstProperty = getProperty(FirstConcrete.class, "genericField"); + SamplePersistentProperty secondProperty = getProperty(SecondConcrete.class, "genericField"); assertThat(firstProperty).isEqualTo(secondProperty); assertThat(firstProperty.hashCode()).isEqualTo(secondProperty.hashCode()); @@ -108,67 +90,54 @@ public class AbstractPersistentPropertyUnitTests { @Test // DATACMNS-180 public void doesNotConsiderJavaTransientFieldsTransient() { - - Field transientField = ReflectionUtils.findField(TestClassComplex.class, "transientField"); - - PersistentProperty property = new SamplePersistentProperty(Optional.of(transientField), null, entity, - typeHolder); - assertThat(property.isTransient()).isFalse(); + assertThat(getProperty(TestClassComplex.class, "transientField").isTransient()).isFalse(); } @Test // DATACMNS-206 public void findsSimpleGettersAndASetters() { - Field field = ReflectionUtils.findField(AccessorTestClass.class, "id"); - PersistentProperty property = new SamplePersistentProperty(Optional.of(field), - getPropertyDescriptor(AccessorTestClass.class, "id"), entity, typeHolder); + SamplePersistentProperty property = getProperty(AccessorTestClass.class, "id"); - assertThat(property.getGetter()).isNotNull(); - assertThat(property.getSetter()).isNotNull(); + assertThat(property.getGetter()).isPresent(); + assertThat(property.getSetter()).isPresent(); } @Test // DATACMNS-206 public void doesNotUseInvalidGettersAndASetters() { - Field field = ReflectionUtils.findField(AccessorTestClass.class, "anotherId"); - PersistentProperty property = new SamplePersistentProperty(Optional.of(field), - getPropertyDescriptor(AccessorTestClass.class, "anotherId"), entity, typeHolder); + SamplePersistentProperty property = getProperty(AccessorTestClass.class, "anotherId"); - assertThat(property.getGetter()).isNull(); - assertThat(property.getSetter()).isNull(); + assertThat(property.getGetter()).isNotPresent(); + assertThat(property.getSetter()).isNotPresent(); } @Test // DATACMNS-206 public void usesCustomGetter() { - Field field = ReflectionUtils.findField(AccessorTestClass.class, "yetAnotherId"); - PersistentProperty property = new SamplePersistentProperty(Optional.of(field), - getPropertyDescriptor(AccessorTestClass.class, "yetAnotherId"), entity, typeHolder); + SamplePersistentProperty property = getProperty(AccessorTestClass.class, "yetAnotherId"); - assertThat(property.getGetter()).isNotNull(); - assertThat(property.getSetter()).isNull(); + assertThat(property.getGetter()).isPresent(); + assertThat(property.getSetter()).isNotPresent(); } @Test // DATACMNS-206 public void usesCustomSetter() { - Field field = ReflectionUtils.findField(AccessorTestClass.class, "yetYetAnotherId"); - PersistentProperty property = new SamplePersistentProperty(Optional.of(field), - getPropertyDescriptor(AccessorTestClass.class, "yetYetAnotherId"), entity, typeHolder); + SamplePersistentProperty property = getProperty(AccessorTestClass.class, "yetYetAnotherId"); - assertThat(property.getGetter()).isNull(); - assertThat(property.getSetter()).isNotNull(); + assertThat(property.getGetter()).isNotPresent(); + assertThat(property.getSetter()).isPresent(); } @Test // DATACMNS-206 - public void returnsNullGetterAndSetterIfNoPropertyDescriptorGiven() { + public void doesNotDiscoverGetterAndSetterIfNoPropertyDescriptorGiven() { Field field = ReflectionUtils.findField(AccessorTestClass.class, "id"); - PersistentProperty property = new SamplePersistentProperty(Optional.of(field), null, - entity, typeHolder); + PersistentProperty property = new SamplePersistentProperty(Property.of(field), + getEntity(AccessorTestClass.class), typeHolder); - assertThat(property.getGetter()).isNull(); - assertThat(property.getSetter()).isNull(); + assertThat(property.getGetter()).isNotPresent(); + assertThat(property.getSetter()).isNotPresent(); } @Test // DATACMNS-337 @@ -223,25 +192,31 @@ public class AbstractPersistentPropertyUnitTests { assertThat(property.isEntity()).isFalse(); } + private BasicPersistentEntity getEntity(Class type) { + return new BasicPersistentEntity<>(ClassTypeInformation.from(type)); + } + private SamplePersistentProperty getProperty(Class type, String name) { - BasicPersistentEntity entity = new BasicPersistentEntity( - ClassTypeInformation.from(type)); + Optional field = Optional.ofNullable(ReflectionUtils.findField(type, name)); - Field field = ReflectionUtils.findField(type, name); - return new SamplePersistentProperty(Optional.of(field), null, entity, typeHolder); + Property property = field.map(it -> Property.of(it, getPropertyDescriptor(type, name))) + .orElseGet(() -> Property.of(getPropertyDescriptor(type, name).orElseThrow( + () -> new IllegalArgumentException(String.format("Couldn't find property %s on %s!", name, type))))); + + return new SamplePersistentProperty(property, getEntity(type), typeHolder); } - private static PropertyDescriptor getPropertyDescriptor(Class type, String propertyName) { + private static Optional getPropertyDescriptor(Class type, String propertyName) { try { return Arrays.stream(Introspector.getBeanInfo(type).getPropertyDescriptors())// .filter(it -> it.getName().equals(propertyName))// - .findFirst().orElse(null); + .findFirst(); - } catch (IntrospectionException e) { - return null; + } catch (IntrospectionException o_O) { + throw new RuntimeException(o_O); } } @@ -311,9 +286,9 @@ public class AbstractPersistentPropertyUnitTests { class SamplePersistentProperty extends AbstractPersistentProperty { - public SamplePersistentProperty(Optional field, PropertyDescriptor propertyDescriptor, - PersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { - super(field, propertyDescriptor, owner, simpleTypeHolder); + public SamplePersistentProperty(Property property, PersistentEntity owner, + SimpleTypeHolder simpleTypeHolder) { + super(property, owner, simpleTypeHolder); } public boolean isIdProperty() { diff --git a/src/test/java/org/springframework/data/mapping/model/AnnotationBasedPersistentPropertyUnitTests.java b/src/test/java/org/springframework/data/mapping/model/AnnotationBasedPersistentPropertyUnitTests.java index 848fca1df..98354ca06 100755 --- a/src/test/java/org/springframework/data/mapping/model/AnnotationBasedPersistentPropertyUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/model/AnnotationBasedPersistentPropertyUnitTests.java @@ -55,7 +55,7 @@ public class AnnotationBasedPersistentPropertyUnitTests

type, String name) { - return context.getPersistentEntity(type).getPersistentProperty(name).orElse(null); + return context.getRequiredPersistentEntity(type).getPersistentProperty(name).orElse(null); } static class Sample { diff --git a/src/test/java/org/springframework/data/mapping/model/BasicPersistentEntityUnitTests.java b/src/test/java/org/springframework/data/mapping/model/BasicPersistentEntityUnitTests.java index 6946fa245..ab5b3262e 100755 --- a/src/test/java/org/springframework/data/mapping/model/BasicPersistentEntityUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/model/BasicPersistentEntityUnitTests.java @@ -16,9 +16,6 @@ package org.springframework.data.mapping.model; import static org.assertj.core.api.Assertions.*; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.CoreMatchers.not; -import static org.junit.Assume.*; import static org.mockito.Mockito.*; import java.lang.annotation.Retention; @@ -28,8 +25,6 @@ import java.util.Iterator; import java.util.List; import java.util.Optional; -import org.hamcrest.CoreMatchers; -import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -42,6 +37,7 @@ import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedBy; import org.springframework.data.annotation.TypeAlias; +import org.springframework.data.mapping.Alias; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentEntitySpec; @@ -86,25 +82,22 @@ public class BasicPersistentEntityUnitTests> { public void returnsNullForTypeAliasIfNoneConfigured() { PersistentEntity entity = createEntity(Entity.class); - assertThat(entity.getTypeAlias()).isNotPresent(); + assertThat(entity.getTypeAlias()).isEqualTo(Alias.NONE); } @Test public void returnsTypeAliasIfAnnotated() { PersistentEntity entity = createEntity(AliasedEntity.class); - assertThat(entity.getTypeAlias()).isEqualTo("foo"); + assertThat(entity.getTypeAlias()).isEqualTo(Alias.of("foo")); } @Test // DATACMNS-50 @SuppressWarnings("unchecked") public void considersComparatorForPropertyOrder() { - BasicPersistentEntity entity = createEntity(Person.class, new Comparator() { - public int compare(T o1, T o2) { - return o1.getName().compareTo(o2.getName()); - } - }); + BasicPersistentEntity entity = createEntity(Person.class, + Comparator.comparing(PersistentProperty::getName)); T lastName = (T) Mockito.mock(PersistentProperty.class); when(lastName.getName()).thenReturn("lastName"); @@ -124,20 +117,21 @@ public class BasicPersistentEntityUnitTests> { assertThat(properties).hasSize(3); Iterator iterator = properties.iterator(); - assertThat(iterator.next()).isEqualTo(entity.getPersistentProperty("firstName")); - assertThat(iterator.next()).isEqualTo(entity.getPersistentProperty("lastName")); - assertThat(iterator.next()).isEqualTo(entity.getPersistentProperty("ssn")); + + assertThat(entity.getPersistentProperty("firstName")).hasValue(iterator.next()); + assertThat(entity.getPersistentProperty("lastName")).hasValue(iterator.next()); + assertThat(entity.getPersistentProperty("ssn")).hasValue(iterator.next()); } @Test // DATACMNS-186 public void addingAndIdPropertySetsIdPropertyInternally() { MutablePersistentEntity entity = createEntity(Person.class); - assertThat(entity.getIdProperty()).isNull(); + assertThat(entity.getIdProperty()).isNotPresent(); when(property.isIdProperty()).thenReturn(true); entity.addPersistentProperty(property); - assertThat(entity.getIdProperty()).isEqualTo(property); + assertThat(entity.getIdProperty()).hasValue(property); } @Test // DATACMNS-186 @@ -157,7 +151,7 @@ public class BasicPersistentEntityUnitTests> { public void detectsPropertyWithAnnotation() { SampleMappingContext context = new SampleMappingContext(); - PersistentEntity entity = context.getPersistentEntity(Entity.class); + PersistentEntity entity = context.getRequiredPersistentEntity(Entity.class); Optional property = entity.getPersistentProperty(LastModifiedBy.class); @@ -192,15 +186,13 @@ public class BasicPersistentEntityUnitTests> { @Test // DATACMNS-809 public void returnsGeneratedPropertyAccessorForPropertyAccessor() { - assumeThat(System.getProperty("java.version"), not(CoreMatchers.startsWith("1.6"))); - SampleMappingContext context = new SampleMappingContext(); - PersistentEntity entity = context.getPersistentEntity(Entity.class); + PersistentEntity entity = context.getRequiredPersistentEntity(Entity.class); Entity value = new Entity(); PersistentPropertyAccessor accessor = entity.getPropertyAccessor(value); - assertThat(accessor).isNotEqualTo(instanceOf(BeanWrapper.class)); + assertThat(accessor).isNotInstanceOf(BeanWrapper.class); assertThat(accessor.getClass().getName()).contains("_Accessor_"); assertThat(accessor.getBean()).isEqualTo(value); } @@ -209,7 +201,7 @@ public class BasicPersistentEntityUnitTests> { public void rejectsNullBeanForPropertyAccessor() { SampleMappingContext context = new SampleMappingContext(); - PersistentEntity entity = context.getPersistentEntity(Entity.class); + PersistentEntity entity = context.getRequiredPersistentEntity(Entity.class); entity.getPropertyAccessor(null); } @@ -218,7 +210,7 @@ public class BasicPersistentEntityUnitTests> { public void rejectsNonMatchingBeanForPropertyAccessor() { SampleMappingContext context = new SampleMappingContext(); - PersistentEntity entity = context.getPersistentEntity(Entity.class); + PersistentEntity entity = context.getRequiredPersistentEntity(Entity.class); entity.getPropertyAccessor("foo"); } @@ -227,7 +219,7 @@ public class BasicPersistentEntityUnitTests> { public void supportsSubtypeInstancesOnPropertyAccessorLookup() { SampleMappingContext context = new SampleMappingContext(); - PersistentEntity entity = context.getPersistentEntity(Entity.class); + PersistentEntity entity = context.getRequiredPersistentEntity(Entity.class); assertThat(entity.getPropertyAccessor(new Subtype())).isNotNull(); } @@ -237,7 +229,7 @@ public class BasicPersistentEntityUnitTests> { PersistentEntity entity = createEntity( AliasEntityUsingComposedAnnotation.class); - assertThat(entity.getTypeAlias()).isEqualTo("bar"); + assertThat(entity.getTypeAlias()).isEqualTo(Alias.of("bar")); } @Test // DATACMNS-866 diff --git a/src/test/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactoryDatatypeTests.java b/src/test/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactoryDatatypeTests.java index 1590de9e3..b11592bb9 100755 --- a/src/test/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactoryDatatypeTests.java +++ b/src/test/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactoryDatatypeTests.java @@ -65,7 +65,8 @@ public class ClassGeneratingPropertyAccessorFactoryDatatypeTests { public static List parameters() throws Exception { List parameters = new ArrayList<>(); - List> types = Arrays.asList(FieldAccess.class, PropertyAccess.class, PrivateFinalFieldAccess.class, PrivateFinalPropertyAccess.class); + List> types = Arrays.asList(FieldAccess.class, PropertyAccess.class, PrivateFinalFieldAccess.class, + PrivateFinalPropertyAccess.class); parameters.addAll(parameters(types, "primitiveInteger", Integer.valueOf(1))); parameters.addAll(parameters(types, "primitiveIntegerArray", new int[] { 1, 2, 3 })); @@ -113,8 +114,8 @@ public class ClassGeneratingPropertyAccessorFactoryDatatypeTests { Constructor[] constructors = type.getDeclaredConstructors(); constructors[0].setAccessible(true); - parameters - .add(new Object[] { constructors[0].newInstance(), propertyName, value, type.getSimpleName() + "/" + propertyName }); + parameters.add(new Object[] { constructors[0].newInstance(), propertyName, value, + type.getSimpleName() + "/" + propertyName }); } return parameters; @@ -136,20 +137,20 @@ public class ClassGeneratingPropertyAccessorFactoryDatatypeTests { public void shouldUseClassPropertyAccessorFactory() throws Exception { BasicPersistentEntity persistentEntity = mappingContext - .getPersistentEntity(bean.getClass()); + .getRequiredPersistentEntity(bean.getClass()); assertThat(ReflectionTestUtils.getField(persistentEntity, "propertyAccessorFactory")) .isInstanceOf(ClassGeneratingPropertyAccessorFactory.class); } private PersistentPropertyAccessor getPersistentPropertyAccessor(Object bean) { - return factory.getPropertyAccessor(mappingContext.getPersistentEntity(bean.getClass()), bean); + return factory.getPropertyAccessor(mappingContext.getRequiredPersistentEntity(bean.getClass()), bean); } private Optional> getProperty(Object bean, String name) { BasicPersistentEntity persistentEntity = mappingContext - .getPersistentEntity(bean.getClass()); + .getRequiredPersistentEntity(bean.getClass()); return persistentEntity.getPersistentProperty(name); } diff --git a/src/test/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactoryEntityTypeTests.java b/src/test/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactoryEntityTypeTests.java index c182dfb52..d45f4ef1d 100755 --- a/src/test/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactoryEntityTypeTests.java +++ b/src/test/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactoryEntityTypeTests.java @@ -42,7 +42,7 @@ public class ClassGeneratingPropertyAccessorFactoryEntityTypeTests { Algorithm quickSort = new QuickSort(); - assertThat(getEntityInformation(Algorithm.class).getId(quickSort)).isEqualTo(quickSort.getName()); + assertThat(getEntityInformation(Algorithm.class).getId(quickSort)).hasValue(quickSort.getName()); } @Test // DATACMNS-853 @@ -50,12 +50,12 @@ public class ClassGeneratingPropertyAccessorFactoryEntityTypeTests { Person jonDoe = new Person("JonDoe"); - assertThat(getEntityInformation(Person.class).getId(jonDoe)).isEqualTo(jonDoe.name); + assertThat(getEntityInformation(Person.class).getId(jonDoe)).hasValue(jonDoe.name); } - private EntityInformation getEntityInformation(Class type) { + private EntityInformation getEntityInformation(Class type) { - PersistentEntity entity = mappingContext.getPersistentEntity(type); + PersistentEntity entity = mappingContext.getRequiredPersistentEntity(type); return new PersistentEntityInformation(entity); } diff --git a/src/test/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactoryTests.java b/src/test/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactoryTests.java index 6b16bbe91..13d38d8d1 100755 --- a/src/test/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactoryTests.java +++ b/src/test/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactoryTests.java @@ -16,7 +16,8 @@ package org.springframework.data.mapping.model; -import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import java.lang.reflect.Constructor; import java.util.ArrayList; @@ -28,6 +29,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; + import org.springframework.data.annotation.AccessType; import org.springframework.data.annotation.AccessType.Type; import org.springframework.data.mapping.PersistentProperty; @@ -68,7 +70,8 @@ public class ClassGeneratingPropertyAccessorFactoryTests { "privateProperty", "packageDefaultProperty", "protectedProperty", "publicProperty", "syntheticProperty"); parameters.addAll(parameters(new InnerPrivateType(), propertyNames, Object.class)); - parameters.addAll(parameters(new InnerTypeWithPrivateAncestor(), propertyNames, InnerTypeWithPrivateAncestor.class)); + parameters + .addAll(parameters(new InnerTypeWithPrivateAncestor(), propertyNames, InnerTypeWithPrivateAncestor.class)); parameters.addAll(parameters(new InnerPackageDefaultType(), propertyNames, InnerPackageDefaultType.class)); parameters.addAll(parameters(new InnerProtectedType(), propertyNames, InnerProtectedType.class)); parameters.addAll(parameters(new InnerPublicType(), propertyNames, InnerPublicType.class)); @@ -119,10 +122,10 @@ public class ClassGeneratingPropertyAccessorFactoryTests { @Test(expected = IllegalArgumentException.class) // DATACMNS-809 public void shouldFailOnNullBean() { - factory.getPropertyAccessor(mappingContext.getPersistentEntity(bean.getClass()), null); + factory.getPropertyAccessor(mappingContext.getRequiredPersistentEntity(bean.getClass()), null); } - @Test(expected = UnsupportedOperationException.class) // DATACMNS-809 + @Test // DATACMNS-809 public void getPropertyShouldFailOnUnhandledProperty() { assertThat(getProperty(new Dummy(), "dummy")).hasValueSatisfying(property -> { @@ -132,33 +135,34 @@ public class ClassGeneratingPropertyAccessorFactoryTests { }); } - @Test(expected = UnsupportedOperationException.class) // DATACMNS-809 + @Test // DATACMNS-809 public void setPropertyShouldFailOnUnhandledProperty() { assertThat(getProperty(new Dummy(), "dummy")).hasValueSatisfying(property -> { - getPersistentPropertyAccessor(bean).setProperty(property, Optional.empty()); - }); + assertThatExceptionOfType(UnsupportedOperationException.class)// + .isThrownBy(() -> getPersistentPropertyAccessor(bean).setProperty(property, Optional.empty())); + }); } @Test // DATACMNS-809 public void shouldUseClassPropertyAccessorFactory() throws Exception { BasicPersistentEntity persistentEntity = mappingContext - .getPersistentEntity(bean.getClass()); + .getRequiredPersistentEntity(bean.getClass()); assertThat(ReflectionTestUtils.getField(persistentEntity, "propertyAccessorFactory")) .isInstanceOf(ClassGeneratingPropertyAccessorFactory.class); } private PersistentPropertyAccessor getPersistentPropertyAccessor(Object bean) { - return factory.getPropertyAccessor(mappingContext.getPersistentEntity(bean.getClass()), bean); + return factory.getPropertyAccessor(mappingContext.getRequiredPersistentEntity(bean.getClass()), bean); } private Optional> getProperty(Object bean, String name) { BasicPersistentEntity persistentEntity = mappingContext - .getPersistentEntity(bean.getClass()); + .getRequiredPersistentEntity(bean.getClass()); return persistentEntity.getPersistentProperty(name); } diff --git a/src/test/java/org/springframework/data/mapping/model/ConvertingPropertyAccessorUnitTests.java b/src/test/java/org/springframework/data/mapping/model/ConvertingPropertyAccessorUnitTests.java index 5b10e5946..4c989f42a 100755 --- a/src/test/java/org/springframework/data/mapping/model/ConvertingPropertyAccessorUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/model/ConvertingPropertyAccessorUnitTests.java @@ -43,7 +43,7 @@ public class ConvertingPropertyAccessorUnitTests { @Test(expected = IllegalArgumentException.class) // DATACMNS-596 public void rejectsNullConversionService() { - new ConvertingPropertyAccessor(new BeanWrapper(new Object()), null); + new ConvertingPropertyAccessor(new BeanWrapper<>(new Object()), null); } @Test // DATACMNS-596 @@ -111,14 +111,15 @@ public class ConvertingPropertyAccessorUnitTests { private static ConvertingPropertyAccessor getAccessor(Object entity, ConversionService conversionService) { - PersistentPropertyAccessor wrapper = new BeanWrapper(entity); + PersistentPropertyAccessor wrapper = new BeanWrapper<>(entity); return new ConvertingPropertyAccessor(wrapper, conversionService); } private static Optional getIdProperty() { SampleMappingContext mappingContext = new SampleMappingContext(); - BasicPersistentEntity entity = mappingContext.getPersistentEntity(Entity.class); + BasicPersistentEntity entity = mappingContext + .getRequiredPersistentEntity(Entity.class); return entity.getPersistentProperty("id"); } diff --git a/src/test/java/org/springframework/data/mapping/model/IdPropertyIdentifierAccessorUnitTests.java b/src/test/java/org/springframework/data/mapping/model/IdPropertyIdentifierAccessorUnitTests.java index b10b8b183..1e4065952 100755 --- a/src/test/java/org/springframework/data/mapping/model/IdPropertyIdentifierAccessorUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/model/IdPropertyIdentifierAccessorUnitTests.java @@ -32,13 +32,13 @@ public class IdPropertyIdentifierAccessorUnitTests { @Test(expected = IllegalArgumentException.class) // DATACMNS-599 public void rejectsEntityWithoutIdentifierProperty() { - new IdPropertyIdentifierAccessor(mappingContext.getPersistentEntity(Sample.class), new Sample()); + new IdPropertyIdentifierAccessor(mappingContext.getRequiredPersistentEntity(Sample.class), new Sample()); } @Test(expected = IllegalArgumentException.class) // DATACMNS-599 public void rejectsNullBean() { - new IdPropertyIdentifierAccessor(mappingContext.getPersistentEntity(SampleWithId.class), null); + new IdPropertyIdentifierAccessor(mappingContext.getRequiredPersistentEntity(SampleWithId.class), null); } @Test // DATACMNS-599 @@ -48,9 +48,9 @@ public class IdPropertyIdentifierAccessorUnitTests { sample.id = 1L; IdentifierAccessor accessor = new IdPropertyIdentifierAccessor( - mappingContext.getPersistentEntity(SampleWithId.class), sample); + mappingContext.getRequiredPersistentEntity(SampleWithId.class), sample); - assertThat(accessor.getIdentifier()).isEqualTo(sample.id); + assertThat(accessor.getIdentifier()).hasValue(sample.id); } static class Sample {} diff --git a/src/test/java/org/springframework/data/mapping/model/PersistentEntityParameterValueProviderUnitTests.java b/src/test/java/org/springframework/data/mapping/model/PersistentEntityParameterValueProviderUnitTests.java index 923f40f0a..503a888ad 100755 --- a/src/test/java/org/springframework/data/mapping/model/PersistentEntityParameterValueProviderUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/model/PersistentEntityParameterValueProviderUnitTests.java @@ -16,7 +16,7 @@ package org.springframework.data.mapping.model; import static org.assertj.core.api.Assertions.*; -import static org.mockito.Matchers.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.Iterator; diff --git a/src/test/java/org/springframework/data/mapping/model/SpelExpressionParameterProviderUnitTests.java b/src/test/java/org/springframework/data/mapping/model/SpelExpressionParameterProviderUnitTests.java index 8ccefc53a..a660e5113 100755 --- a/src/test/java/org/springframework/data/mapping/model/SpelExpressionParameterProviderUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/model/SpelExpressionParameterProviderUnitTests.java @@ -16,6 +16,7 @@ package org.springframework.data.mapping.model; import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.Optional; @@ -24,7 +25,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.core.convert.ConversionService; import org.springframework.data.mapping.PreferredConstructor.Parameter; @@ -47,11 +47,9 @@ public class SpelExpressionParameterProviderUnitTests { @Before @SuppressWarnings("unchecked") public void setUp() { - provider = new SpELExpressionParameterValueProvider(evaluator, conversionService, - delegate); + provider = new SpELExpressionParameterValueProvider<>(evaluator, conversionService, delegate); parameter = mock(Parameter.class); - when(parameter.hasSpelExpression()).thenReturn(true); when(parameter.getSpelExpression()).thenReturn(Optional.empty()); when(parameter.getRawType()).thenReturn(Object.class); } @@ -61,7 +59,6 @@ public class SpelExpressionParameterProviderUnitTests { public void delegatesIfParameterDoesNotHaveASpELExpression() { Parameter parameter = mock(Parameter.class); - when(parameter.hasSpelExpression()).thenReturn(false); provider.getParameterValue(parameter); verify(delegate, times(1)).getParameterValue(parameter); @@ -81,9 +78,11 @@ public class SpelExpressionParameterProviderUnitTests { @Test public void handsSpELValueToConversionService() { - when(evaluator.evaluate(Mockito.any(String.class))).thenReturn("value"); + doReturn(Optional.of("source")).when(parameter).getSpelExpression(); + doReturn("value").when(evaluator).evaluate(any()); provider.getParameterValue(parameter); + verify(delegate, times(0)).getParameterValue(parameter); verify(conversionService, times(1)).convert("value", Object.class); } @@ -91,9 +90,11 @@ public class SpelExpressionParameterProviderUnitTests { @Test public void doesNotConvertNullValue() { - when(evaluator.evaluate(Mockito.any(String.class))).thenReturn(null); + doReturn(Optional.of("source")).when(parameter).getSpelExpression(); + doReturn(null).when(evaluator).evaluate(any()); provider.getParameterValue(parameter); + verify(delegate, times(0)).getParameterValue(parameter); verify(conversionService, times(0)).convert("value", Object.class); } @@ -103,6 +104,7 @@ public class SpelExpressionParameterProviderUnitTests { provider = new SpELExpressionParameterValueProvider(evaluator, conversionService, delegate) { + @Override @SuppressWarnings("unchecked") protected T potentiallyConvertSpelValue(Object object, Parameter parameter) { @@ -110,10 +112,11 @@ public class SpelExpressionParameterProviderUnitTests { } }; - when(evaluator.evaluate(Mockito.anyString())).thenReturn("value"); + doReturn(Optional.of("source")).when(parameter).getSpelExpression(); + doReturn("value").when(evaluator).evaluate(any()); + + assertThat(provider.getParameterValue(parameter)).hasValue("FOO"); - Object result = provider.getParameterValue(parameter); - assertThat(result).isEqualTo("FOO"); verify(delegate, times(0)).getParameterValue(parameter); } } diff --git a/src/test/java/org/springframework/data/projection/ProjectingMethodInterceptorUnitTests.java b/src/test/java/org/springframework/data/projection/ProjectingMethodInterceptorUnitTests.java index 40d8fd239..4ab3a0c52 100755 --- a/src/test/java/org/springframework/data/projection/ProjectingMethodInterceptorUnitTests.java +++ b/src/test/java/org/springframework/data/projection/ProjectingMethodInterceptorUnitTests.java @@ -16,7 +16,7 @@ package org.springframework.data.projection; import static org.assertj.core.api.Assertions.*; -import static org.mockito.Matchers.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.Collection; diff --git a/src/test/java/org/springframework/data/projection/SpelEvaluatingMethodInterceptorUnitTests.java b/src/test/java/org/springframework/data/projection/SpelEvaluatingMethodInterceptorUnitTests.java index 1afe2e250..34f82f26b 100755 --- a/src/test/java/org/springframework/data/projection/SpelEvaluatingMethodInterceptorUnitTests.java +++ b/src/test/java/org/springframework/data/projection/SpelEvaluatingMethodInterceptorUnitTests.java @@ -86,12 +86,8 @@ public class SpelEvaluatingMethodInterceptorUnitTests { @Test(expected = IllegalStateException.class) // DATACMNS-630 public void rejectsEmptySpelExpression() throws Throwable { - when(invocation.getMethod()).thenReturn(InvalidProjection.class.getMethod("getAddress")); - - SpelEvaluatingMethodInterceptor interceptor = new SpelEvaluatingMethodInterceptor(delegate, new Target(), - new DefaultListableBeanFactory(), parser, InvalidProjection.class); - - interceptor.invoke(invocation); + new SpelEvaluatingMethodInterceptor(delegate, new Target(), new DefaultListableBeanFactory(), parser, + InvalidProjection.class); } @Test // DATACMNS-630 diff --git a/src/test/java/org/springframework/data/querydsl/QPageRequestUnitTests.java b/src/test/java/org/springframework/data/querydsl/QPageRequestUnitTests.java index 469729a5c..5281bada0 100755 --- a/src/test/java/org/springframework/data/querydsl/QPageRequestUnitTests.java +++ b/src/test/java/org/springframework/data/querydsl/QPageRequestUnitTests.java @@ -40,15 +40,15 @@ public class QPageRequestUnitTests extends AbstractPageRequestUnitTests { QUser user = QUser.user; QPageRequest pageRequest = new QPageRequest(0, 10, user.firstname.asc()); - assertThat(pageRequest.getSort()).isEqualTo(new QSort(user.firstname.asc())); + assertThat(pageRequest.getSort()).isEqualTo(QSort.by(user.firstname.asc())); } @Test public void constructsQPageRequestWithQSort() { QUser user = QUser.user; - QPageRequest pageRequest = new QPageRequest(0, 10, new QSort(user.firstname.asc())); + QPageRequest pageRequest = new QPageRequest(0, 10, QSort.by(user.firstname.asc())); - assertThat(pageRequest.getSort()).isEqualTo(new QSort(user.firstname.asc())); + assertThat(pageRequest.getSort()).isEqualTo(QSort.by(user.firstname.asc())); } } diff --git a/src/test/java/org/springframework/data/querydsl/QSortUnitTests.java b/src/test/java/org/springframework/data/querydsl/QSortUnitTests.java index 249d77af7..801bc4c9e 100755 --- a/src/test/java/org/springframework/data/querydsl/QSortUnitTests.java +++ b/src/test/java/org/springframework/data/querydsl/QSortUnitTests.java @@ -41,11 +41,6 @@ import com.querydsl.core.types.dsl.StringPath; */ public class QSortUnitTests { - @Test(expected = IllegalArgumentException.class) // DATACMNS-402 - public void shouldThrowIfNoOrderSpecifiersAreGiven() { - new QSort(); - } - @Test(expected = IllegalArgumentException.class) // DATACMNS-402 public void shouldThrowIfNullIsGiven() { new QSort((List>) null); @@ -165,7 +160,7 @@ public class QSortUnitTests { StringPath path = new PathBuilderFactory().create(User.class).getString("firstname"); - QSort sort = new QSort(new OrderSpecifier(com.querydsl.core.types.Order.ASC, path)); + QSort sort = new QSort(new OrderSpecifier<>(com.querydsl.core.types.Order.ASC, path)); assertThat(sort).contains(new Order(Direction.ASC, "firstname")); } diff --git a/src/test/java/org/springframework/data/querydsl/QuerydslRepositoryInvokerAdapterUnitTests.java b/src/test/java/org/springframework/data/querydsl/QuerydslRepositoryInvokerAdapterUnitTests.java index b5ab19af1..d2a8acd93 100755 --- a/src/test/java/org/springframework/data/querydsl/QuerydslRepositoryInvokerAdapterUnitTests.java +++ b/src/test/java/org/springframework/data/querydsl/QuerydslRepositoryInvokerAdapterUnitTests.java @@ -15,11 +15,10 @@ */ package org.springframework.data.querydsl; -import static org.mockito.Matchers.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.io.Serializable; -import java.lang.reflect.Method; import org.junit.Before; import org.junit.Test; @@ -27,10 +26,8 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.repository.support.RepositoryInvoker; -import org.springframework.util.MultiValueMap; import com.querydsl.core.types.Predicate; @@ -57,7 +54,7 @@ public class QuerydslRepositoryInvokerAdapterUnitTests { @Test // DATACMNS-669 public void forwardsFindAllToExecutorWithPredicate() { - Sort sort = new Sort("firstname"); + Sort sort = Sort.by("firstname"); adapter.invokeFindAll(sort); verify(executor, times(1)).findAll(predicate, sort); @@ -67,7 +64,7 @@ public class QuerydslRepositoryInvokerAdapterUnitTests { @Test // DATACMNS-669 public void forwardsFindAllWithPageableToExecutorWithPredicate() { - PageRequest pageable = new PageRequest(0, 10); + PageRequest pageable = PageRequest.of(0, 10); adapter.invokeFindAll(pageable); verify(executor, times(1)).findAll(predicate, pageable); @@ -91,15 +88,14 @@ public class QuerydslRepositoryInvokerAdapterUnitTests { verify(delegate, times(1)).hasSaveMethod(); adapter.invokeDelete(any(Serializable.class)); - verify(delegate, times(1)).invokeDelete(any(Serializable.class)); + verify(delegate, times(1)).invokeDelete(any()); adapter.invokeFindOne(any(Serializable.class)); - verify(delegate, times(1)).invokeFindOne(any(Serializable.class)); + verify(delegate, times(1)).invokeFindOne(any()); - adapter.invokeQueryMethod(any(Method.class), (MultiValueMap) any(MultiValueMap.class), - any(Pageable.class), any(Sort.class)); - verify(delegate, times(1)).invokeQueryMethod(any(Method.class), - (MultiValueMap) any(MultiValueMap.class), any(Pageable.class), any(Sort.class)); + adapter.invokeQueryMethod(any(), any(), any(), any()); + + verify(delegate, times(1)).invokeQueryMethod(any(), any(), any(), any()); adapter.invokeSave(any()); verify(delegate, times(1)).invokeSave(any()); diff --git a/src/test/java/org/springframework/data/querydsl/binding/QuerydslPredicateBuilderUnitTests.java b/src/test/java/org/springframework/data/querydsl/binding/QuerydslPredicateBuilderUnitTests.java index 6196356ed..421199a5d 100755 --- a/src/test/java/org/springframework/data/querydsl/binding/QuerydslPredicateBuilderUnitTests.java +++ b/src/test/java/org/springframework/data/querydsl/binding/QuerydslPredicateBuilderUnitTests.java @@ -173,7 +173,7 @@ public class QuerydslPredicateBuilderUnitTests { Predicate predicate = builder.getPredicate(USER_TYPE, values, DEFAULT_BINDINGS); - assertThat(predicate).isEqualTo((Predicate) QUser.user.addresses.any().street.eq("VALUE")); + assertThat(predicate).isEqualTo(QUser.user.addresses.any().street.eq("VALUE")); } @Test // DATACMNS-941 diff --git a/src/test/java/org/springframework/data/repository/cdi/CdiRepositoryBeanUnitTests.java b/src/test/java/org/springframework/data/repository/cdi/CdiRepositoryBeanUnitTests.java index 9c3ccf054..072dee968 100755 --- a/src/test/java/org/springframework/data/repository/cdi/CdiRepositoryBeanUnitTests.java +++ b/src/test/java/org/springframework/data/repository/cdi/CdiRepositoryBeanUnitTests.java @@ -53,23 +53,23 @@ public class CdiRepositoryBeanUnitTests { @Test(expected = IllegalArgumentException.class) public void voidRejectsNullQualifiers() { - new DummyCdiRepositoryBean(null, SampleRepository.class, beanManager); + new DummyCdiRepositoryBean<>(null, SampleRepository.class, beanManager); } @Test(expected = IllegalArgumentException.class) public void voidRejectsNullRepositoryType() { - new DummyCdiRepositoryBean(NO_ANNOTATIONS, null, beanManager); + new DummyCdiRepositoryBean<>(NO_ANNOTATIONS, null, beanManager); } @Test(expected = IllegalArgumentException.class) public void voidRejectsNullBeanManager() { - new DummyCdiRepositoryBean(NO_ANNOTATIONS, SampleRepository.class, null); + new DummyCdiRepositoryBean<>(NO_ANNOTATIONS, SampleRepository.class, null); } @Test public void returnsBasicMetadata() { - DummyCdiRepositoryBean bean = new DummyCdiRepositoryBean(NO_ANNOTATIONS, + DummyCdiRepositoryBean bean = new DummyCdiRepositoryBean<>(NO_ANNOTATIONS, SampleRepository.class, beanManager); assertThat(bean.getBeanClass()).isEqualTo(SampleRepository.class); @@ -80,7 +80,7 @@ public class CdiRepositoryBeanUnitTests { @Test public void returnsAllImplementedTypes() { - DummyCdiRepositoryBean bean = new DummyCdiRepositoryBean(NO_ANNOTATIONS, + DummyCdiRepositoryBean bean = new DummyCdiRepositoryBean<>(NO_ANNOTATIONS, SampleRepository.class, beanManager); Set types = bean.getTypes(); @@ -91,7 +91,7 @@ public class CdiRepositoryBeanUnitTests { @SuppressWarnings("unchecked") public void detectsStereotypes() { - DummyCdiRepositoryBean bean = new DummyCdiRepositoryBean( + DummyCdiRepositoryBean bean = new DummyCdiRepositoryBean<>( NO_ANNOTATIONS, StereotypedSampleRepository.class, beanManager); assertThat(bean.getStereotypes()).containsExactly(StereotypeAnnotation.class); @@ -101,7 +101,7 @@ public class CdiRepositoryBeanUnitTests { @SuppressWarnings("rawtypes") public void scopeDefaultsToApplicationScoped() { - Bean bean = new DummyCdiRepositoryBean(NO_ANNOTATIONS, SampleRepository.class, + Bean bean = new DummyCdiRepositoryBean<>(NO_ANNOTATIONS, SampleRepository.class, beanManager); assertThat(bean.getScope()).isEqualTo(ApplicationScoped.class); } @@ -109,7 +109,7 @@ public class CdiRepositoryBeanUnitTests { @Test // DATACMNS-322 public void createsPassivationId() { - CdiRepositoryBean bean = new DummyCdiRepositoryBean(SINGLE_ANNOTATION, + CdiRepositoryBean bean = new DummyCdiRepositoryBean<>(SINGLE_ANNOTATION, SampleRepository.class, beanManager); assertThat(bean.getId()).isEqualTo(PASSIVATION_ID); } diff --git a/src/test/java/org/springframework/data/repository/config/AnnotationRepositoryConfigurationSourceUnitTests.java b/src/test/java/org/springframework/data/repository/config/AnnotationRepositoryConfigurationSourceUnitTests.java index b193d85c0..46b9483f8 100755 --- a/src/test/java/org/springframework/data/repository/config/AnnotationRepositoryConfigurationSourceUnitTests.java +++ b/src/test/java/org/springframework/data/repository/config/AnnotationRepositoryConfigurationSourceUnitTests.java @@ -101,7 +101,7 @@ public class AnnotationRepositoryConfigurationSourceUnitTests { public void findsStringAttributeByName() { RepositoryConfigurationSource source = getConfigSource(DefaultConfigurationWithBasePackage.class); - assertThat(source.getAttribute("namedQueriesLocation")).isEqualTo("bar"); + assertThat(source.getAttribute("namedQueriesLocation")).hasValue("bar"); } @Test // DATACMNS-502 @@ -129,7 +129,7 @@ public class AnnotationRepositoryConfigurationSourceUnitTests { RepositoryConfigurationSource configurationSource = new AnnotationRepositoryConfigurationSource(metadata, SampleAnnotation.class, resourceLoader, environment); - assertThat(configurationSource.getRepositoryBaseClassName()).isNull(); + assertThat(configurationSource.getRepositoryBaseClassName()).isNotPresent(); } private AnnotationRepositoryConfigurationSource getConfigSource(Class type) { diff --git a/src/test/java/org/springframework/data/repository/config/DefaultRepositoryConfigurationUnitTests.java b/src/test/java/org/springframework/data/repository/config/DefaultRepositoryConfigurationUnitTests.java index 337aae7e4..760891147 100755 --- a/src/test/java/org/springframework/data/repository/config/DefaultRepositoryConfigurationUnitTests.java +++ b/src/test/java/org/springframework/data/repository/config/DefaultRepositoryConfigurationUnitTests.java @@ -37,7 +37,7 @@ public class DefaultRepositoryConfigurationUnitTests { @Test public void supportsBasicConfiguration() { - RepositoryConfiguration configuration = new DefaultRepositoryConfiguration( + RepositoryConfiguration configuration = new DefaultRepositoryConfiguration<>( source, new RootBeanDefinition("com.acme.MyRepository")); assertThat(configuration.getConfigurationSource()).isEqualTo(source); diff --git a/src/test/java/org/springframework/data/repository/config/RepositoryBeanDefinitionRegistrarSupportUnitTests.java b/src/test/java/org/springframework/data/repository/config/RepositoryBeanDefinitionRegistrarSupportUnitTests.java index a96a7ab55..cd9f193cf 100755 --- a/src/test/java/org/springframework/data/repository/config/RepositoryBeanDefinitionRegistrarSupportUnitTests.java +++ b/src/test/java/org/springframework/data/repository/config/RepositoryBeanDefinitionRegistrarSupportUnitTests.java @@ -15,7 +15,7 @@ */ package org.springframework.data.repository.config; -import static org.mockito.Matchers.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.lang.annotation.Annotation; @@ -31,7 +31,7 @@ import org.springframework.core.env.StandardEnvironment; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.StandardAnnotationMetadata; -import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; +import org.springframework.data.repository.core.support.DummyRepositoryFactoryBean; /** * Integration test for {@link RepositoryBeanDefinitionRegistrarSupport}. @@ -122,7 +122,7 @@ public class RepositoryBeanDefinitionRegistrarSupportUnitTests { static class DummyConfigurationExtension extends RepositoryConfigurationExtensionSupport { public String getRepositoryFactoryClassName() { - return RepositoryFactoryBeanSupport.class.getName(); + return DummyRepositoryFactoryBean.class.getName(); } @Override diff --git a/src/test/java/org/springframework/data/repository/config/XmlRepositoryConfigurationSourceUnitTests.java b/src/test/java/org/springframework/data/repository/config/XmlRepositoryConfigurationSourceUnitTests.java index cfe7e4aa5..161c1801a 100755 --- a/src/test/java/org/springframework/data/repository/config/XmlRepositoryConfigurationSourceUnitTests.java +++ b/src/test/java/org/springframework/data/repository/config/XmlRepositoryConfigurationSourceUnitTests.java @@ -16,7 +16,7 @@ package org.springframework.data.repository.config; import static org.assertj.core.api.Assertions.*; -import static org.mockito.Matchers.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import org.junit.Test; @@ -45,6 +45,6 @@ public class XmlRepositoryConfigurationSourceUnitTests { when(element.getAttribute("some-xml-attribute")).thenReturn("value"); - assertThat(source.getAttribute("someXmlAttribute")).isEqualTo("value"); + assertThat(source.getAttribute("someXmlAttribute")).hasValue("value"); } } diff --git a/src/test/java/org/springframework/data/repository/core/support/AbstractEntityInformationUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/AbstractEntityInformationUnitTests.java index 555410dd2..152211486 100755 --- a/src/test/java/org/springframework/data/repository/core/support/AbstractEntityInformationUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/AbstractEntityInformationUnitTests.java @@ -18,10 +18,9 @@ package org.springframework.data.repository.core.support; import static org.assertj.core.api.Assertions.*; import java.io.Serializable; +import java.util.Optional; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.springframework.data.annotation.Id; import org.springframework.data.repository.core.EntityInformation; import org.springframework.test.util.ReflectionTestUtils; @@ -35,18 +34,16 @@ import org.springframework.util.ReflectionUtils; */ public class AbstractEntityInformationUnitTests { - @Rule public ExpectedException exception = ExpectedException.none(); - @Test(expected = IllegalArgumentException.class) public void rejectsNullDomainClass() throws Exception { - - new DummyEntityInformation(null); + new DummyEntityInformation<>(null); } @Test public void considersEntityNewIfGetIdReturnsNull() throws Exception { - EntityInformation metadata = new DummyEntityInformation(Object.class); + EntityInformation metadata = new DummyEntityInformation<>(Object.class); + assertThat(metadata.isNew(null)).isTrue(); assertThat(metadata.isNew(new Object())).isFalse(); } @@ -54,7 +51,8 @@ public class AbstractEntityInformationUnitTests { @Test // DATACMNS-357 public void detectsNewStateForPrimitiveIds() { - FooEn fooEn = new FooEn(PrimitiveIdEntity.class); + CustomEntityInformation fooEn = new CustomEntityInformation( + PrimitiveIdEntity.class); PrimitiveIdEntity entity = new PrimitiveIdEntity(); assertThat(fooEn.isNew(entity)).isTrue(); @@ -66,7 +64,7 @@ public class AbstractEntityInformationUnitTests { @Test // DATACMNS-357 public void detectsNewStateForPrimitiveWrapperIds() { - FooEn fooEn = new FooEn( + CustomEntityInformation fooEn = new CustomEntityInformation( PrimitiveWrapperIdEntity.class); PrimitiveWrapperIdEntity entity = new PrimitiveWrapperIdEntity(); @@ -79,12 +77,12 @@ public class AbstractEntityInformationUnitTests { @Test // DATACMNS-357 public void rejectsUnsupportedPrimitiveIdType() { - FooEn information = new FooEn( + CustomEntityInformation information = new CustomEntityInformation( UnsupportedPrimitiveIdEntity.class); - exception.expect(IllegalArgumentException.class); - exception.expectMessage(boolean.class.getName()); - information.isNew(new UnsupportedPrimitiveIdEntity()); + assertThatExceptionOfType(IllegalArgumentException.class)// + .isThrownBy(() -> information.isNew(new UnsupportedPrimitiveIdEntity()))// + .withMessageContaining(boolean.class.getName()); } static class PrimitiveIdEntity { @@ -102,19 +100,19 @@ public class AbstractEntityInformationUnitTests { @Id boolean id; } - static class FooEn extends AbstractEntityInformation { + static class CustomEntityInformation extends AbstractEntityInformation { private final Class type; - private FooEn(Class type) { + private CustomEntityInformation(Class type) { super(type); this.type = type; } @Override @SuppressWarnings("unchecked") - public ID getId(T entity) { - return (ID) ReflectionTestUtils.getField(entity, "id"); + public Optional getId(T entity) { + return Optional.ofNullable((ID) ReflectionTestUtils.getField(entity, "id")); } @Override diff --git a/src/test/java/org/springframework/data/repository/core/support/DefaultCrudMethodsUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/DefaultCrudMethodsUnitTests.java index db058eb93..f2cd424c0 100755 --- a/src/test/java/org/springframework/data/repository/core/support/DefaultCrudMethodsUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/DefaultCrudMethodsUnitTests.java @@ -142,7 +142,7 @@ public class DefaultCrudMethodsUnitTests { RepositoryMetadata metadata = new DefaultRepositoryMetadata(repositoryInterface); RepositoryInformation information = new DefaultRepositoryInformation(metadata, PagingAndSortingRepository.class, - null); + Optional.empty()); return new DefaultCrudMethods(information); } diff --git a/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryInformationUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryInformationUnitTests.java index 0ae6a99a6..da3de0564 100755 --- a/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryInformationUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryInformationUnitTests.java @@ -231,7 +231,7 @@ public class DefaultRepositoryInformationUnitTests { GenericsSaveRepositoryImpl customImplementation = new GenericsSaveRepositoryImpl(); RepositoryMetadata metadata = new DefaultRepositoryMetadata(GenericsSaveRepository.class); RepositoryInformation information = new DefaultRepositoryInformation(metadata, RepositoryFactorySupport.class, - customImplementation.getClass()); + Optional.of(customImplementation.getClass())); Method customBaseRepositoryMethod = GenericsSaveRepository.class.getMethod("save", Object.class); assertThat(information.isCustomMethod(customBaseRepositoryMethod), is(true)); diff --git a/src/test/java/org/springframework/data/repository/core/support/DummyEntityInformation.java b/src/test/java/org/springframework/data/repository/core/support/DummyEntityInformation.java index 47d8b472e..fa7cf7476 100644 --- a/src/test/java/org/springframework/data/repository/core/support/DummyEntityInformation.java +++ b/src/test/java/org/springframework/data/repository/core/support/DummyEntityInformation.java @@ -16,6 +16,7 @@ package org.springframework.data.repository.core.support; import java.io.Serializable; +import java.util.Optional; /** * Dummy implementation of {@link AbstractEntityInformation}. @@ -37,8 +38,8 @@ public class DummyEntityInformation extends AbstractEntityInformation getId(Object entity) { + return Optional.ofNullable(entity == null ? null : entity.toString()); } /* @@ -48,4 +49,4 @@ public class DummyEntityInformation extends AbstractEntityInformation getIdType() { return Serializable.class; } -} \ No newline at end of file +} diff --git a/src/test/java/org/springframework/data/repository/core/support/ExampleSpecificationAccessorUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/ExampleSpecificationAccessorUnitTests.java index 2e10df47c..258269518 100755 --- a/src/test/java/org/springframework/data/repository/core/support/ExampleSpecificationAccessorUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/ExampleSpecificationAccessorUnitTests.java @@ -21,8 +21,6 @@ import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatc import org.junit.Before; import org.junit.Test; import org.springframework.data.domain.ExampleMatcher; -import org.springframework.data.domain.ExampleMatcher.GenericPropertyMatcher; -import org.springframework.data.domain.ExampleMatcher.MatcherConfigurer; import org.springframework.data.domain.ExampleMatcher.NoOpPropertyValueTransformer; import org.springframework.data.domain.ExampleMatcher.NullHandler; import org.springframework.data.domain.ExampleMatcher.PropertyValueTransformer; @@ -155,12 +153,7 @@ public class ExampleSpecificationAccessorUnitTests { specification = ExampleMatcher.matching().withStringMatcher(StringMatcher.ENDING) .withMatcher("firstname", contains()).withMatcher("address.city", startsWith()) - .withMatcher("lastname", new MatcherConfigurer() { - @Override - public void configureMatcher(GenericPropertyMatcher matcher) { - matcher.ignoreCase(); - } - }); + .withMatcher("lastname", matcher -> matcher.ignoreCase()); exampleSpecificationAccessor = new ExampleMatcherAccessor(specification); @@ -175,12 +168,7 @@ public class ExampleSpecificationAccessorUnitTests { specification = ExampleMatcher.matching().// withStringMatcher(StringMatcher.STARTING).// - withMatcher("firstname", new MatcherConfigurer() { - @Override - public void configureMatcher(GenericPropertyMatcher matcher) { - matcher.ignoreCase(); - } - }); + withMatcher("firstname", matcher -> matcher.ignoreCase()); exampleSpecificationAccessor = new ExampleMatcherAccessor(specification); diff --git a/src/test/java/org/springframework/data/repository/core/support/PersistableEntityInformationUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/PersistableEntityInformationUnitTests.java index 3cd91d158..cbc3a63cb 100755 --- a/src/test/java/org/springframework/data/repository/core/support/PersistableEntityInformationUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/PersistableEntityInformationUnitTests.java @@ -43,9 +43,10 @@ public class PersistableEntityInformationUnitTests { public void usesPersistablesGetId() throws Exception { when(persistable.getId()).thenReturn(2L, 1L, 3L); - assertThat(metadata.getId(persistable)).isEqualTo(2L); - assertThat(metadata.getId(persistable)).isEqualTo(1L); - assertThat(metadata.getId(persistable)).isEqualTo(3L); + + assertThat(metadata.getId(persistable)).hasValue(2L); + assertThat(metadata.getId(persistable)).hasValue(1L); + assertThat(metadata.getId(persistable)).hasValue(3L); } @Test @@ -53,6 +54,7 @@ public class PersistableEntityInformationUnitTests { public void usesPersistablesIsNew() throws Exception { when(persistable.isNew()).thenReturn(true, false); + assertThat(metadata.isNew(persistable)).isTrue(); assertThat(metadata.isNew(persistable)).isFalse(); } diff --git a/src/test/java/org/springframework/data/repository/core/support/PersistenceExceptionTranslationRepositoryProxyPostProcessorUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/PersistenceExceptionTranslationRepositoryProxyPostProcessorUnitTests.java index ca051127e..84ee9e74f 100755 --- a/src/test/java/org/springframework/data/repository/core/support/PersistenceExceptionTranslationRepositoryProxyPostProcessorUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/PersistenceExceptionTranslationRepositoryProxyPostProcessorUnitTests.java @@ -15,13 +15,9 @@ */ package org.springframework.data.repository.core.support; -import static org.mockito.Matchers.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; -import java.util.HashMap; -import java.util.Map; - -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -29,7 +25,6 @@ import org.mockito.runners.MockitoJUnitRunner; import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.dao.support.PersistenceExceptionTranslationInterceptor; -import org.springframework.dao.support.PersistenceExceptionTranslator; /** * Unit test for {@link TransactionalRepositoryProxyPostProcessor}. @@ -43,18 +38,8 @@ public class PersistenceExceptionTranslationRepositoryProxyPostProcessorUnitTest @Mock ListableBeanFactory beanFactory; @Mock ProxyFactory proxyFactory; - @Before - public void setUp() { - - Map beans = new HashMap(); - beans.put("foo", mock(PersistenceExceptionTranslator.class)); - when(beanFactory.getBeansOfType(eq(PersistenceExceptionTranslator.class), anyBoolean(), anyBoolean())).thenReturn( - beans); - } - @Test(expected = IllegalArgumentException.class) // DATACMNS-318 public void rejectsNullBeanFactory() throws Exception { - new PersistenceExceptionTranslationRepositoryProxyPostProcessor(null); } diff --git a/src/test/java/org/springframework/data/repository/core/support/PersistentEntityInformationUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/PersistentEntityInformationUnitTests.java index b31223031..4c7141381 100755 --- a/src/test/java/org/springframework/data/repository/core/support/PersistentEntityInformationUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/PersistentEntityInformationUnitTests.java @@ -37,7 +37,7 @@ public class PersistentEntityInformationUnitTests { public void obtainsIdAndIdTypeInformationFromPersistentEntity() { SampleMappingContext context = new SampleMappingContext(); - PersistentEntity entity = context.getPersistentEntity(Sample.class); + PersistentEntity entity = context.getRequiredPersistentEntity(Sample.class); EntityInformation information = new PersistentEntityInformation(entity); assertThat(information.getIdType()).isEqualTo(Long.class); @@ -45,18 +45,19 @@ public class PersistentEntityInformationUnitTests { Sample sample = new Sample(); sample.id = 5L; - assertThat(information.getId(sample)).isEqualTo(5L); + assertThat(information.getId(sample)).hasValue(5L); } @Test // DATACMNS-596 public void returnsNullIfNoIdPropertyPresent() { SampleMappingContext context = new SampleMappingContext(); - PersistentEntity entity = context.getPersistentEntity(EntityWithoutId.class); + PersistentEntity entity = context + .getRequiredPersistentEntity(EntityWithoutId.class); PersistentEntityInformation information = new PersistentEntityInformation( entity); - assertThat(information.getId(new EntityWithoutId())).isNull(); + assertThat(information.getId(new EntityWithoutId())).isNotPresent(); } static class Sample { diff --git a/src/test/java/org/springframework/data/repository/core/support/QueryExecutionResultHandlerUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/QueryExecutionResultHandlerUnitTests.java index dbee5f8aa..555af9551 100755 --- a/src/test/java/org/springframework/data/repository/core/support/QueryExecutionResultHandlerUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/QueryExecutionResultHandlerUnitTests.java @@ -98,7 +98,7 @@ public class QueryExecutionResultHandlerUnitTests { @Test // DATACMNS-917 public void defaultsNullToEmptyMap() throws Exception { - assertThat(handler.postProcessInvocationResult(null, getTypeDescriptorFor("map")), is(instanceOf(Map.class))); + assertThat(handler.postProcessInvocationResult(null, getTypeDescriptorFor("map"))).isInstanceOf(Map.class); } @Test // DATACMNS-836 diff --git a/src/test/java/org/springframework/data/repository/core/support/QueryExecutorMethodInterceptorUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/QueryExecutorMethodInterceptorUnitTests.java index 321393cee..cdaf1df27 100755 --- a/src/test/java/org/springframework/data/repository/core/support/QueryExecutorMethodInterceptorUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/QueryExecutorMethodInterceptorUnitTests.java @@ -15,7 +15,7 @@ */ package org.springframework.data.repository.core.support; -import static org.mockito.Matchers.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.Optional; diff --git a/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java index c2666482c..cc67cd795 100755 --- a/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java @@ -25,7 +25,6 @@ import java.lang.reflect.Method; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Optional; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; @@ -37,9 +36,7 @@ import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; import org.mockito.runners.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.core.SpringVersion; import org.springframework.data.domain.Page; @@ -121,7 +118,7 @@ public class RepositoryFactorySupportUnitTests { @Test public void invokesCustomMethodIfItRedeclaresACRUDOne() { - ObjectRepository repository = factory.getRepository(ObjectRepository.class, Optional.of(customImplementation)); + ObjectRepository repository = factory.getRepository(ObjectRepository.class, customImplementation); repository.findOne(1); verify(customImplementation, times(1)).findOne(1); @@ -132,7 +129,7 @@ public class RepositoryFactorySupportUnitTests { public void createsRepositoryInstanceWithCustomIntermediateRepository() { CustomRepository repository = factory.getRepository(CustomRepository.class); - Pageable pageable = new PageRequest(0, 10); + Pageable pageable = PageRequest.of(0, 10); repository.findAll(pageable); verify(backingRepo, times(1)).findAll(pageable); @@ -160,12 +157,9 @@ public class RepositoryFactorySupportUnitTests { final Object reference = new Object(); - when(factory.queryOne.execute(Mockito.any(Object[].class))).then(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - Thread.sleep(500); - return reference; - } + when(factory.queryOne.execute(Mockito.any(Object[].class))).then(invocation -> { + Thread.sleep(500); + return reference; }); ConvertingRepository repository = factory.getRepository(ConvertingRepository.class); @@ -295,13 +289,9 @@ public class RepositoryFactorySupportUnitTests { private ConvertingRepository prepareConvertingRepository(final Object expectedValue) { - when(factory.queryOne.execute(Mockito.any(Object[].class))).then(new Answer() { - - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - Thread.sleep(200); - return expectedValue; - } + when(factory.queryOne.execute(Mockito.any(Object[].class))).then(invocation -> { + Thread.sleep(200); + return expectedValue; }); AsyncAnnotationBeanPostProcessor processor = new AsyncAnnotationBeanPostProcessor(); diff --git a/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryProxyPostProcessorUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryProxyPostProcessorUnitTests.java index a52daacf9..03d4f3b35 100755 --- a/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryProxyPostProcessorUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryProxyPostProcessorUnitTests.java @@ -16,15 +16,11 @@ package org.springframework.data.repository.core.support; import static org.assertj.core.api.Assertions.*; -import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import java.io.Serializable; import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -32,7 +28,6 @@ import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.support.TransactionalRepositoryProxyPostProcessor.CustomAnnotationTransactionAttributeSource; @@ -53,15 +48,6 @@ public class TransactionRepositoryProxyPostProcessorUnitTests { @Mock ProxyFactory proxyFactory; @Mock RepositoryInformation repositoryInformation; - @Before - public void setUp() { - - Map beans = new HashMap(); - beans.put("foo", mock(PersistenceExceptionTranslator.class)); - when(beanFactory.getBeansOfType(eq(PersistenceExceptionTranslator.class), anyBoolean(), anyBoolean())) - .thenReturn(beans); - } - @Test(expected = IllegalArgumentException.class) public void rejectsNullBeanFactory() throws Exception { new TransactionalRepositoryProxyPostProcessor(null, "transactionManager", true); diff --git a/src/test/java/org/springframework/data/repository/init/ResourceReaderRepositoryInitializerUnitTests.java b/src/test/java/org/springframework/data/repository/init/ResourceReaderRepositoryInitializerUnitTests.java index 58621b9a0..28efc63b1 100755 --- a/src/test/java/org/springframework/data/repository/init/ResourceReaderRepositoryInitializerUnitTests.java +++ b/src/test/java/org/springframework/data/repository/init/ResourceReaderRepositoryInitializerUnitTests.java @@ -15,7 +15,7 @@ */ package org.springframework.data.repository.init; -import static org.mockito.Matchers.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.Collection; diff --git a/src/test/java/org/springframework/data/repository/query/ExtensionAwareEvaluationContextProviderUnitTests.java b/src/test/java/org/springframework/data/repository/query/ExtensionAwareEvaluationContextProviderUnitTests.java index 904babe28..c1484d70c 100755 --- a/src/test/java/org/springframework/data/repository/query/ExtensionAwareEvaluationContextProviderUnitTests.java +++ b/src/test/java/org/springframework/data/repository/query/ExtensionAwareEvaluationContextProviderUnitTests.java @@ -55,7 +55,7 @@ public class ExtensionAwareEvaluationContextProviderUnitTests { public void setUp() throws Exception { this.method = SampleRepo.class.getMethod("findByFirstname", String.class); - this.provider = new ExtensionAwareEvaluationContextProvider(Collections. emptyList()); + this.provider = new ExtensionAwareEvaluationContextProvider(Collections.emptyList()); } @Test // DATACMNS-533 @@ -70,7 +70,7 @@ public class ExtensionAwareEvaluationContextProviderUnitTests { @Test // DATACMNS-533 public void secondExtensionOverridesFirstOne() { - List extensions = new ArrayList(); + List extensions = new ArrayList<>(); extensions.add(new DummyExtension("_first", "first")); extensions.add(new DummyExtension("_second", "second")); @@ -82,7 +82,7 @@ public class ExtensionAwareEvaluationContextProviderUnitTests { @Test // DATACMNS-533 public void allowsDirectAccessToExtensionViaKey() { - List extensions = new ArrayList(); + List extensions = new ArrayList<>(); extensions.add(new DummyExtension("_first", "first")); extensions.add(new DummyExtension("_second", "second")); @@ -121,9 +121,9 @@ public class ExtensionAwareEvaluationContextProviderUnitTests { public void exposesPageableParameter() throws Exception { this.method = SampleRepo.class.getMethod("findByFirstname", String.class, Pageable.class); - PageRequest pageable = new PageRequest(2, 3, new Sort(Direction.DESC, "lastname")); + PageRequest pageable = PageRequest.of(2, 3, new Sort(Direction.DESC, "lastname")); - assertThat(evaluateExpression("#pageable.offset", new Object[] { "test", pageable })).isEqualTo(6); + assertThat(evaluateExpression("#pageable.offset", new Object[] { "test", pageable })).isEqualTo(6L); assertThat(evaluateExpression("#pageable.pageSize", new Object[] { "test", pageable })).isEqualTo(3); assertThat(evaluateExpression("#pageable.sort.toString()", new Object[] { "test", pageable })) .isEqualTo("lastname: DESC"); diff --git a/src/test/java/org/springframework/data/repository/query/ParametersParameterAccessorUnitTests.java b/src/test/java/org/springframework/data/repository/query/ParametersParameterAccessorUnitTests.java index 874661ae5..4a9b8d547 100755 --- a/src/test/java/org/springframework/data/repository/query/ParametersParameterAccessorUnitTests.java +++ b/src/test/java/org/springframework/data/repository/query/ParametersParameterAccessorUnitTests.java @@ -72,7 +72,7 @@ public class ParametersParameterAccessorUnitTests { DefaultParameters parameters = new DefaultParameters(method); ParametersParameterAccessor accessor = new ParametersParameterAccessor(parameters, - new Object[] { new PageRequest(0, 10), "Foo" }); + new Object[] { PageRequest.of(0, 10), "Foo" }); assertThat(accessor).hasSize(1); } diff --git a/src/test/java/org/springframework/data/repository/query/ResultProcessorUnitTests.java b/src/test/java/org/springframework/data/repository/query/ResultProcessorUnitTests.java index 266f91d2a..ad80e0ca5 100755 --- a/src/test/java/org/springframework/data/repository/query/ResultProcessorUnitTests.java +++ b/src/test/java/org/springframework/data/repository/query/ResultProcessorUnitTests.java @@ -29,6 +29,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -107,7 +108,7 @@ public class ResultProcessorUnitTests { ResultProcessor information = getProcessor("findAllProjection"); - List source = new ArrayList(Arrays.asList(new Sample("Dave", "Matthews"))); + List source = new ArrayList<>(Arrays.asList(new Sample("Dave", "Matthews"))); List result = information.processResult(source); assertThat(result).hasSize(1); @@ -119,7 +120,7 @@ public class ResultProcessorUnitTests { ResultProcessor information = getProcessor("findPageProjection", Pageable.class); - Page source = new PageImpl(Arrays.asList(new Sample("Dave", "Matthews"))); + Page source = new PageImpl<>(Arrays.asList(new Sample("Dave", "Matthews"))); Page result = information.processResult(source); assertThat(result.getContent()).hasSize(1); @@ -143,12 +144,12 @@ public class ResultProcessorUnitTests { ParameterAccessor accessor = mock(ParameterAccessor.class); ResultProcessor factory = getProcessor("findOneDynamic", Class.class); - assertThat(factory.withDynamicProjection(null)).isEqualTo(factory); - assertThat(factory.withDynamicProjection(accessor)).isEqualTo(factory); + assertThat(factory.withDynamicProjection(Optional.empty())).isEqualTo(factory); + assertThat(factory.withDynamicProjection(Optional.of(accessor))).isEqualTo(factory); - doReturn(SampleProjection.class).when(accessor).getDynamicProjection(); + doReturn(Optional.of(SampleProjection.class)).when(accessor).getDynamicProjection(); - ResultProcessor processor = factory.withDynamicProjection(accessor); + ResultProcessor processor = factory.withDynamicProjection(Optional.of(accessor)); assertThat(processor.getReturnedType().getReturnedType()).isEqualTo(SampleProjection.class); } @@ -170,7 +171,7 @@ public class ResultProcessorUnitTests { @Test // DATACMNS-842 public void supportsSlicesAsReturnWrapper() throws Exception { - Slice slice = new SliceImpl(Collections.singletonList(new Sample("Dave", "Matthews"))); + Slice slice = new SliceImpl<>(Collections.singletonList(new Sample("Dave", "Matthews"))); Object result = getProcessor("findSliceProjection", Pageable.class).processResult(slice); diff --git a/src/test/java/org/springframework/data/repository/query/SimpleParameterAccessorUnitTests.java b/src/test/java/org/springframework/data/repository/query/SimpleParameterAccessorUnitTests.java index 114981108..6360e1f9f 100755 --- a/src/test/java/org/springframework/data/repository/query/SimpleParameterAccessorUnitTests.java +++ b/src/test/java/org/springframework/data/repository/query/SimpleParameterAccessorUnitTests.java @@ -42,7 +42,6 @@ public class SimpleParameterAccessorUnitTests { @Test public void testname() throws Exception { - new ParametersParameterAccessor(parameters, new Object[] { "test" }); } @@ -54,19 +53,16 @@ public class SimpleParameterAccessorUnitTests { @Test(expected = IllegalArgumentException.class) public void rejectsNullValues() throws Exception { - new ParametersParameterAccessor(parameters, null); } @Test(expected = IllegalArgumentException.class) public void rejectsTooLittleNumberOfArguments() throws Exception { - new ParametersParameterAccessor(parameters, new Object[0]); } @Test(expected = IllegalArgumentException.class) public void rejectsTooManyArguments() throws Exception { - new ParametersParameterAccessor(parameters, new Object[] { "test", "test" }); } @@ -74,34 +70,38 @@ public class SimpleParameterAccessorUnitTests { public void returnsNullForPageableAndSortIfNoneAvailable() throws Exception { ParameterAccessor accessor = new ParametersParameterAccessor(parameters, new Object[] { "test" }); - assertThat(accessor.getPageable()).isNull(); - assertThat(accessor.getSort()).isNull(); + + assertThat(accessor.getPageable()).isEqualTo(Pageable.NONE); + assertThat(accessor.getSort().isSorted()).isFalse(); } @Test public void returnsSortIfAvailable() { - Sort sort = new Sort("foo"); + Sort sort = Sort.by("foo"); ParameterAccessor accessor = new ParametersParameterAccessor(sortParameters, new Object[] { "test", sort }); + assertThat(accessor.getSort()).isEqualTo(sort); - assertThat(accessor.getPageable()).isNull(); + assertThat(accessor.getPageable()).isEqualTo(Pageable.NONE); } @Test public void returnsPageableIfAvailable() { - Pageable pageable = new PageRequest(0, 10); + Pageable pageable = PageRequest.of(0, 10); ParameterAccessor accessor = new ParametersParameterAccessor(pageableParameters, new Object[] { "test", pageable }); + assertThat(accessor.getPageable()).isEqualTo(pageable); - assertThat(accessor.getSort()).isNull(); + assertThat(accessor.getSort().isSorted()).isFalse(); } @Test public void returnsSortFromPageableIfAvailable() throws Exception { - Sort sort = new Sort("foo"); - Pageable pageable = new PageRequest(0, 10, sort); + Sort sort = Sort.by("foo"); + Pageable pageable = PageRequest.of(0, 10, sort); ParameterAccessor accessor = new ParametersParameterAccessor(pageableParameters, new Object[] { "test", pageable }); + assertThat(accessor.getPageable()).isEqualTo(pageable); assertThat(accessor.getSort()).isEqualTo(sort); } diff --git a/src/test/java/org/springframework/data/repository/query/StreamQueryResultHandlerUnitTests.java b/src/test/java/org/springframework/data/repository/query/StreamQueryResultHandlerUnitTests.java deleted file mode 100755 index bb38045b6..000000000 --- a/src/test/java/org/springframework/data/repository/query/StreamQueryResultHandlerUnitTests.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2016-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.repository.query; - -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; - -import lombok.Value; - -import java.util.Arrays; -import java.util.stream.Stream; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.core.convert.converter.Converter; -import org.springframework.data.projection.ProjectionFactory; -import org.springframework.data.repository.query.ResultProcessor.StreamQueryResultHandler; - -/** - * Unit tests for {@link StreamQueryResultHandler}. - * - * @author John Blum - * @author Oliver Gierke - */ -public class StreamQueryResultHandlerUnitTests { - - StreamQueryResultHandler handler; - - @Before - public void setUp() { - - ReturnedType returnedType = ReturnedType.of(String.class, Person.class, mock(ProjectionFactory.class)); - - this.handler = new StreamQueryResultHandler(returnedType, new Converter() { - - @Override - public Object convert(Object source) { - return source.toString(); - } - }); - } - - @Test // DATACMNS-868 - @SuppressWarnings("unchecked") - public void mapsStreamUsingConverter() { - - Stream people = Arrays.asList(Person.of("Dave", "Matthews")).stream(); - - Object result = this.handler.handle(people); - - assertThat(result).isInstanceOf(Stream.class); - - Stream stream = (Stream) result; - - assertThat(stream).allMatch(it -> { - - assertThat(it).isInstanceOf(String.class); - - String string = (String) it; - - assertThat(string).contains("Dave"); - assertThat(string).contains("Matthews"); - - return true; - }); - - stream.close(); - } - - @Test(expected = IllegalArgumentException.class) // DATACMNS-868 - public void rejectsNullSource() { - handler.handle(null); - } - - @Value(staticConstructor = "of") - static class Person { - String firstName, lastName; - } -} diff --git a/src/test/java/org/springframework/data/repository/query/parser/OrderBySourceUnitTests.java b/src/test/java/org/springframework/data/repository/query/parser/OrderBySourceUnitTests.java index 8cbe6d226..79aed5c16 100755 --- a/src/test/java/org/springframework/data/repository/query/parser/OrderBySourceUnitTests.java +++ b/src/test/java/org/springframework/data/repository/query/parser/OrderBySourceUnitTests.java @@ -16,11 +16,11 @@ package org.springframework.data.repository.query.parser; import static org.assertj.core.api.Assertions.*; -import static org.springframework.data.domain.Sort.Direction.*; + +import java.util.Optional; import org.junit.Test; import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Sort.Order; /** * Unit test for {@link OrderBySource}. @@ -31,19 +31,20 @@ public class OrderBySourceUnitTests { @Test public void handlesSingleDirectionAndPropertyCorrectly() throws Exception { - assertThat(new OrderBySource("UsernameDesc").toSort()).hasValue(new Sort(DESC, "username")); + assertThat(new OrderBySource("UsernameDesc").toSort()).isEqualTo(Sort.by("username").descending()); } @Test public void handlesCamelCasePropertyCorrecty() throws Exception { - assertThat(new OrderBySource("LastnameUsernameDesc").toSort()).hasValue(new Sort(DESC, "lastnameUsername")); + assertThat(new OrderBySource("LastnameUsernameDesc").toSort()).isEqualTo(Sort.by("lastnameUsername").descending()); } @Test public void handlesMultipleDirectionsCorrectly() throws Exception { OrderBySource orderBySource = new OrderBySource("LastnameAscUsernameDesc"); - assertThat(orderBySource.toSort()).hasValue(new Sort(new Order(ASC, "lastname"), new Order(DESC, "username"))); + assertThat(orderBySource.toSort()).isEqualTo(Sort.by("lastname").ascending().and(Sort.by("username").descending())); + // assertThat(orderBySource.toSort()).hasValue(new Sort(new Order(ASC, "lastname"), new Order(DESC, "username"))); } @Test(expected = IllegalArgumentException.class) @@ -55,15 +56,20 @@ public class OrderBySourceUnitTests { @Test public void usesNestedPropertyCorrectly() throws Exception { - OrderBySource source = new OrderBySource("BarNameDesc", Foo.class); - assertThat(source.toSort()).hasValue(new Sort(new Order(DESC, "bar.name"))); + OrderBySource source = new OrderBySource("BarNameDesc", Optional.of(Foo.class)); + assertThat(source.toSort()).isEqualTo(Sort.by("bar.name").descending()); } @Test // DATACMNS-641 public void defaultsSortOrderToAscendingSort() { OrderBySource source = new OrderBySource("lastname"); - assertThat(source.toSort()).hasValue(new Sort("lastname")); + assertThat(source.toSort()).isEqualTo(Sort.by("lastname")); + } + + @Test + public void orderBySourceFromEmptyStringResultsInUnsorted() { + assertThat(new OrderBySource("").toSort()).isEqualTo(Sort.unsorted()); } @SuppressWarnings("unused") diff --git a/src/test/java/org/springframework/data/repository/query/parser/PartTreeUnitTests.java b/src/test/java/org/springframework/data/repository/query/parser/PartTreeUnitTests.java index 0ff43c9bf..c7ac3ec79 100755 --- a/src/test/java/org/springframework/data/repository/query/parser/PartTreeUnitTests.java +++ b/src/test/java/org/springframework/data/repository/query/parser/PartTreeUnitTests.java @@ -28,7 +28,6 @@ import java.util.List; import org.junit.Test; import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Sort.Direction; import org.springframework.data.mapping.PropertyPath; import org.springframework.data.repository.query.parser.Part.IgnoreCaseType; import org.springframework.data.repository.query.parser.Part.Type; @@ -74,14 +73,14 @@ public class PartTreeUnitTests { public void parsesAndPropertiesCorrectly() throws Exception { PartTree partTree = partTree("firstnameAndLastname"); assertPart(partTree, parts("firstname", "lastname")); - assertThat(partTree.getSort()).isNull(); + assertThat(partTree.getSort().isSorted()).isFalse(); } @Test public void parsesOrPropertiesCorrectly() throws Exception { PartTree partTree = partTree("firstnameOrLastname"); assertPart(partTree, parts("firstname"), parts("lastname")); - assertThat(partTree.getSort()).isNull(); + assertThat(partTree.getSort().isSorted()).isFalse(); } @Test @@ -92,8 +91,7 @@ public class PartTreeUnitTests { @Test public void hasSortIfOrderByIsGiven() throws Exception { - PartTree partTree = partTree("firstnameOrderByLastnameDesc"); - assertThat(partTree.getSort()).isEqualTo(new Sort(Direction.DESC, "lastname")); + assertThat(partTree("firstnameOrderByLastnameDesc").getSort()).isEqualTo(Sort.by("lastname").descending()); } @Test @@ -105,7 +103,7 @@ public class PartTreeUnitTests { private void hasSortIfOrderByIsGivenWithAllIgnoreCase(String source) throws Exception { PartTree partTree = partTree(source); - assertThat(partTree.getSort()).isEqualTo(new Sort(Direction.DESC, "lastname")); + assertThat(partTree.getSort()).isEqualTo(Sort.by("lastname").descending()); } @Test @@ -119,7 +117,7 @@ public class PartTreeUnitTests { // Check it's non-greedy (would strip everything until Order*By* // otherwise) PartTree tree = detectsDistinctCorrectly(prefix + "ByLastnameOrderByFirstnameDesc", false); - assertThat(tree.getSort()).isEqualTo(new Sort(Direction.DESC, "firstname")); + assertThat(tree.getSort()).isEqualTo(Sort.by("firstname").descending()); } } @@ -289,7 +287,9 @@ public class PartTreeUnitTests { @Test // DATACMNS-221 public void parsesSpecialCharactersCorrectly() { + PartTree tree = new PartTree("findByØreAndÅrOrderByÅrAsc", DomainObjectWithSpecialChars.class); + assertPart(tree, new Part[] { new Part("øre", DomainObjectWithSpecialChars.class), new Part("år", DomainObjectWithSpecialChars.class) }); assertThat(tree.getSort().getOrderFor("år").isAscending()).isTrue(); @@ -332,7 +332,7 @@ public class PartTreeUnitTests { new Part("이름", DomainObjectWithSpecialChars.class), // new Part("order.id", DomainObjectWithSpecialChars.class), // new Part("nested.이름", DomainObjectWithSpecialChars.class) // - }); + }); assertPartsIn(parts.next(), new Part[] { // new Part("nested.order.id", DomainObjectWithSpecialChars.class) // }); @@ -365,13 +365,13 @@ public class PartTreeUnitTests { new Part("property1", DomainObjectWithSpecialChars.class), // new Part("øre", DomainObjectWithSpecialChars.class), // new Part("år", DomainObjectWithSpecialChars.class) // - }); + }); assertPartsIn(parts.next(), new Part[] { // new Part("nested.order.id", DomainObjectWithSpecialChars.class), // new Part("nested.property1", DomainObjectWithSpecialChars.class), // new Part("property1", DomainObjectWithSpecialChars.class) // - }); + }); assertThat(tree.getSort().getOrderFor("생일").isAscending()).isTrue(); } @@ -440,7 +440,7 @@ public class PartTreeUnitTests { PartTree tree = new PartTree("findAllByOrderByLastnameAsc", User.class); assertThat(tree.getParts()).isEmpty(); - assertThat(tree.getSort()).isEqualTo(new Sort(Direction.ASC, "lastname")); + assertThat(tree.getSort()).isEqualTo(Sort.by("lastname").ascending()); } @Test // DATACMNS-448 @@ -665,7 +665,7 @@ public class PartTreeUnitTests { private static Collection toCollection(Iterable iterable) { - List result = new ArrayList(); + List result = new ArrayList<>(); for (T element : iterable) { result.add(element); } diff --git a/src/test/java/org/springframework/data/repository/support/CrudRepositoryInvokerUnitTests.java b/src/test/java/org/springframework/data/repository/support/CrudRepositoryInvokerUnitTests.java index 2cf2b850b..2837bc4b9 100755 --- a/src/test/java/org/springframework/data/repository/support/CrudRepositoryInvokerUnitTests.java +++ b/src/test/java/org/springframework/data/repository/support/CrudRepositoryInvokerUnitTests.java @@ -96,8 +96,8 @@ public class CrudRepositoryInvokerUnitTests { Method method = CrudRepository.class.getMethod("findAll"); - getInvokerFor(orderRepository, expectInvocationOf(method)).invokeFindAll((Pageable) null); - getInvokerFor(orderRepository, expectInvocationOf(method)).invokeFindAll((Sort) null); + getInvokerFor(orderRepository, expectInvocationOf(method)).invokeFindAll(Pageable.NONE); + getInvokerFor(orderRepository, expectInvocationOf(method)).invokeFindAll(Sort.unsorted()); } @Test // DATACMNS-589 @@ -107,9 +107,9 @@ public class CrudRepositoryInvokerUnitTests { Method findAllWithSort = CrudWithFindAllWithSort.class.getMethod("findAll", Sort.class); - getInvokerFor(repository, expectInvocationOf(findAllWithSort)).invokeFindAll((Pageable) null); - getInvokerFor(repository, expectInvocationOf(findAllWithSort)).invokeFindAll(new PageRequest(0, 10)); - getInvokerFor(repository, expectInvocationOf(findAllWithSort)).invokeFindAll((Sort) null); + getInvokerFor(repository, expectInvocationOf(findAllWithSort)).invokeFindAll(Sort.unsorted()); + getInvokerFor(repository, expectInvocationOf(findAllWithSort)).invokeFindAll(PageRequest.of(0, 10)); + getInvokerFor(repository, expectInvocationOf(findAllWithSort)).invokeFindAll(Pageable.NONE); } @Test // DATACMNS-589 @@ -119,8 +119,8 @@ public class CrudRepositoryInvokerUnitTests { Method findAllWithPageable = CrudWithFindAllWithPageable.class.getMethod("findAll", Pageable.class); - getInvokerFor(repository, expectInvocationOf(findAllWithPageable)).invokeFindAll((Pageable) null); - getInvokerFor(repository, expectInvocationOf(findAllWithPageable)).invokeFindAll(new PageRequest(0, 10)); + getInvokerFor(repository, expectInvocationOf(findAllWithPageable)).invokeFindAll(Pageable.NONE); + getInvokerFor(repository, expectInvocationOf(findAllWithPageable)).invokeFindAll(PageRequest.of(0, 10)); } @SuppressWarnings({ "rawtypes", "unchecked" }) @@ -150,7 +150,7 @@ public class CrudRepositoryInvokerUnitTests { static class Person {} - interface PersonRepository extends PagingAndSortingRepository { + public interface PersonRepository extends PagingAndSortingRepository { Page findByFirstName(@Param("firstName") String firstName, Pageable pageable); diff --git a/src/test/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactoryIntegrationTests.java b/src/test/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactoryIntegrationTests.java index b7b91af08..a72ba4cb8 100755 --- a/src/test/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactoryIntegrationTests.java +++ b/src/test/java/org/springframework/data/repository/support/DefaultRepositoryInvokerFactoryIntegrationTests.java @@ -23,7 +23,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; -import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.repository.sample.Product; import org.springframework.data.repository.sample.ProductRepository; @@ -56,7 +55,7 @@ public class DefaultRepositoryInvokerFactoryIntegrationTests { @Test // DATACMNS-410, DATACMNS-589 public void findOneShouldDelegateToAppropriateRepository() { - Mockito.reset(productRepository); + // Mockito.reset(productRepository); Product product = new Product(); when(productRepository.findOne(4711L)).thenReturn(product); diff --git a/src/test/java/org/springframework/data/repository/support/DomainClassConverterIntegrationTests.java b/src/test/java/org/springframework/data/repository/support/DomainClassConverterIntegrationTests.java index f7dd1cd5f..84f81a91f 100755 --- a/src/test/java/org/springframework/data/repository/support/DomainClassConverterIntegrationTests.java +++ b/src/test/java/org/springframework/data/repository/support/DomainClassConverterIntegrationTests.java @@ -33,9 +33,7 @@ import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.data.repository.CrudRepository; -import org.springframework.data.repository.core.EntityInformation; import org.springframework.data.repository.core.RepositoryInformation; -import org.springframework.data.repository.core.support.DummyEntityInformation; import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; import org.springframework.data.repository.core.support.RepositoryFactoryInformation; @@ -65,16 +63,10 @@ public class DomainClassConverterIntegrationTests { beanFactory.registerBeanDefinition("postProcessor", new RootBeanDefinition(PredictingProcessor.class)); beanFactory.registerBeanDefinition("repoFactory", new RootBeanDefinition(RepositoryFactoryBeanSupport.class)); - doReturn(PersonRepository.class).when(information).getRepositoryInterface(); doReturn(Person.class).when(information).getDomainType(); doReturn(Serializable.class).when(information).getIdType(); - - EntityInformation entityInformation = new DummyEntityInformation(Person.class); - - when(factory.getObject()).thenReturn(repository); - when(factory.getObjectType()).thenReturn(PersonRepository.class); - when(factory.getEntityInformation()).thenReturn(entityInformation); - when(factory.getRepositoryInformation()).thenReturn(information); + doReturn(PersonRepository.class).when(factory).getObjectType(); + doReturn(information).when(factory).getRepositoryInformation(); GenericApplicationContext context = new GenericApplicationContext(beanFactory); context.refresh(); diff --git a/src/test/java/org/springframework/data/repository/support/DomainClassConverterUnitTests.java b/src/test/java/org/springframework/data/repository/support/DomainClassConverterUnitTests.java index 1c0f00179..9acffa283 100755 --- a/src/test/java/org/springframework/data/repository/support/DomainClassConverterUnitTests.java +++ b/src/test/java/org/springframework/data/repository/support/DomainClassConverterUnitTests.java @@ -16,7 +16,7 @@ package org.springframework.data.repository.support; import static org.assertj.core.api.Assertions.*; -import static org.mockito.Matchers.*; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.lang.reflect.Method; @@ -46,7 +46,7 @@ import org.springframework.web.bind.annotation.ModelAttribute; * @author Oliver Gierke * @author Thomas Darimont */ -@RunWith(MockitoJUnitRunner.class) +@RunWith(MockitoJUnitRunner.Silent.class) public class DomainClassConverterUnitTests { static final User USER = new User(); @@ -115,8 +115,7 @@ public class DomainClassConverterUnitTests { ApplicationContext context = initContextWithRepo(); converter.setApplicationContext(context); - when(service.canConvert(String.class, Long.class)).thenReturn(true); - when(service.convert(anyString(), eq(Long.class))).thenReturn(1L); + doReturn(1L).when(service).convert(any(), eq(Long.class)); converter.convert("1", STRING_TYPE, USER_TYPE); diff --git a/src/test/java/org/springframework/data/repository/support/MethodParametersUnitTests.java b/src/test/java/org/springframework/data/repository/support/MethodParametersUnitTests.java index f5f0e47f7..bd0c49e68 100755 --- a/src/test/java/org/springframework/data/repository/support/MethodParametersUnitTests.java +++ b/src/test/java/org/springframework/data/repository/support/MethodParametersUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.*; import java.lang.reflect.Method; import java.util.List; +import java.util.Optional; import org.junit.Test; import org.springframework.beans.factory.annotation.Qualifier; @@ -35,11 +36,11 @@ public class MethodParametersUnitTests { public void prefersAnnotatedParameterOverDiscovered() throws Exception { Method method = Sample.class.getMethod("method", String.class, String.class, Object.class); - MethodParameters parameters = new MethodParameters(method, new AnnotationAttribute(Qualifier.class)); + MethodParameters parameters = new MethodParameters(method, Optional.of(new AnnotationAttribute(Qualifier.class))); - assertThat(parameters.getParameter("param")).isNotNull(); - assertThat(parameters.getParameter("foo")).isNotNull(); - assertThat(parameters.getParameter("another")).isNull(); + assertThat(parameters.getParameter("param")).isPresent(); + assertThat(parameters.getParameter("foo")).isPresent(); + assertThat(parameters.getParameter("another")).isNotPresent(); } /** @@ -52,6 +53,7 @@ public class MethodParametersUnitTests { MethodParameters methodParameters = new MethodParameters(method); List objectParameters = methodParameters.getParametersOfType(Object.class); + assertThat(objectParameters).hasSize(1); assertThat(objectParameters.get(0).getParameterIndex()).isEqualTo(2); } diff --git a/src/test/java/org/springframework/data/repository/support/PageableExecutionUtilsUnitTests.java b/src/test/java/org/springframework/data/repository/support/PageableExecutionUtilsUnitTests.java index e60854c58..c04da9701 100755 --- a/src/test/java/org/springframework/data/repository/support/PageableExecutionUtilsUnitTests.java +++ b/src/test/java/org/springframework/data/repository/support/PageableExecutionUtilsUnitTests.java @@ -20,6 +20,7 @@ import static org.mockito.Mockito.*; import java.util.Arrays; import java.util.Collections; +import java.util.function.LongSupplier; import org.junit.Test; import org.junit.runner.RunWith; @@ -27,7 +28,7 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; -import org.springframework.data.repository.support.PageableExecutionUtils.TotalSupplier; +import org.springframework.data.domain.Pageable; /** * Unit tests for {@link PageableExecutionUtils}. @@ -38,7 +39,7 @@ import org.springframework.data.repository.support.PageableExecutionUtils.TotalS @RunWith(MockitoJUnitRunner.class) public class PageableExecutionUtilsUnitTests { - @Mock TotalSupplier totalSupplierMock; + @Mock LongSupplier totalSupplierMock; @Test // DATAMCNS-884 public void firstPageRequestIsLessThanOneFullPageDoesNotRequireTotal() { @@ -52,9 +53,9 @@ public class PageableExecutionUtilsUnitTests { } @Test // DATAMCNS-884 - public void noPageableRequesDoesNotRequireTotal() { + public void noPageableRequestDoesNotRequireTotal() { - Page page = PageableExecutionUtils.getPage(Arrays.asList(1, 2, 3), null, totalSupplierMock); + Page page = PageableExecutionUtils.getPage(Arrays.asList(1, 2, 3), Pageable.NONE, totalSupplierMock); assertThat(page).contains(1, 2, 3); assertThat(page.getTotalElements()).isEqualTo(3L); @@ -65,7 +66,7 @@ public class PageableExecutionUtilsUnitTests { @Test // DATAMCNS-884 public void subsequentPageRequestIsLessThanOneFullPageDoesNotRequireTotal() { - Page page = PageableExecutionUtils.getPage(Arrays.asList(1, 2, 3), new PageRequest(5, 10), + Page page = PageableExecutionUtils.getPage(Arrays.asList(1, 2, 3), PageRequest.of(5, 10), totalSupplierMock); assertThat(page).contains(1, 2, 3); @@ -77,7 +78,7 @@ public class PageableExecutionUtilsUnitTests { @Test // DATAMCNS-884 public void firstPageRequestHitsUpperBoundRequiresTotal() { - doReturn(4L).when(totalSupplierMock).get(); + doReturn(4L).when(totalSupplierMock).getAsLong(); Page page = PageableExecutionUtils.getPage(Arrays.asList(1, 2, 3), PageRequest.of(0, 3), totalSupplierMock); @@ -85,13 +86,13 @@ public class PageableExecutionUtilsUnitTests { assertThat(page).contains(1, 2, 3); assertThat(page.getTotalElements()).isEqualTo(4L); - verify(totalSupplierMock).get(); + verify(totalSupplierMock).getAsLong(); } @Test // DATAMCNS-884 public void subsequentPageRequestHitsUpperBoundRequiresTotal() { - doReturn(7L).when(totalSupplierMock).get(); + doReturn(7L).when(totalSupplierMock).getAsLong(); Page page = PageableExecutionUtils.getPage(Arrays.asList(1, 2, 3), PageRequest.of(1, 3), totalSupplierMock); @@ -99,18 +100,18 @@ public class PageableExecutionUtilsUnitTests { assertThat(page).contains(1, 2, 3); assertThat(page.getTotalElements()).isEqualTo(7L); - verify(totalSupplierMock).get(); + verify(totalSupplierMock).getAsLong(); } @Test // DATAMCNS-884 public void subsequentPageRequestWithoutResultRequiresRequireTotal() { - doReturn(7L).when(totalSupplierMock).get(); - Page page = PageableExecutionUtils.getPage(Collections.emptyList(), new PageRequest(5, 10), + doReturn(7L).when(totalSupplierMock).getAsLong(); + Page page = PageableExecutionUtils.getPage(Collections.emptyList(), PageRequest.of(5, 10), totalSupplierMock); assertThat(page.getTotalElements()).isEqualTo(7L); - verify(totalSupplierMock).get(); + verify(totalSupplierMock).getAsLong(); } } diff --git a/src/test/java/org/springframework/data/repository/support/PaginginAndSortingRepositoryInvokerUnitTests.java b/src/test/java/org/springframework/data/repository/support/PaginginAndSortingRepositoryInvokerUnitTests.java index e17bd0876..856059322 100755 --- a/src/test/java/org/springframework/data/repository/support/PaginginAndSortingRepositoryInvokerUnitTests.java +++ b/src/test/java/org/springframework/data/repository/support/PaginginAndSortingRepositoryInvokerUnitTests.java @@ -45,8 +45,8 @@ public class PaginginAndSortingRepositoryInvokerUnitTests { Repository repository = mock(Repository.class); Method method = PagingAndSortingRepository.class.getMethod("findAll", Pageable.class); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(new PageRequest(0, 10)); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll((Pageable) null); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(PageRequest.of(0, 10)); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Pageable.NONE); } @Test // DATACMNS-589 @@ -55,8 +55,8 @@ public class PaginginAndSortingRepositoryInvokerUnitTests { Repository repository = mock(Repository.class); Method method = PagingAndSortingRepository.class.getMethod("findAll", Sort.class); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(new Sort("foo")); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll((Sort) null); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Sort.by("foo")); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Sort.unsorted()); } @Test // DATACMNS-589 @@ -65,8 +65,8 @@ public class PaginginAndSortingRepositoryInvokerUnitTests { RepositoryWithRedeclaredFindAllWithPageable repository = mock(RepositoryWithRedeclaredFindAllWithPageable.class); Method method = RepositoryWithRedeclaredFindAllWithPageable.class.getMethod("findAll", Pageable.class); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(new PageRequest(0, 10)); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll((Pageable) null); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(PageRequest.of(0, 10)); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Pageable.NONE); } @Test // DATACMNS-589 @@ -75,8 +75,8 @@ public class PaginginAndSortingRepositoryInvokerUnitTests { RepositoryWithRedeclaredFindAllWithSort repository = mock(RepositoryWithRedeclaredFindAllWithSort.class); Method method = RepositoryWithRedeclaredFindAllWithSort.class.getMethod("findAll", Sort.class); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(new Sort("foo")); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll((Sort) null); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Sort.by("foo")); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Sort.unsorted()); } @SuppressWarnings({ "unchecked", "rawtypes" }) diff --git a/src/test/java/org/springframework/data/repository/support/ReflectionRepositoryInvokerUnitTests.java b/src/test/java/org/springframework/data/repository/support/ReflectionRepositoryInvokerUnitTests.java index e93608938..e9eca353b 100755 --- a/src/test/java/org/springframework/data/repository/support/ReflectionRepositoryInvokerUnitTests.java +++ b/src/test/java/org/springframework/data/repository/support/ReflectionRepositoryInvokerUnitTests.java @@ -58,7 +58,7 @@ import org.springframework.util.MultiValueMap; @RunWith(MockitoJUnitRunner.class) public class ReflectionRepositoryInvokerUnitTests { - static final Page EMPTY_PAGE = new PageImpl(Collections. emptyList()); + static final Page EMPTY_PAGE = new PageImpl<>(Collections.emptyList()); ConversionService conversionService; @@ -104,10 +104,10 @@ public class ReflectionRepositoryInvokerUnitTests { Method method = ManualCrudRepository.class.getMethod("findAll"); ManualCrudRepository repository = mock(ManualCrudRepository.class); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll((Pageable) null); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(new PageRequest(0, 10)); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll((Sort) null); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(new Sort("foo")); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Pageable.NONE); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(PageRequest.of(0, 10)); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Sort.unsorted()); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Sort.by("foo")); } @Test // DATACMNS-589 @@ -116,10 +116,10 @@ public class ReflectionRepositoryInvokerUnitTests { Method method = RepoWithFindAllWithSort.class.getMethod("findAll", Sort.class); RepoWithFindAllWithSort repository = mock(RepoWithFindAllWithSort.class); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll((Pageable) null); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(new PageRequest(0, 10)); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll((Sort) null); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(new Sort("foo")); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Pageable.NONE); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(PageRequest.of(0, 10)); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Sort.unsorted()); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Sort.by("foo")); } @Test // DATACMNS-589 @@ -128,8 +128,8 @@ public class ReflectionRepositoryInvokerUnitTests { Method method = RepoWithFindAllWithPageable.class.getMethod("findAll", Pageable.class); RepoWithFindAllWithPageable repository = mock(RepoWithFindAllWithPageable.class); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll((Pageable) null); - getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(new PageRequest(0, 10)); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(Pageable.NONE); + getInvokerFor(repository, expectInvocationOf(method)).invokeFindAll(PageRequest.of(0, 10)); } @Test // DATACMNS-589 @@ -141,7 +141,8 @@ public class ReflectionRepositoryInvokerUnitTests { Method method = PersonRepository.class.getMethod("findByFirstName", String.class, Pageable.class); PersonRepository repository = mock(PersonRepository.class); - getInvokerFor(repository, expectInvocationOf(method)).invokeQueryMethod(method, parameters, null, null); + getInvokerFor(repository, expectInvocationOf(method)).invokeQueryMethod(method, parameters, Pageable.NONE, + Sort.unsorted()); } @Test // DATACMNS-589 @@ -153,7 +154,8 @@ public class ReflectionRepositoryInvokerUnitTests { Method method = PersonRepository.class.getMethod("findByCreatedUsingISO8601Date", Date.class, Pageable.class); PersonRepository repository = mock(PersonRepository.class); - getInvokerFor(repository, expectInvocationOf(method)).invokeQueryMethod(method, parameters, null, null); + getInvokerFor(repository, expectInvocationOf(method)).invokeQueryMethod(method, parameters, Pageable.NONE, + Sort.unsorted()); } @Test // DATAREST-335, DATAREST-346, DATACMNS-589 @@ -189,7 +191,7 @@ public class ReflectionRepositoryInvokerUnitTests { RepositoryInvoker invoker = getInvokerFor(mock(EmptyRepository.class)); assertThat(invoker.hasFindAllMethod()).isFalse(); - invoker.invokeFindAll((Pageable) null); + invoker.invokeFindAll(Sort.unsorted()); } @Test(expected = IllegalStateException.class) // DATACMNS-589 @@ -212,7 +214,8 @@ public class ReflectionRepositoryInvokerUnitTests { Method method = PersonRepository.class.getMethod("findByIdIn", Collection.class); PersonRepository repository = mock(PersonRepository.class); - getInvokerFor(repository, expectInvocationOf(method)).invokeQueryMethod(method, parameters, null, null); + getInvokerFor(repository, expectInvocationOf(method)).invokeQueryMethod(method, parameters, Pageable.NONE, + Sort.unsorted()); } } @@ -227,7 +230,7 @@ public class ReflectionRepositoryInvokerUnitTests { Method method = SimpleRepository.class.getMethod("findByClass", int.class); try { - invoker.invokeQueryMethod(method, parameters, null, null); + invoker.invokeQueryMethod(method, parameters, Pageable.NONE, Sort.unsorted()); } catch (QueryMethodParameterConversionException o_O) { assertThat(o_O.getParameter()).isEqualTo(new MethodParameters(method).getParameters().get(0)); diff --git a/src/test/java/org/springframework/data/repository/support/RepositoriesUnitTests.java b/src/test/java/org/springframework/data/repository/support/RepositoriesUnitTests.java index 1f35dc6b5..3fa4f7ee3 100755 --- a/src/test/java/org/springframework/data/repository/support/RepositoriesUnitTests.java +++ b/src/test/java/org/springframework/data/repository/support/RepositoriesUnitTests.java @@ -54,7 +54,7 @@ import org.springframework.util.ClassUtils; * @author Oliver Gierke * @author Thomas Darimont */ -@RunWith(MockitoJUnitRunner.class) +@RunWith(MockitoJUnitRunner.Silent.class) public class RepositoriesUnitTests { GenericApplicationContext context; @@ -174,7 +174,7 @@ public class RepositoriesUnitTests { } public PersistentEntity getPersistentEntity() { - return mappingContext.getPersistentEntity(repositoryMetadata.getDomainType()); + return mappingContext.getRequiredPersistentEntity(repositoryMetadata.getDomainType()); } public List getQueryMethods() { @@ -217,7 +217,7 @@ public class RepositoriesUnitTests { */ @Override public Set> getAlternativeDomainTypes() { - return Collections.> singleton(super.getDomainType()); + return Collections.>singleton(super.getDomainType()); } } diff --git a/src/test/java/org/springframework/data/util/AnnotationDetectionMethodCallbackUnitTests.java b/src/test/java/org/springframework/data/util/AnnotationDetectionMethodCallbackUnitTests.java index 2277d99bc..4f28c4f87 100755 --- a/src/test/java/org/springframework/data/util/AnnotationDetectionMethodCallbackUnitTests.java +++ b/src/test/java/org/springframework/data/util/AnnotationDetectionMethodCallbackUnitTests.java @@ -35,7 +35,7 @@ public class AnnotationDetectionMethodCallbackUnitTests { @Test // DATACMNS-452 public void findsMethodWithAnnotation() throws Exception { - AnnotationDetectionMethodCallback callback = new AnnotationDetectionMethodCallback(Value.class); + AnnotationDetectionMethodCallback callback = new AnnotationDetectionMethodCallback<>(Value.class); ReflectionUtils.doWithMethods(Sample.class, callback); assertThat(callback.hasFoundAnnotation()).isTrue(); @@ -52,7 +52,7 @@ public class AnnotationDetectionMethodCallbackUnitTests { exception.expectMessage("getValue"); exception.expectMessage("getOtherValue"); - AnnotationDetectionMethodCallback callback = new AnnotationDetectionMethodCallback(Value.class, true); + AnnotationDetectionMethodCallback callback = new AnnotationDetectionMethodCallback<>(Value.class, true); ReflectionUtils.doWithMethods(Multiple.class, callback); } diff --git a/src/test/java/org/springframework/data/util/ClassTypeInformationUnitTests.java b/src/test/java/org/springframework/data/util/ClassTypeInformationUnitTests.java index 847cf87b6..21da0b726 100755 --- a/src/test/java/org/springframework/data/util/ClassTypeInformationUnitTests.java +++ b/src/test/java/org/springframework/data/util/ClassTypeInformationUnitTests.java @@ -17,6 +17,7 @@ package org.springframework.data.util; import static org.assertj.core.api.Assertions.*; import static org.springframework.data.util.ClassTypeInformation.*; +import static org.springframework.data.util.OptionalAssert.*; import javaslang.collection.Traversable; @@ -45,26 +46,25 @@ public class ClassTypeInformationUnitTests { assertThat(discoverer.getType()).isEqualTo(ConcreteType.class); - TypeInformation content = discoverer.getProperty("content"); + OptionalAssert> assertThat = assertOptional(discoverer.getProperty("content")); - assertThat(content.getType()).isEqualTo(String.class); - assertThat(content.getComponentType()).isNull(); - assertThat(content.getMapValueType()).isNull(); + assertThat.value(it -> it.getType()).isEqualTo(String.class); + assertThat.flatMap(it -> it.getComponentType()).isNotPresent(); + assertThat.flatMap(it -> it.getMapValueType()).isNotPresent(); } @Test public void discoversTypeForNestedGenericField() { TypeInformation discoverer = ClassTypeInformation.from(ConcreteWrapper.class); - assertThat(discoverer.getType()).isEqualTo(ConcreteWrapper.class); - TypeInformation wrapper = discoverer.getProperty("wrapped"); - assertThat(wrapper.getType()).isEqualTo(GenericType.class); - TypeInformation content = wrapper.getProperty("content"); - assertThat(content.getType()).isEqualTo(String.class); - assertThat(discoverer.getProperty("wrapped").getProperty("content").getType()).isEqualTo(String.class); - assertThat(discoverer.getProperty("wrapped.content").getType()).isEqualTo(String.class); + assertOptional(discoverer.getProperty("wrapped")).andAssert(inner -> { + inner.value(it -> it.getType()).isEqualTo(GenericType.class); + inner.flatMap(it -> it.getProperty("content")).value(it -> it.getType()).isEqualTo(String.class); + }); + + assertOptional(discoverer.getProperty("wrapped.content")).value(it -> it.getType()).isEqualTo(String.class); } @Test @@ -72,7 +72,7 @@ public class ClassTypeInformationUnitTests { public void discoversBoundType() { TypeInformation information = ClassTypeInformation.from(GenericTypeWithBound.class); - assertThat(information.getProperty("person").getType()).isEqualTo(Person.class); + assertOptional(information.getProperty("person")).value(it -> it.getType()).isEqualTo(Person.class); } @Test @@ -80,7 +80,7 @@ public class ClassTypeInformationUnitTests { TypeInformation information = ClassTypeInformation .from(SpecialGenericTypeWithBound.class); - assertThat(information.getProperty("person").getType()).isEqualTo(SpecialPerson.class); + assertOptional(information.getProperty("person")).value(it -> it.getType()).isEqualTo(SpecialPerson.class); } @Test @@ -88,43 +88,52 @@ public class ClassTypeInformationUnitTests { public void discoversBoundTypeForNested() { TypeInformation information = ClassTypeInformation.from(AnotherGenericType.class); - assertThat(information.getProperty("nested").getType()).isEqualTo(GenericTypeWithBound.class); - assertThat(information.getProperty("nested.person").getType()).isEqualTo(Person.class); + + assertOptional(information.getProperty("nested")).value(it -> it.getType()).isEqualTo(GenericTypeWithBound.class); + assertOptional(information.getProperty("nested.person")).value(it -> it.getType()).isEqualTo(Person.class); } @Test public void discoversArraysAndCollections() { + TypeInformation information = ClassTypeInformation.from(StringCollectionContainer.class); - TypeInformation property = information.getProperty("array"); - assertThat(property.getComponentType().getType()).isEqualTo(String.class); + OptionalAssert> optional = assertOptional(information.getProperty("array")); - Class type = property.getType(); - assertThat(type).isEqualTo(String[].class); - assertThat(type.isArray()).isTrue(); + optional.flatMap(it -> it.getComponentType()).value(it -> it.getType()).isEqualTo(String.class); + optional.value(it -> it.getType()).satisfies(it -> { + assertThat(it).isEqualTo(String[].class); + assertThat(it.isArray()).isTrue(); + }); - property = information.getProperty("foo"); - assertThat(property.getType()).isEqualTo(Collection[].class); - assertThat(property.getComponentType().getType()).isEqualTo(Collection.class); - assertThat(property.getComponentType().getComponentType().getType()).isEqualTo(String.class); + optional = assertOptional(information.getProperty("foo")); - property = information.getProperty("rawSet"); - assertThat(property.getType()).isEqualTo(Set.class); - assertThat(property.getComponentType().getType()).isEqualTo(Object.class); - assertThat(property.getMapValueType()).isNull(); + optional.value(it -> it.getType()).isEqualTo(Collection[].class); + optional.flatMap(it -> it.getComponentType()).andAssert(it -> { + it.value(inner -> inner.getType()).isEqualTo(Collection.class); + it.flatMap(inner -> inner.getComponentType()).value(inner -> inner.getType()).isEqualTo(String.class); + }); + + optional = assertOptional(information.getProperty("rawSet")); + + optional.value(it -> it.getType()).isEqualTo(Set.class); + optional.flatMap(it -> it.getComponentType()).value(it -> it.getType()).isEqualTo(Object.class); + optional.flatMap(it -> it.getMapValueType()).isNotPresent(); } @Test public void discoversMapValueType() { TypeInformation information = ClassTypeInformation.from(StringMapContainer.class); - TypeInformation genericMap = information.getProperty("genericMap"); - assertThat(genericMap.getType()).isEqualTo(Map.class); - assertThat(genericMap.getMapValueType().getType()).isEqualTo(String.class); + OptionalAssert> assertion = assertOptional(information.getProperty("genericMap")); + + assertion.value(it -> it.getType()).isEqualTo(Map.class); + assertion.flatMap(it -> it.getMapValueType()).value(it -> it.getType()).isEqualTo(String.class); + + assertion = assertOptional(information.getProperty("map")); - TypeInformation map = information.getProperty("map"); - assertThat(map.getType()).isEqualTo(Map.class); - assertThat(map.getMapValueType().getType()).isEqualTo(Calendar.class); + assertion.value(it -> it.getType()).isEqualTo(Map.class); + assertion.flatMap(it -> it.getMapValueType()).value(it -> it.getType()).isEqualTo(Calendar.class); } @Test @@ -141,13 +150,8 @@ public class ClassTypeInformationUnitTests { TypeInformation from = ClassTypeInformation.from(PropertyGetter.class); - TypeInformation property = from.getProperty("_name"); - assertThat(property).isNotNull(); - assertThat(property.getType()).isEqualTo(String.class); - - property = from.getProperty("name"); - assertThat(property).isNotNull(); - assertThat(property.getType()).isEqualTo(byte[].class); + assertOptional(from.getProperty("_name")).value(it -> it.getType()).isEqualTo(String.class); + assertOptional(from.getProperty("name")).value(it -> it.getType()).isEqualTo(byte[].class); } @Test // DATACMNS-77 @@ -162,16 +166,18 @@ public class ClassTypeInformationUnitTests { TypeInformation information = ClassTypeInformation.from(ClassWithWildCardBound.class); - TypeInformation property = information.getProperty("wildcard"); - assertThat(property.isCollectionLike()).isTrue(); - assertThat(property.getComponentType().getType()).isEqualTo(String.class); + OptionalAssert> assertion = assertOptional(information.getProperty("wildcard")); + + assertion.value(it -> it.isCollectionLike()).isEqualTo(true); + assertion.flatMap(it -> it.getComponentType()).value(it -> it.getType()).isEqualTo(String.class); - property = information.getProperty("complexWildcard"); - assertThat(property.isCollectionLike()).isTrue(); + assertion = assertOptional(information.getProperty("complexWildcard")); - TypeInformation component = property.getComponentType(); - assertThat(component.isCollectionLike()).isTrue(); - assertThat(component.getComponentType().getType()).isEqualTo(String.class); + assertion.value(it -> it.isCollectionLike()).isEqualTo(true); + assertion.flatMap(it -> it.getComponentType()).andAssert(it -> { + it.value(inner -> inner.isCollectionLike()).isEqualTo(true); + it.flatMap(inner -> inner.getComponentType()).value(inner -> inner.getType()).isEqualTo(String.class); + }); } @Test @@ -258,8 +264,9 @@ public class ClassTypeInformationUnitTests { public void returnsComponentTypeForMultiDimensionalArrayCorrectly() { TypeInformation information = from(String[][].class); + assertThat(information.getType()).isEqualTo(String[][].class); - assertThat(information.getComponentType().getType()).isEqualTo(String[].class); + assertOptional(information.getComponentType()).value(it -> it.getType()).isEqualTo(String[].class); assertThat(information.getActualType().getActualType().getType()).isEqualTo(String.class); } @@ -268,10 +275,8 @@ public class ClassTypeInformationUnitTests { public void findsGetterOnInterface() { TypeInformation information = from(Product.class); - TypeInformation categoryIdInfo = information.getProperty("category.id"); - assertThat(categoryIdInfo).isNotNull(); - assertThat(categoryIdInfo).isEqualTo((TypeInformation) from(Long.class)); + assertOptional(information.getProperty("category.id")).hasValue(from(Long.class)); } @Test(expected = IllegalArgumentException.class) // DATACMNS-387 @@ -280,27 +285,32 @@ public class ClassTypeInformationUnitTests { } @Test // DATACMNS-422 - public void returnsNullForRawTypesOnly() { + public void returnsEmptyOptionalForRawTypesOnly() { - assertThat(from(MyRawIterable.class).getComponentType()).isNull(); - assertThat(from(MyIterable.class).getComponentType()).isNotNull(); + assertThat(from(MyRawIterable.class).getComponentType()).isNotPresent(); + assertThat(from(MyIterable.class).getComponentType()).isPresent(); } @Test // DATACMNS-440 public void detectsSpecialMapAsMapValueType() { - TypeInformation information = ClassTypeInformation.from(SuperGenerics.class); + OptionalAssert> assertion = assertOptional( + ClassTypeInformation.from(SuperGenerics.class).getProperty("seriously")); - TypeInformation propertyInformation = information.getProperty("seriously"); - assertThat(propertyInformation.getType()).isEqualTo(SortedMap.class); + assertion// + // Type + .andAssert(inner -> inner.value(it -> it.getType()).isEqualTo(SortedMap.class))// - TypeInformation mapValueType = propertyInformation.getMapValueType(); - assertThat(mapValueType.getType()).isEqualTo(SortedMap.class); - assertThat(mapValueType.getComponentType().getType()).isEqualTo(String.class); + // Map value type + .andAssert(inner -> inner.flatMap(it -> it.getMapValueType()).andAssert(value -> { + value.value(it -> it.getType()).isEqualTo(SortedMap.class); + value.flatMap(it -> it.getComponentType()).value(it -> it.getType()).isEqualTo(String.class); - TypeInformation nestedValueType = mapValueType.getMapValueType(); - assertThat(nestedValueType.getType()).isEqualTo(List.class); - assertThat(nestedValueType.getComponentType().getType()).isEqualTo(Person.class); + // Nested value type + }).flatMap(it -> it.getMapValueType()).andAssert(nestedValue -> { + nestedValue.value(it -> it.getType()).isEqualTo(List.class); + nestedValue.flatMap(it -> it.getComponentType()).value(it -> it.getType()).isEqualTo(Person.class); + })); } @Test // DATACMNS-446 @@ -313,33 +323,33 @@ public class ClassTypeInformationUnitTests { public void resolvesNestedGenericsToConcreteType() { ClassTypeInformation rootType = from(ConcreteRoot.class); - TypeInformation subsPropertyType = rootType.getProperty("subs"); - TypeInformation subsElementType = subsPropertyType.getActualType(); - TypeInformation subSubType = subsElementType.getProperty("subSub"); - assertThat(subSubType.getType()).isEqualTo(ConcreteSubSub.class); + assertOptional(rootType.getProperty("subs"))// + .map(it -> it.getActualType())// + .flatMap(it -> it.getProperty("subSub"))// + .value(it -> it.getType()).isEqualTo(ConcreteSubSub.class); } @Test // DATACMNS-594 public void considersGenericsOfTypeBounds() { - ClassTypeInformation customer = ClassTypeInformation.from(ConcreteRootIntermediate.class); - TypeInformation leafType = customer.getProperty("intermediate.content.intermediate.content"); - - assertThat(leafType.getType()).isEqualTo(Leaf.class); + assertOptional(ClassTypeInformation.from(ConcreteRootIntermediate.class) + .getProperty("intermediate.content.intermediate.content"))// + .value(it -> it.getType()).isEqualTo(Leaf.class); } @Test // DATACMNS-783, DATACMNS-853 public void specializesTypeUsingTypeVariableContext() { ClassTypeInformation root = ClassTypeInformation.from(Foo.class); - TypeInformation property = root.getProperty("abstractBar"); - TypeInformation specialized = property.specialize(ClassTypeInformation.from(Bar.class)); - - assertThat(specialized.getType()).isEqualTo(Bar.class); - assertThat(specialized.getProperty("field").getType()).isEqualTo(Character.class); - assertThat(specialized.getProperty("anotherField").getType()).isEqualTo(Integer.class); + assertOptional(root.getProperty("abstractBar"))// + .map(it -> it.specialize(ClassTypeInformation.from(Bar.class)))// + .andAssert(inner -> { + inner.value(it -> it.getType()).isEqualTo(Bar.class); + inner.flatMap(it -> it.getProperty("field")).value(it -> it.getType()).isEqualTo(Character.class); + inner.flatMap(it -> it.getProperty("anotherField")).value(it -> it.getType()).isEqualTo(Integer.class); + }); } @Test // DATACMNS-783 @@ -347,10 +357,9 @@ public class ClassTypeInformationUnitTests { public void usesTargetTypeDirectlyIfNoGenericsAreInvolved() { ClassTypeInformation root = ClassTypeInformation.from(Foo.class); - TypeInformation property = root.getProperty("object"); - ClassTypeInformation from = ClassTypeInformation.from(Bar.class); - assertThat(property.specialize(from)).isEqualTo((TypeInformation) from); + + assertOptional(root.getProperty("object")).value(it -> it.specialize(from)).isEqualTo(from); } @Test // DATACMNS-855 @@ -358,14 +367,17 @@ public class ClassTypeInformationUnitTests { public void specializedTypeEqualsAndHashCode() { ClassTypeInformation root = ClassTypeInformation.from(Foo.class); - TypeInformation property = root.getProperty("abstractBar"); - TypeInformation left = property.specialize(ClassTypeInformation.from(Bar.class)); - TypeInformation right = property.specialize(ClassTypeInformation.from(Bar.class)); + OptionalAssert> assertion = assertOptional(root.getProperty("abstractBar")); - assertThat(left).isEqualTo(right); - assertThat(right).isEqualTo(left); - assertThat(left.hashCode()).isEqualTo(right.hashCode()); + assertion + .map(it -> Pair.of(it.specialize(ClassTypeInformation.from(Bar.class)), + it.specialize(ClassTypeInformation.from(Bar.class))))// + .hasValueSatisfying(pair -> { + assertThat(pair.getFirst()).isEqualTo(pair.getSecond()); + assertThat(pair.getSecond()).isEqualTo(pair.getFirst()); + assertThat(pair.getFirst().hashCode()).isEqualTo(pair.getSecond().hashCode()); + }); } @Test // DATACMNS-896 @@ -373,7 +385,7 @@ public class ClassTypeInformationUnitTests { ClassTypeInformation information = ClassTypeInformation.from(Concrete.class); - assertThat(information.getProperty("field").getType()).isEqualTo(Nested.class); + assertOptional(information.getProperty("field")).value(it -> it.getType()).isEqualTo(Nested.class); } @Test // DATACMNS-940 diff --git a/src/test/java/org/springframework/data/util/DataCmns511Tests.java b/src/test/java/org/springframework/data/util/DataCmns511Tests.java index 6395ce794..015fe7134 100755 --- a/src/test/java/org/springframework/data/util/DataCmns511Tests.java +++ b/src/test/java/org/springframework/data/util/DataCmns511Tests.java @@ -15,7 +15,7 @@ */ package org.springframework.data.util; -import static org.assertj.core.api.Assertions.*; +import static org.springframework.data.util.OptionalAssert.*; import java.util.HashSet; import java.util.Set; @@ -33,26 +33,32 @@ public class DataCmns511Tests { @SuppressWarnings("rawtypes") public void detectsEqualTypeVariableTypeInformationInstances() { - TypeInformation firstRoleType = ClassTypeInformation.from(AbstractRole.class); - TypeInformation firstCreatedBy = firstRoleType.getProperty("createdBy"); - TypeInformation secondRoleType = firstCreatedBy.getProperty("roles").getActualType(); - TypeInformation secondCreatedBy = secondRoleType.getProperty("createdBy"); - TypeInformation thirdRoleType = secondCreatedBy.getProperty("roles").getActualType(); - TypeInformation thirdCreatedBy = thirdRoleType.getProperty("createdBy"); + OptionalAssert> assertion = assertOptional( + ClassTypeInformation.from(AbstractRole.class).getProperty("createdBy")); - assertThat(secondCreatedBy).isEqualTo(thirdCreatedBy); - assertThat(secondCreatedBy.hashCode()).isEqualTo(thirdCreatedBy.hashCode()); + assertion.flatMap(it -> it.getProperty("roles"))// + .map(it -> it.getActualType())// + .flatMap(it -> it.getProperty("createdBy"))// + .andAssert(second -> { + + OptionalAssert> third = second.flatMap(it -> it.getProperty("roles"))// + .map(it -> it.getActualType())// + .flatMap(it -> it.getProperty("createdBy")); + + second.isEqualTo(third); + second.value(it -> it.hashCode()).isEqualTo(third.getActual().hashCode()); + }); } - static class AbstractRole, ROLE extends AbstractRole> extends - AuditingEntity { + static class AbstractRole, ROLE extends AbstractRole> + extends AuditingEntity { String name; } static abstract class AbstractUser, ROLE extends AbstractRole> { - Set roles = new HashSet(); + Set roles = new HashSet<>(); } static abstract class AuditingEntity> { diff --git a/src/test/java/org/springframework/data/util/OptionalAssert.java b/src/test/java/org/springframework/data/util/OptionalAssert.java new file mode 100644 index 000000000..a1f59b7fe --- /dev/null +++ b/src/test/java/org/springframework/data/util/OptionalAssert.java @@ -0,0 +1,79 @@ +/* + * Copyright 2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.util; + +import lombok.EqualsAndHashCode; + +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Function; + +import org.assertj.core.api.AbstractObjectAssert; +import org.assertj.core.api.Assertions; + +/** + * @author Oliver Gierke + */ +@EqualsAndHashCode(callSuper = true) +public class OptionalAssert extends org.assertj.core.api.OptionalAssert { + + public OptionalAssert(Optional actual) { + super(actual); + } + + public static OptionalAssert assertOptional(Optional optional) { + return new OptionalAssert(optional); + } + + public Optional getActual() { + return actual; + } + + public OptionalAssert flatMap(Function> function) { + + Assertions.assertThat(actual).isPresent(); + + return assertOptional(actual.flatMap(function)); + } + + public OptionalAssert map(Function function) { + + Assertions.assertThat(actual).isPresent(); + + return assertOptional(actual.map(function)); + } + + public AbstractObjectAssert value(Function function) { + + Assertions.assertThat(actual).isPresent(); + + return Assertions.assertThat(actual.map(function).orElseThrow(() -> new IllegalStateException())); + } + + public OptionalAssert isEqualTo(OptionalAssert other) { + + Assertions.assertThat(actual).isEqualTo(other.actual); + + return this; + } + + public OptionalAssert andAssert(Consumer> consumer) { + + consumer.accept(this); + + return this; + } +} diff --git a/src/test/java/org/springframework/data/util/ParameterizedTypeUnitTests.java b/src/test/java/org/springframework/data/util/ParameterizedTypeUnitTests.java index 09a4af9c4..744826ac9 100755 --- a/src/test/java/org/springframework/data/util/ParameterizedTypeUnitTests.java +++ b/src/test/java/org/springframework/data/util/ParameterizedTypeUnitTests.java @@ -18,6 +18,7 @@ package org.springframework.data.util; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; import static org.springframework.data.util.ClassTypeInformation.*; +import static org.springframework.data.util.OptionalAssert.*; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; @@ -27,6 +28,7 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Optional; import org.junit.Before; import org.junit.Test; @@ -55,8 +57,8 @@ public class ParameterizedTypeUnitTests { @Test public void considersTypeInformationsWithDifferingParentsNotEqual() { - TypeDiscoverer stringParent = new TypeDiscoverer(String.class, EMPTY_MAP); - TypeDiscoverer objectParent = new TypeDiscoverer(Object.class, EMPTY_MAP); + TypeDiscoverer stringParent = new TypeDiscoverer<>(String.class, EMPTY_MAP); + TypeDiscoverer objectParent = new TypeDiscoverer<>(Object.class, EMPTY_MAP); ParameterizedTypeInformation first = new ParameterizedTypeInformation<>(one, stringParent, EMPTY_MAP); ParameterizedTypeInformation second = new ParameterizedTypeInformation<>(one, objectParent, EMPTY_MAP); @@ -67,7 +69,7 @@ public class ParameterizedTypeUnitTests { @Test public void considersTypeInformationsWithSameParentsNotEqual() { - TypeDiscoverer stringParent = new TypeDiscoverer(String.class, EMPTY_MAP); + TypeDiscoverer stringParent = new TypeDiscoverer<>(String.class, EMPTY_MAP); ParameterizedTypeInformation first = new ParameterizedTypeInformation<>(one, stringParent, EMPTY_MAP); ParameterizedTypeInformation second = new ParameterizedTypeInformation<>(one, stringParent, EMPTY_MAP); @@ -79,19 +81,23 @@ public class ParameterizedTypeUnitTests { public void resolvesMapValueTypeCorrectly() { TypeInformation type = ClassTypeInformation.from(Foo.class); - TypeInformation propertyType = type.getProperty("param"); - assertThat(propertyType.getProperty("value").getType()).isEqualTo(String.class); - assertThat(propertyType.getMapValueType().getType()).isEqualTo(String.class); + Optional> propertyType = type.getProperty("param"); + + OptionalAssert> assertion = assertOptional(propertyType); + + assertion.flatMap(it -> it.getProperty("value")).value(it -> it.getType()).isEqualTo(String.class); + assertion.flatMap(it -> it.getMapValueType()).value(it -> it.getType()).isEqualTo(String.class); propertyType = type.getProperty("param2"); - assertThat(propertyType.getProperty("value").getType()).isEqualTo(String.class); - assertThat(propertyType.getMapValueType().getType()).isEqualTo(Locale.class); + + assertion.flatMap(it -> it.getProperty("value")).value(it -> it.getType()).isEqualTo(String.class); + assertion.flatMap(it -> it.getMapValueType()).value(it -> it.getType()).isEqualTo(String.class); } @Test // DATACMNS-446 public void createsToStringRepresentation() { - assertThat(from(Foo.class).getProperty("param").toString()) + assertOptional(from(Foo.class).getProperty("param")).value(it -> it.toString()) .isEqualTo("org.springframework.data.util.ParameterizedTypeUnitTests$Localized"); } @@ -99,37 +105,47 @@ public class ParameterizedTypeUnitTests { @SuppressWarnings("rawtypes") public void hashCodeShouldBeConsistentWithEqualsForResolvedTypes() { - TypeInformation first = from(First.class).getProperty("property"); - TypeInformation second = from(Second.class).getProperty("property"); + Optional> first = from(First.class).getProperty("property"); + Optional> second = from(Second.class).getProperty("property"); assertThat(first).isEqualTo(second); - assertThat(first.hashCode()).isEqualTo(second.hashCode()); + + assertThat(first).hasValueSatisfying(left -> { + assertThat(second).hasValueSatisfying(right -> { + assertThat(left.hashCode()).isEqualTo(right.hashCode()); + }); + }); } @Test // DATACMNS-485 @SuppressWarnings("rawtypes") public void getActualTypeShouldNotUnwrapParameterizedTypes() { - TypeInformation type = from(First.class).getProperty("property"); - assertThat(type.getActualType()).isEqualTo(type); + Optional> type = from(First.class).getProperty("property"); + + assertOptional(type).map(it -> it.getActualType()).isEqualTo(type); } @Test // DATACMNS-697 public void usesLocalGenericInformationOfFields() { TypeInformation information = ClassTypeInformation.from(NormalizedProfile.class); - TypeInformation valueType = information.getProperty("education2.data").getComponentType(); - assertThat(valueType.getProperty("value").getType()).isEqualTo(Education.class); + + assertOptional(information.getProperty("education2.data"))// + .flatMap(it -> it.getComponentType())// + .flatMap(it -> it.getProperty("value"))// + .value(it -> it.getType())// + .isEqualTo(Education.class); } @Test // DATACMNS-899 - public void returnsNullMapValueTypeForNonMapProperties() { + public void returnsEmptyOptionalMapValueTypeForNonMapProperties() { - TypeInformation valueType = ClassTypeInformation.from(Bar.class).getProperty("param"); - TypeInformation mapValueType = valueType.getMapValueType(); + OptionalAssert> assertion = assertOptional( + ClassTypeInformation.from(Bar.class).getProperty("param")); - assertThat(valueType).isInstanceOf(ParameterizedTypeInformation.class); - assertThat(mapValueType).isNull(); + assertion.hasValueSatisfying(it -> assertThat(it).isInstanceOf(ParameterizedTypeInformation.class)); + assertion.flatMap(it -> it.getMapValueType()).isEmpty(); } @SuppressWarnings("serial") diff --git a/src/test/java/org/springframework/data/util/TypeDiscovererUnitTests.java b/src/test/java/org/springframework/data/util/TypeDiscovererUnitTests.java index dab374097..6049c7f16 100755 --- a/src/test/java/org/springframework/data/util/TypeDiscovererUnitTests.java +++ b/src/test/java/org/springframework/data/util/TypeDiscovererUnitTests.java @@ -26,6 +26,7 @@ import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Optional; import org.junit.Test; import org.junit.runner.RunWith; @@ -47,14 +48,14 @@ public class TypeDiscovererUnitTests { @Test(expected = IllegalArgumentException.class) public void rejectsNullType() { - new TypeDiscoverer(null, null); + new TypeDiscoverer<>(null, null); } @Test public void isNotEqualIfTypesDiffer() { - TypeDiscoverer objectTypeInfo = new TypeDiscoverer(Object.class, EMPTY_MAP); - TypeDiscoverer stringTypeInfo = new TypeDiscoverer(String.class, EMPTY_MAP); + TypeDiscoverer objectTypeInfo = new TypeDiscoverer<>(Object.class, EMPTY_MAP); + TypeDiscoverer stringTypeInfo = new TypeDiscoverer<>(String.class, EMPTY_MAP); assertThat(objectTypeInfo.equals(stringTypeInfo)).isFalse(); } @@ -64,8 +65,8 @@ public class TypeDiscovererUnitTests { assertThat(firstMap.equals(secondMap)).isFalse(); - TypeDiscoverer first = new TypeDiscoverer(Object.class, firstMap); - TypeDiscoverer second = new TypeDiscoverer(Object.class, secondMap); + TypeDiscoverer first = new TypeDiscoverer<>(Object.class, firstMap); + TypeDiscoverer second = new TypeDiscoverer<>(Object.class, secondMap); assertThat(first.equals(second)).isFalse(); } @@ -74,8 +75,9 @@ public class TypeDiscovererUnitTests { public void dealsWithTypesReferencingThemselves() { TypeInformation information = from(SelfReferencing.class); - TypeInformation first = information.getProperty("parent").getMapValueType(); - TypeInformation second = first.getProperty("map").getMapValueType(); + Optional> first = information.getProperty("parent").flatMap(it -> it.getMapValueType()); + Optional> second = first.flatMap(it -> it.getProperty("map")) + .flatMap(it -> it.getMapValueType()); assertThat(second).isEqualTo(first); } @@ -84,27 +86,35 @@ public class TypeDiscovererUnitTests { public void dealsWithTypesReferencingThemselvesInAMap() { TypeInformation information = from(SelfReferencingMap.class); - TypeInformation mapValueType = information.getProperty("map").getMapValueType(); + Optional> property = information.getProperty("map"); - assertThat(information).isEqualTo(mapValueType); + assertThat(property).hasValueSatisfying(it -> { + assertThat(it.getMapValueType()).hasValue(information); + }); } @Test public void returnsComponentAndValueTypesForMapExtensions() { - TypeInformation discoverer = new TypeDiscoverer(CustomMap.class, EMPTY_MAP); + TypeInformation discoverer = new TypeDiscoverer<>(CustomMap.class, EMPTY_MAP); - assertThat(discoverer.getMapValueType().getType()).isEqualTo(Locale.class); - assertThat(discoverer.getComponentType().getType()).isEqualTo(String.class); + assertThat(discoverer.getMapValueType()).hasValueSatisfying(it -> { + assertThat(it.getType()).isEqualTo(Locale.class); + }); + + assertThat(discoverer.getComponentType()).hasValueSatisfying(it -> { + assertThat(it.getType()).isEqualTo(String.class); + }); } @Test public void returnsComponentTypeForCollectionExtension() { - TypeDiscoverer discoverer = new TypeDiscoverer(CustomCollection.class, - firstMap); + TypeDiscoverer discoverer = new TypeDiscoverer<>(CustomCollection.class, firstMap); - assertThat(discoverer.getComponentType().getType()).isEqualTo(String.class); + assertThat(discoverer.getComponentType()).hasValueSatisfying(it -> { + assertThat(it.getType()).isEqualTo(String.class); + }); } @Test @@ -112,49 +122,56 @@ public class TypeDiscovererUnitTests { TypeDiscoverer discoverer = new TypeDiscoverer(String[].class, EMPTY_MAP); - assertThat(discoverer.getComponentType().getType()).isEqualTo(String.class); + assertThat(discoverer.getComponentType()).hasValueSatisfying(it -> { + assertThat(it.getType()).isEqualTo(String.class); + }); } @Test // DATACMNS-57 @SuppressWarnings("rawtypes") public void discoveresConstructorParameterTypesCorrectly() throws NoSuchMethodException, SecurityException { - TypeDiscoverer discoverer = new TypeDiscoverer(GenericConstructors.class, - firstMap); + TypeDiscoverer discoverer = new TypeDiscoverer<>(GenericConstructors.class, firstMap); Constructor constructor = GenericConstructors.class.getConstructor(List.class, Locale.class); List> types = discoverer.getParameterTypes(constructor); assertThat(types).hasSize(2); assertThat(types.get(0).getType()).isEqualTo(List.class); - assertThat(types.get(0).getComponentType().getType()).isEqualTo(String.class); + assertThat(types.get(0).getComponentType()).hasValueSatisfying(it -> { + assertThat(it.getType()).isEqualTo(String.class); + }); } @Test @SuppressWarnings("rawtypes") public void returnsNullForComponentAndValueTypesForRawMaps() { - TypeDiscoverer discoverer = new TypeDiscoverer(Map.class, EMPTY_MAP); + TypeDiscoverer discoverer = new TypeDiscoverer<>(Map.class, EMPTY_MAP); - assertThat(discoverer.getComponentType()).isNull(); - assertThat(discoverer.getMapValueType()).isNull(); + assertThat(discoverer.getComponentType()).isEmpty(); + assertThat(discoverer.getMapValueType()).isEmpty(); } @Test // DATACMNS-167 @SuppressWarnings("rawtypes") public void doesNotConsiderTypeImplementingIterableACollection() { - TypeDiscoverer discoverer = new TypeDiscoverer(Person.class, EMPTY_MAP); + TypeDiscoverer discoverer = new TypeDiscoverer<>(Person.class, EMPTY_MAP); TypeInformation reference = from(Address.class); - TypeInformation addresses = discoverer.getProperty("addresses"); + Optional> addresses = discoverer.getProperty("addresses"); - assertThat(addresses.isCollectionLike()).isFalse(); - assertThat(addresses.getComponentType()).isEqualTo(reference); + assertThat(addresses).hasValueSatisfying(it -> { + assertThat(it.isCollectionLike()).isFalse(); + assertThat(it.getComponentType()).hasValue(reference); + }); - TypeInformation adressIterable = discoverer.getProperty("addressIterable"); + Optional> adressIterable = discoverer.getProperty("addressIterable"); - assertThat(adressIterable.isCollectionLike()).isTrue(); - assertThat(adressIterable.getComponentType()).isEqualTo(reference); + assertThat(adressIterable).hasValueSatisfying(it -> { + assertThat(it.isCollectionLike()).isTrue(); + assertThat(it.getComponentType()).hasValue(reference); + }); } class Person { diff --git a/src/test/java/org/springframework/data/util/TypeInformationAssert.java b/src/test/java/org/springframework/data/util/TypeInformationAssert.java new file mode 100644 index 000000000..0946b0256 --- /dev/null +++ b/src/test/java/org/springframework/data/util/TypeInformationAssert.java @@ -0,0 +1,41 @@ +package org.springframework.data.util; + +import java.util.Optional; + +import org.assertj.core.api.AbstractAssert; +import org.assertj.core.api.AbstractObjectAssert; +import org.assertj.core.api.Assertions; + +public class TypeInformationAssert extends AbstractAssert> { + + /** + * @param actual + * @param selfType + */ + public TypeInformationAssert(TypeInformation actual) { + super(actual, TypeInformationAssert.class); + } + + public static TypeInformationAssert assertThat(TypeInformation information) { + return new TypeInformationAssert(information); + } + + public TypeInformationAssert hasComponentType(Class type) { + + Assertions.assertThat(actual.getComponentType()).hasValueSatisfying(it -> { + Assertions.assertThat(it.getType()).isEqualTo(type); + }); + + return this; + } + + public AbstractObjectAssert> hasProperty(String property) { + + Optional> property2 = actual.getProperty(property); + + return Assertions.assertThat(property2.orElseGet(() -> { + failWithMessage("Property %s not found!", property); + return null; + })); + } +} diff --git a/src/test/java/org/springframework/data/web/HateoasPageableHandlerMethodArgumentResolverUnitTests.java b/src/test/java/org/springframework/data/web/HateoasPageableHandlerMethodArgumentResolverUnitTests.java index 5c74920a5..a0a5981a9 100755 --- a/src/test/java/org/springframework/data/web/HateoasPageableHandlerMethodArgumentResolverUnitTests.java +++ b/src/test/java/org/springframework/data/web/HateoasPageableHandlerMethodArgumentResolverUnitTests.java @@ -52,7 +52,7 @@ public class HateoasPageableHandlerMethodArgumentResolverUnitTests MethodParameter parameter = new MethodParameter(Sample.class.getMethod("supportedMethod", Pageable.class), 0); UriComponentsContributor resolver = new HateoasPageableHandlerMethodArgumentResolver(); UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://localhost:8080?page=0&size=10"); - resolver.enhance(builder, parameter, new PageRequest(1, 20)); + resolver.enhance(builder, parameter, PageRequest.of(1, 20)); MultiValueMap params = builder.build().getQueryParams(); @@ -67,7 +67,7 @@ public class HateoasPageableHandlerMethodArgumentResolverUnitTests @Test // DATACMNS-335 public void preventsPageSizeFromExceedingMayValueIfConfiguredOnWrite() throws Exception { - assertUriStringFor(new PageRequest(0, 200), "page=0&size=100"); + assertUriStringFor(PageRequest.of(0, 200), "page=0&size=100"); } @Test // DATACMNS-418 @@ -101,7 +101,7 @@ public class HateoasPageableHandlerMethodArgumentResolverUnitTests UriComponentsBuilder builder = UriComponentsBuilder.fromPath("/"); - resolver.enhance(builder, null, new PageRequest(0, 10)); + resolver.enhance(builder, null, PageRequest.of(0, 10)); MultiValueMap params = builder.build().getQueryParams(); diff --git a/src/test/java/org/springframework/data/web/JsonProjectingMethodInterceptorFactoryUnitTests.java b/src/test/java/org/springframework/data/web/JsonProjectingMethodInterceptorFactoryUnitTests.java index e3adcf90d..910312f6f 100755 --- a/src/test/java/org/springframework/data/web/JsonProjectingMethodInterceptorFactoryUnitTests.java +++ b/src/test/java/org/springframework/data/web/JsonProjectingMethodInterceptorFactoryUnitTests.java @@ -15,7 +15,6 @@ */ package org.springframework.data.web; -import static org.hamcrest.Matchers.*; import static org.assertj.core.api.Assertions.*; import lombok.AllArgsConstructor; diff --git a/src/test/java/org/springframework/data/web/MapDataBinderUnitTests.java b/src/test/java/org/springframework/data/web/MapDataBinderUnitTests.java index 3a9756b1f..58b1e3f33 100755 --- a/src/test/java/org/springframework/data/web/MapDataBinderUnitTests.java +++ b/src/test/java/org/springframework/data/web/MapDataBinderUnitTests.java @@ -64,7 +64,7 @@ public class MapDataBinderUnitTests { Map result = bind(values); - List list = new ArrayList(); + List list = new ArrayList<>(); list.add("String"); assertThat(result).isEqualTo((Map) singletonMap("foo", singletonMap("bar", singletonMap("fooBar", list)))); diff --git a/src/test/java/org/springframework/data/web/PageableDefaultUnitTests.java b/src/test/java/org/springframework/data/web/PageableDefaultUnitTests.java index fea396186..06f5990b2 100755 --- a/src/test/java/org/springframework/data/web/PageableDefaultUnitTests.java +++ b/src/test/java/org/springframework/data/web/PageableDefaultUnitTests.java @@ -48,10 +48,10 @@ public abstract class PageableDefaultUnitTests { static final int PAGE_SIZE = 47; static final int PAGE_NUMBER = 23; - static final AbstractPageRequest REFERENCE_WITHOUT_SORT = new PageRequest(PAGE_NUMBER, PAGE_SIZE); - static final AbstractPageRequest REFERENCE_WITH_SORT = new PageRequest(PAGE_NUMBER, PAGE_SIZE, SORT); - static final AbstractPageRequest REFERENCE_WITH_SORT_FIELDS = new PageRequest(PAGE_NUMBER, PAGE_SIZE, new Sort( - SORT_FIELDS)); + static final AbstractPageRequest REFERENCE_WITHOUT_SORT = PageRequest.of(PAGE_NUMBER, PAGE_SIZE); + static final AbstractPageRequest REFERENCE_WITH_SORT = PageRequest.of(PAGE_NUMBER, PAGE_SIZE, SORT); + static final AbstractPageRequest REFERENCE_WITH_SORT_FIELDS = PageRequest.of(PAGE_NUMBER, PAGE_SIZE, + Sort.by(SORT_FIELDS)); @Rule public ExpectedException exception = ExpectedException.none(); @@ -69,8 +69,8 @@ public abstract class PageableDefaultUnitTests { @Test public void returnsDefaultIfNoRequestParametersAndNoDefault() throws Exception { - assertSupportedAndResult(getParameterOfMethod("supportedMethod"), - (Pageable) ReflectionTestUtils.getField(getResolver(), "fallbackPageable")); + assertSupportedAndResult(getParameterOfMethod("supportedMethod"), (Pageable) ReflectionTestUtils + .invokeMethod(ReflectionTestUtils.getField(getResolver(), "fallbackPageable"), "get")); } @Test diff --git a/src/test/java/org/springframework/data/web/PageableHandlerMethodArgumentResolverUnitTests.java b/src/test/java/org/springframework/data/web/PageableHandlerMethodArgumentResolverUnitTests.java index 7b00fae42..dc7060f6c 100755 --- a/src/test/java/org/springframework/data/web/PageableHandlerMethodArgumentResolverUnitTests.java +++ b/src/test/java/org/springframework/data/web/PageableHandlerMethodArgumentResolverUnitTests.java @@ -18,6 +18,8 @@ package org.springframework.data.web; import static org.assertj.core.api.Assertions.*; import static org.springframework.data.web.PageableHandlerMethodArgumentResolver.*; +import java.util.Optional; + import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Qualifier; @@ -53,7 +55,7 @@ public class PageableHandlerMethodArgumentResolverUnitTests extends PageableDefa request.addParameter("page", "0"); request.addParameter("size", "200"); - assertSupportedAndResult(supportedMethodParameter, new PageRequest(0, 100), request); + assertSupportedAndResult(supportedMethodParameter, PageRequest.of(0, 100), request); } @Test(expected = IllegalArgumentException.class) @@ -85,7 +87,7 @@ public class PageableHandlerMethodArgumentResolverUnitTests extends PageableDefa request.addParameter("foo_page", "2"); request.addParameter("foo_size", "10"); - assertSupportedAndResult(parameter, new PageRequest(2, 10), request); + assertSupportedAndResult(parameter, PageRequest.of(2, 10), request); } @Test // DATACMNS-377 @@ -141,7 +143,7 @@ public class PageableHandlerMethodArgumentResolverUnitTests extends PageableDefa public void returnsNullIfFallbackIsNullAndNoParametersGiven() throws Exception { PageableHandlerMethodArgumentResolver resolver = getResolver(); - resolver.setFallbackPageable(null); + resolver.setFallbackPageable(Optional.empty()); assertSupportedAndResult(supportedMethodParameter, null, new ServletWebRequest(new MockHttpServletRequest()), resolver); @@ -151,7 +153,7 @@ public class PageableHandlerMethodArgumentResolverUnitTests extends PageableDefa public void returnsNullIfFallbackIsNullAndOnlyPageIsGiven() throws Exception { PageableHandlerMethodArgumentResolver resolver = getResolver(); - resolver.setFallbackPageable(null); + resolver.setFallbackPageable(Optional.empty()); MockHttpServletRequest request = new MockHttpServletRequest(); request.addParameter("page", "20"); @@ -163,7 +165,7 @@ public class PageableHandlerMethodArgumentResolverUnitTests extends PageableDefa public void returnsNullIfFallbackIsNullAndOnlySizeIsGiven() throws Exception { PageableHandlerMethodArgumentResolver resolver = getResolver(); - resolver.setFallbackPageable(null); + resolver.setFallbackPageable(Optional.empty()); MockHttpServletRequest request = new MockHttpServletRequest(); request.addParameter("size", "10"); @@ -189,7 +191,7 @@ public class PageableHandlerMethodArgumentResolverUnitTests extends PageableDefa public void usesNullSortIfNoDefaultIsConfiguredAndPageAndSizeAreGiven() { PageableHandlerMethodArgumentResolver resolver = getResolver(); - resolver.setFallbackPageable(null); + resolver.setFallbackPageable(Optional.empty()); MockHttpServletRequest request = new MockHttpServletRequest(); request.addParameter("page", "0"); @@ -199,7 +201,7 @@ public class PageableHandlerMethodArgumentResolverUnitTests extends PageableDefa assertThat(result.getPageNumber()).isEqualTo(0); assertThat(result.getPageSize()).isEqualTo(10); - assertThat(result.getSort()).isNull(); + assertThat(result.getSort().isSorted()).isFalse(); } @Test // DATACMNS-692 @@ -236,8 +238,8 @@ public class PageableHandlerMethodArgumentResolverUnitTests extends PageableDefa PageableHandlerMethodArgumentResolver resolver = getResolver(); resolver.setFallbackPageable(null); - assertThat(resolver.isFallbackPageable(null), is(false)); - assertThat(resolver.isFallbackPageable(new PageRequest(0, 10)), is(false)); + assertThat(resolver.isFallbackPageable(null)).isFalse(); + assertThat(resolver.isFallbackPageable(PageRequest.of(0, 10))).isTrue(); } @Override diff --git a/src/test/java/org/springframework/data/web/PagedResourcesAssemblerUnitTests.java b/src/test/java/org/springframework/data/web/PagedResourcesAssemblerUnitTests.java index 494b977d1..dcf4fe1b1 100755 --- a/src/test/java/org/springframework/data/web/PagedResourcesAssemblerUnitTests.java +++ b/src/test/java/org/springframework/data/web/PagedResourcesAssemblerUnitTests.java @@ -49,11 +49,11 @@ import org.springframework.web.util.UriComponentsBuilder; */ public class PagedResourcesAssemblerUnitTests { - static final Pageable PAGEABLE = new PageRequest(0, 20); - static final Page EMPTY_PAGE = new PageImpl(Collections. emptyList(), PAGEABLE, 0); + static final Pageable PAGEABLE = PageRequest.of(0, 20); + static final Page EMPTY_PAGE = new PageImpl<>(Collections.emptyList(), PAGEABLE, 0); HateoasPageableHandlerMethodArgumentResolver resolver = new HateoasPageableHandlerMethodArgumentResolver(); - PagedResourcesAssembler assembler = new PagedResourcesAssembler(resolver, null); + PagedResourcesAssembler assembler = new PagedResourcesAssembler<>(resolver, null); @Before public void setUp() { @@ -95,7 +95,7 @@ public class PagedResourcesAssemblerUnitTests { UriComponents baseUri = UriComponentsBuilder.fromUriString("http://foo:9090").build(); - PagedResourcesAssembler assembler = new PagedResourcesAssembler(resolver, baseUri); + PagedResourcesAssembler assembler = new PagedResourcesAssembler<>(resolver, baseUri); PagedResources> resources = assembler.toResource(createPage(1)); assertThat(resources.getLink(Link.REL_PREVIOUS).getHref()).startsWith(baseUri.toUriString()); @@ -120,8 +120,8 @@ public class PagedResourcesAssemblerUnitTests { resolver.setOneIndexedParameters(true); - AbstractPageRequest request = new PageRequest(0, 1); - Page page = new PageImpl(Collections. emptyList(), request, 0); + AbstractPageRequest request = PageRequest.of(0, 1); + Page page = new PageImpl<>(Collections.emptyList(), request, 0); assembler.toResource(page); } @@ -155,7 +155,7 @@ public class PagedResourcesAssemblerUnitTests { HateoasPageableHandlerMethodArgumentResolver argumentResolver = new HateoasPageableHandlerMethodArgumentResolver(); argumentResolver.setOneIndexedParameters(true); - PagedResourcesAssembler assembler = new PagedResourcesAssembler(argumentResolver, null); + PagedResourcesAssembler assembler = new PagedResourcesAssembler<>(argumentResolver, null); PagedResources> resource = assembler.toResource(createPage(1)); assertThat(resource.hasLink("prev")).isTrue(); @@ -228,7 +228,7 @@ public class PagedResourcesAssemblerUnitTests { @Test // DATACMNS-701 public void alwaysAddsFirstAndLastLinkIfConfiguredTo() { - PagedResourcesAssembler assembler = new PagedResourcesAssembler(resolver, null); + PagedResourcesAssembler assembler = new PagedResourcesAssembler<>(resolver, null); assembler.setForceFirstAndLastRels(true); PagedResources> resources = assembler.toResource(EMPTY_PAGE); @@ -240,7 +240,7 @@ public class PagedResourcesAssemblerUnitTests { @Test // DATACMNS-802 public void usesCustomPagedResources() { - ResourceAssembler, PagedResources>> assembler = new CustomPagedResourcesAssembler( + ResourceAssembler, PagedResources>> assembler = new CustomPagedResourcesAssembler<>( resolver, null); assertThat(assembler.toResource(EMPTY_PAGE)).isInstanceOf(CustomPagedResources.class); @@ -248,12 +248,12 @@ public class PagedResourcesAssemblerUnitTests { private static Page createPage(int index) { - AbstractPageRequest request = new PageRequest(index, 1); + Pageable request = PageRequest.of(index, 1); Person person = new Person(); person.name = "Dave"; - return new PageImpl(Arrays.asList(person), request, 3); + return new PageImpl<>(Arrays.asList(person), request, 3); } private static Map getQueryParameters(Link link) { @@ -293,7 +293,7 @@ public class PagedResourcesAssemblerUnitTests { @Override protected PagedResources createPagedResource(List resources, PageMetadata metadata, Page page) { - return new CustomPagedResources(resources, metadata); + return new CustomPagedResources<>(resources, metadata); } } diff --git a/src/test/java/org/springframework/data/web/ProjectingJackson2HttpMessageConverterUnitTests.java b/src/test/java/org/springframework/data/web/ProjectingJackson2HttpMessageConverterUnitTests.java index 542d235a0..ef5515316 100755 --- a/src/test/java/org/springframework/data/web/ProjectingJackson2HttpMessageConverterUnitTests.java +++ b/src/test/java/org/springframework/data/web/ProjectingJackson2HttpMessageConverterUnitTests.java @@ -15,7 +15,6 @@ */ package org.springframework.data.web; -import static org.hamcrest.CoreMatchers.*; import static org.assertj.core.api.Assertions.*; import java.lang.reflect.Method; diff --git a/src/test/java/org/springframework/data/web/SortDefaultUnitTests.java b/src/test/java/org/springframework/data/web/SortDefaultUnitTests.java index df97c7e02..d490f3ae8 100755 --- a/src/test/java/org/springframework/data/web/SortDefaultUnitTests.java +++ b/src/test/java/org/springframework/data/web/SortDefaultUnitTests.java @@ -46,17 +46,16 @@ public abstract class SortDefaultUnitTests { static final Sort SORT = new Sort(SORT_DIRECTION, SORT_FIELDS); - @Rule - public ExpectedException exception = ExpectedException.none(); + @Rule public ExpectedException exception = ExpectedException.none(); @Test public void parsesSimpleSortStringCorrectly() { - assertSortStringParsedInto(new Sort(new Order("username")), SORT_1); - assertSortStringParsedInto(new Sort(new Order(ASC, "username")), SORT_1); - assertSortStringParsedInto(new Sort(new Order(ASC, "username"), // + assertSortStringParsedInto(Sort.by(new Order("username")), SORT_1); + assertSortStringParsedInto(Sort.by(new Order(ASC, "username")), SORT_1); + assertSortStringParsedInto(Sort.by(new Order(ASC, "username"), // new Order(DESC, "lastname"), new Order(DESC, "firstname")), SORT_2); - assertSortStringParsedInto(new Sort("firstname", "lastname"), SORT_3); + assertSortStringParsedInto(Sort.by("firstname", "lastname"), SORT_3); } private static void assertSortStringParsedInto(Sort expected, String... source) { @@ -74,12 +73,12 @@ public abstract class SortDefaultUnitTests { @Test public void returnsNullForNoDefault() throws Exception { - assertSupportedAndResolvedTo(getParameterOfMethod("supportedMethod"), null); + assertSupportedAndResolvedTo(getParameterOfMethod("supportedMethod"), Sort.unsorted()); } @Test public void discoversSimpleDefault() throws Exception { - assertSupportedAndResolvedTo(getParameterOfMethod("simpleDefault"), new Sort(Direction.ASC, SORT_FIELDS)); + assertSupportedAndResolvedTo(getParameterOfMethod("simpleDefault"), Sort.by(SORT_FIELDS).ascending()); } @Test @@ -114,7 +113,7 @@ public abstract class SortDefaultUnitTests { public void discoversContaineredDefault() throws Exception { MethodParameter parameter = getParameterOfMethod("containeredDefault"); - Sort reference = new Sort("foo", "bar"); + Sort reference = Sort.by("foo", "bar"); assertSupportedAndResolvedTo(parameter, reference); } diff --git a/src/test/java/org/springframework/data/web/SortHandlerMethodArgumentResolverUnitTests.java b/src/test/java/org/springframework/data/web/SortHandlerMethodArgumentResolverUnitTests.java index a9ea81a25..367b1bb2f 100755 --- a/src/test/java/org/springframework/data/web/SortHandlerMethodArgumentResolverUnitTests.java +++ b/src/test/java/org/springframework/data/web/SortHandlerMethodArgumentResolverUnitTests.java @@ -69,14 +69,14 @@ public class SortHandlerMethodArgumentResolverUnitTests extends SortDefaultUnitT SortHandlerMethodArgumentResolver resolver = new SortHandlerMethodArgumentResolver(); Sort sort = resolver.resolveArgument(parameter, null, new ServletWebRequest(new MockHttpServletRequest()), null); - assertThat(sort).isNull(); + assertThat(sort.isSorted()).isFalse(); } @Test public void discoversSimpleSortFromRequest() { MethodParameter parameter = getParameterOfMethod("simpleDefault"); - Sort reference = new Sort("bar", "foo"); + Sort reference = Sort.by("bar", "foo"); NativeWebRequest request = getRequestWithSort(reference); assertSupportedAndResolvedTo(request, parameter, reference); @@ -86,7 +86,7 @@ public class SortHandlerMethodArgumentResolverUnitTests extends SortDefaultUnitT public void discoversComplexSortFromRequest() { MethodParameter parameter = getParameterOfMethod("simpleDefault"); - Sort reference = new Sort("bar", "foo").and(new Sort("fizz", "buzz")); + Sort reference = Sort.by("bar", "foo").and(Sort.by("fizz", "buzz")); assertSupportedAndResolvedTo(getRequestWithSort(reference), parameter, reference); } @@ -95,7 +95,7 @@ public class SortHandlerMethodArgumentResolverUnitTests extends SortDefaultUnitT public void discoversQualifiedSortFromRequest() { MethodParameter parameter = getParameterOfMethod("qualifiedSort"); - Sort reference = new Sort("bar", "foo"); + Sort reference = Sort.by("bar", "foo"); assertSupportedAndResolvedTo(getRequestWithSort(reference, "qual"), parameter, reference); } @@ -110,7 +110,7 @@ public class SortHandlerMethodArgumentResolverUnitTests extends SortDefaultUnitT SortHandlerMethodArgumentResolver resolver = new SortHandlerMethodArgumentResolver(); Sort result = resolver.resolveArgument(parameter, null, new ServletWebRequest(request), null); - assertThat(result).isNull(); + assertThat(result.isSorted()).isFalse(); } @Test // DATACMNS-366 @@ -132,7 +132,7 @@ public class SortHandlerMethodArgumentResolverUnitTests extends SortDefaultUnitT MockHttpServletRequest request = new MockHttpServletRequest(); request.addParameter("sort", ""); - assertThat(resolveSort(request, PARAMETER)).isNull(); + assertThat(resolveSort(request, PARAMETER).isSorted()).isFalse(); } @Test // DATACMNS-408 @@ -141,7 +141,7 @@ public class SortHandlerMethodArgumentResolverUnitTests extends SortDefaultUnitT MockHttpServletRequest request = new MockHttpServletRequest(); request.addParameter("sort", ",DESC"); - assertThat(resolveSort(request, PARAMETER)).isNull(); + assertThat(resolveSort(request, PARAMETER).isSorted()).isFalse(); } @Test // DATACMNS-408 @@ -169,7 +169,7 @@ public class SortHandlerMethodArgumentResolverUnitTests extends SortDefaultUnitT MockHttpServletRequest request = new MockHttpServletRequest(); request.addParameter("sort", ","); - assertThat(resolveSort(request, PARAMETER)).isNull(); + assertThat(resolveSort(request, PARAMETER).isSorted()).isFalse(); } @Test // DATACMNS-753, DATACMNS-408 @@ -178,8 +178,8 @@ public class SortHandlerMethodArgumentResolverUnitTests extends SortDefaultUnitT MockHttpServletRequest request = new MockHttpServletRequest(); request.addParameter("sort", ""); - assertThat(resolveSort(request, getParameterOfMethod("simpleDefault"))).isEqualTo(new Sort("firstname", "lastname")); - assertThat(resolveSort(request, getParameterOfMethod("containeredDefault"))).isEqualTo(new Sort("foo", "bar")); + assertThat(resolveSort(request, getParameterOfMethod("simpleDefault"))).isEqualTo(Sort.by("firstname", "lastname")); + assertThat(resolveSort(request, getParameterOfMethod("containeredDefault"))).isEqualTo(Sort.by("foo", "bar")); } private static Sort resolveSort(HttpServletRequest request, MethodParameter parameter) throws Exception { diff --git a/src/test/java/org/springframework/data/web/XmlBeamHttpMessageConverterUnitTests.java b/src/test/java/org/springframework/data/web/XmlBeamHttpMessageConverterUnitTests.java index 24f53d08d..84ff9cfb5 100755 --- a/src/test/java/org/springframework/data/web/XmlBeamHttpMessageConverterUnitTests.java +++ b/src/test/java/org/springframework/data/web/XmlBeamHttpMessageConverterUnitTests.java @@ -15,7 +15,6 @@ */ package org.springframework.data.web; -import static org.hamcrest.CoreMatchers.*; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; diff --git a/src/test/java/org/springframework/data/web/config/PageableResourcesAssemblerIntegrationTests.java b/src/test/java/org/springframework/data/web/config/PageableResourcesAssemblerIntegrationTests.java index 5d3fda538..e66c051f6 100755 --- a/src/test/java/org/springframework/data/web/config/PageableResourcesAssemblerIntegrationTests.java +++ b/src/test/java/org/springframework/data/web/config/PageableResourcesAssemblerIntegrationTests.java @@ -68,7 +68,7 @@ public class PageableResourcesAssemblerIntegrationTests { assertThat(controller.assembler).isNotNull(); - PagedResources> resources = controller.sample(new PageRequest(1, 1)); + PagedResources> resources = controller.sample(PageRequest.of(1, 1)); assertThat(resources.getLink(Link.REL_PREVIOUS)).isNotNull(); assertThat(resources.getLink(Link.REL_NEXT)).isNotNull(); @@ -99,7 +99,7 @@ public class PageableResourcesAssemblerIntegrationTests { @RequestMapping("/persons") PagedResources> sample(Pageable pageable) { - Page page = new PageImpl(Arrays.asList(new Person()), pageable, + Page page = new PageImpl<>(Arrays.asList(new Person()), pageable, pageable.getOffset() + pageable.getPageSize() + 1); return assembler.toResource(page);