DATACMNS-867 - Rework utility classes.
Removed the additional methods that reflectively checked for the Stream type and whether a Method instance is a default method. Turned utility classes into interfaces where possible. Make use of Lombok's @UtilityClass where not. Removed obsolete implementation class in StreamUtils in favor of a lambda.
This commit is contained in:
@@ -57,7 +57,7 @@ public class DefaultMethodInvokingMethodInterceptor implements MethodInterceptor
|
||||
|
||||
Method method = invocation.getMethod();
|
||||
|
||||
if (!org.springframework.data.util.ReflectionUtils.isDefaultMethod(method)) {
|
||||
if (!method.isDefault()) {
|
||||
return invocation.proceed();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.repository.Repository;
|
||||
@@ -28,7 +29,6 @@ import org.springframework.data.repository.util.QueryExecutionConverters;
|
||||
import org.springframework.data.repository.util.ReactiveWrappers;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.data.util.ReflectionUtils;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -140,7 +140,7 @@ public abstract class AbstractRepositoryMetadata implements RepositoryMetadata {
|
||||
Class<?> rawType = type.getType();
|
||||
|
||||
boolean needToUnwrap = Iterable.class.isAssignableFrom(rawType) || rawType.isArray()
|
||||
|| QueryExecutionConverters.supports(rawType) || ReflectionUtils.isJava8StreamType(rawType);
|
||||
|| QueryExecutionConverters.supports(rawType) || Stream.class.isAssignableFrom(rawType);
|
||||
|
||||
return needToUnwrap ? unwrapWrapperTypes(type.getRequiredComponentType()) : rawType;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ import org.springframework.data.repository.core.CrudMethods;
|
||||
import org.springframework.data.repository.core.RepositoryInformation;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.util.Optionals;
|
||||
import org.springframework.data.util.ReflectionUtils;
|
||||
import org.springframework.data.util.Streamable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -185,7 +184,7 @@ class DefaultRepositoryInformation implements RepositoryInformation {
|
||||
* @return
|
||||
*/
|
||||
private boolean isQueryMethodCandidate(Method method) {
|
||||
return !method.isBridge() && !ReflectionUtils.isDefaultMethod(method) //
|
||||
return !method.isBridge() && !method.isDefault() //
|
||||
&& !Modifier.isStatic(method.getModifiers()) //
|
||||
&& (isQueryAnnotationPresentOn(method) || !isCustomMethod(method) && !isBaseClassMethod(method));
|
||||
}
|
||||
|
||||
@@ -364,9 +364,10 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware,
|
||||
Class<?> baseClass = information.getRepositoryBaseClass();
|
||||
Optional<Constructor<?>> constructor = ReflectionUtils.findConstructor(baseClass, constructorArguments);
|
||||
|
||||
return constructor.map(it -> (R) BeanUtils.instantiateClass(it, constructorArguments)).orElseThrow(() -> new IllegalStateException(String.format(
|
||||
"No suitable constructor found on %s to match the given arguments: %s. Make sure you implement a constructor taking these",
|
||||
baseClass, Arrays.stream(constructorArguments).map(Object::getClass).collect(Collectors.toList()))));
|
||||
return constructor.map(it -> (R) BeanUtils.instantiateClass(it, constructorArguments))
|
||||
.orElseThrow(() -> new IllegalStateException(String.format(
|
||||
"No suitable constructor found on %s to match the given arguments: %s. Make sure you implement a constructor taking these",
|
||||
baseClass, Arrays.stream(constructorArguments).map(Object::getClass).collect(Collectors.toList()))));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,7 @@ import static org.springframework.data.repository.util.ClassUtils.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
@@ -30,7 +31,6 @@ import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.util.QueryExecutionConverters;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.data.util.ReflectionUtils;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -232,7 +232,7 @@ public class QueryMethod {
|
||||
* @since 1.10
|
||||
*/
|
||||
public boolean isStreamQuery() {
|
||||
return ReflectionUtils.isJava8StreamType(unwrappedReturnType);
|
||||
return Stream.class.isAssignableFrom(unwrappedReturnType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
/*
|
||||
* Copyright 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.util;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
@UtilityClass
|
||||
public class CastUtils {
|
||||
public interface CastUtils {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T cast(Object object) {
|
||||
public static <T> T cast(Object object) {
|
||||
return (T) object;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.util;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -29,7 +31,8 @@ import org.springframework.util.StringUtils;
|
||||
* @author Oliver Gierke
|
||||
* @since 1.5
|
||||
*/
|
||||
public abstract class ParsingUtils {
|
||||
@UtilityClass
|
||||
public class ParsingUtils {
|
||||
|
||||
private static final String UPPER = "\\p{Lu}|\\P{InBASIC_LATIN}";
|
||||
private static final String LOWER = "\\p{Ll}";
|
||||
@@ -38,8 +41,6 @@ public abstract class ParsingUtils {
|
||||
|
||||
private static final Pattern CAMEL_CASE = Pattern.compile(CAMEL_CASE_REGEX);
|
||||
|
||||
private ParsingUtils() {}
|
||||
|
||||
/**
|
||||
* Splits up the given camel-case {@link String}.
|
||||
*
|
||||
|
||||
@@ -17,12 +17,12 @@ package org.springframework.data.util;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Constructor;
|
||||
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;
|
||||
@@ -45,22 +45,8 @@ import org.springframework.util.ReflectionUtils.FieldFilter;
|
||||
* @author Christoph Strobl
|
||||
* @since 1.5
|
||||
*/
|
||||
public abstract class ReflectionUtils {
|
||||
|
||||
private static final Class<?> JAVA8_STREAM_TYPE;
|
||||
|
||||
static {
|
||||
|
||||
Class<?> cls = null;
|
||||
|
||||
try {
|
||||
cls = Class.forName("java.util.stream.Stream");
|
||||
} catch (ClassNotFoundException ignore) {}
|
||||
|
||||
JAVA8_STREAM_TYPE = cls;
|
||||
}
|
||||
|
||||
private ReflectionUtils() {}
|
||||
@UtilityClass
|
||||
public class ReflectionUtils {
|
||||
|
||||
/**
|
||||
* Creates an instance of the class with the given fully qualified name or returns the given default instance if the
|
||||
@@ -81,18 +67,6 @@ public abstract class ReflectionUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Back-port of Java 8's {@code isDefault()} method on {@link Method}.
|
||||
*
|
||||
* @param method must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static boolean isDefaultMethod(Method method) {
|
||||
|
||||
return ((method.getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) == Modifier.PUBLIC)
|
||||
&& method.getDeclaringClass().isInterface();
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link FieldFilter} that has a description.
|
||||
*
|
||||
@@ -227,21 +201,6 @@ public abstract class ReflectionUtils {
|
||||
org.springframework.util.ReflectionUtils.setField(field, target, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the given type is assignable to a Java 8 {@link Stream}.
|
||||
*
|
||||
* @param type can be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static boolean isJava8StreamType(Class<?> type) {
|
||||
|
||||
if (type == null || JAVA8_STREAM_TYPE == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return JAVA8_STREAM_TYPE.isAssignableFrom(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a constructor on the given type that matches the given constructor arguments.
|
||||
*
|
||||
@@ -276,15 +235,31 @@ public abstract class ReflectionUtils {
|
||||
return Stream.concat(returnType, parameterTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Method} with the given name and parameters declared on the given type, if available.
|
||||
*
|
||||
* @param type must not be {@literal null}.
|
||||
* @param name must not be {@literal null} or empty.
|
||||
* @param parameterTypes must not be {@literal null}.
|
||||
* @return
|
||||
* @since 2.0
|
||||
*/
|
||||
public static Optional<Method> getMethod(Class<?> type, String name, ResolvableType... parameterTypes) {
|
||||
|
||||
List<Class<?>> collect = Arrays.stream(parameterTypes).map(ResolvableType::getRawClass).collect(Collectors.toList());
|
||||
Assert.notNull(type, "Type must not be null!");
|
||||
Assert.hasText(name, "Name must not be null or empty!");
|
||||
Assert.notNull(parameterTypes, "Parameter types must not be null!");
|
||||
|
||||
Optional<Method> method = Optional.ofNullable(
|
||||
org.springframework.util.ReflectionUtils.findMethod(type, name, collect.toArray(new Class<?>[collect.size()])));
|
||||
List<Class<?>> collect = Arrays.stream(parameterTypes)//
|
||||
.map(ResolvableType::getRawClass)//
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return method.filter(it -> IntStream.range(0, it.getParameterCount())//
|
||||
.allMatch(index -> ResolvableType.forMethodParameter(it, index).equals(parameterTypes[index])));
|
||||
Method method = org.springframework.util.ReflectionUtils.findMethod(type, name,
|
||||
collect.toArray(new Class<?>[collect.size()]));
|
||||
|
||||
return Optional.ofNullable(method)//
|
||||
.filter(it -> IntStream.range(0, it.getParameterCount())//
|
||||
.allMatch(index -> ResolvableType.forMethodParameter(it, index).equals(parameterTypes[index])));
|
||||
}
|
||||
|
||||
private static boolean argumentsMatch(Class<?>[] parameterTypes, Object[] arguments) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
* Copyright 2015-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.
|
||||
@@ -30,9 +30,7 @@ import org.springframework.util.Assert;
|
||||
* @author Oliver Gierke
|
||||
* @since 1.10
|
||||
*/
|
||||
public class StreamUtils {
|
||||
|
||||
private StreamUtils() {}
|
||||
public interface StreamUtils {
|
||||
|
||||
/**
|
||||
* Returns a {@link Stream} backed by the given {@link Iterator}.
|
||||
@@ -51,50 +49,8 @@ public class StreamUtils {
|
||||
Spliterator<T> spliterator = Spliterators.spliteratorUnknownSize(iterator, Spliterator.NONNULL);
|
||||
Stream<T> stream = StreamSupport.stream(spliterator, false);
|
||||
|
||||
return iterator instanceof CloseableIterator
|
||||
? stream.onClose(new CloseableIteratorDisposingRunnable((CloseableIterator<T>) iterator)) : stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link Runnable} that closes the given {@link CloseableIterator} in its {@link #run()} method. If the given
|
||||
* {@code closeable} is {@literal null} the {@link #run()} method effectively becomes a noop.
|
||||
* <p>
|
||||
* Can be used in conjunction with streams as close action via:
|
||||
*
|
||||
* <pre>
|
||||
* CloseableIterator<T> result = ...;
|
||||
* Spliterator<T> spliterator = ...;
|
||||
*
|
||||
* return StreamSupport.stream(spliterator, false).onClose(new CloseableIteratorDisposingRunnable(result));
|
||||
* </pre>
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
* @author Oliver Gierke
|
||||
* @since 1.10
|
||||
*/
|
||||
private static class CloseableIteratorDisposingRunnable implements Runnable {
|
||||
|
||||
private CloseableIterator<?> closeable;
|
||||
|
||||
/**
|
||||
* Creates a new {@link CloseableIteratorDisposingRunnable} for the given {@link CloseableIterator}.
|
||||
*
|
||||
* @param closeable can be {@literal null}.
|
||||
*/
|
||||
public CloseableIteratorDisposingRunnable(CloseableIterator<?> closeable) {
|
||||
this.closeable = closeable;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Runnable#run()
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
if (closeable != null) {
|
||||
closeable.close();
|
||||
}
|
||||
}
|
||||
return iterator instanceof CloseableIterator//
|
||||
? stream.onClose(() -> ((CloseableIterator<T>) iterator).close()) //
|
||||
: stream;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user