/*
 * Copyright 2008-2020 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
 *
 *      https://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.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;

import org.springframework.data.repository.Repository;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

Utility class to work with classes.
Author:Oliver Gierke
/** * Utility class to work with classes. * * @author Oliver Gierke */
public abstract class ClassUtils {
Private constructor to prevent instantiation.
/** * Private constructor to prevent instantiation. */
private ClassUtils() {}
Returns whether the given class contains a property with the given name.
Params:
  • type –
  • property –
Returns:
/** * Returns whether the given class contains a property with the given name. * * @param type * @param property * @return */
public static boolean hasProperty(Class<?> type, String property) { if (null != ReflectionUtils.findMethod(type, "get" + property)) { return true; } return null != ReflectionUtils.findField(type, StringUtils.uncapitalize(property)); }
Returns wthere the given type is the Repository interface.
Params:
  • interfaze –
Returns:
/** * Returns wthere the given type is the {@link Repository} interface. * * @param interfaze * @return */
public static boolean isGenericRepositoryInterface(Class<?> interfaze) { return Repository.class.equals(interfaze); }
Returns whether the given type name is a repository interface name.
Params:
  • interfaceName –
Returns:
/** * Returns whether the given type name is a repository interface name. * * @param interfaceName * @return */
public static boolean isGenericRepositoryInterface(@Nullable String interfaceName) { return Repository.class.getName().equals(interfaceName); }
Returns the number of occurences of the given type in the given Methods parameters.
Params:
  • method –
  • type –
Returns:
/** * Returns the number of occurences of the given type in the given {@link Method}s parameters. * * @param method * @param type * @return */
public static int getNumberOfOccurences(Method method, Class<?> type) { int result = 0; for (Class<?> clazz : method.getParameterTypes()) { if (type.equals(clazz)) { result++; } } return result; }
Asserts the given Method's return type to be one of the given types. Will unwrap known wrapper types before the assignment check (see QueryExecutionConverters).
Params:
  • method – must not be null.
  • types – must not be null or empty.
/** * Asserts the given {@link Method}'s return type to be one of the given types. Will unwrap known wrapper types before * the assignment check (see {@link QueryExecutionConverters}). * * @param method must not be {@literal null}. * @param types must not be {@literal null} or empty. */
public static void assertReturnTypeAssignable(Method method, Class<?>... types) { Assert.notNull(method, "Method must not be null!"); Assert.notEmpty(types, "Types must not be null or empty!"); TypeInformation<?> returnType = getEffectivelyReturnedTypeFrom(method); 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))); }
Returns whether the given object is of one of the given types. Will return false for null.
Params:
  • object –
  • types –
Returns:
/** * Returns whether the given object is of one of the given types. Will return {@literal false} for {@literal null}. * * @param object * @param types * @return */
public static boolean isOfType(@Nullable Object object, Collection<Class<?>> types) { if (object == null) { return false; } return types.stream().anyMatch(it -> it.isAssignableFrom(object.getClass())); }
Returns whether the given Method has a parameter of the given type.
Params:
  • method –
  • type –
Returns:
/** * Returns whether the given {@link Method} has a parameter of the given type. * * @param method * @param type * @return */
public static boolean hasParameterOfType(Method method, Class<?> type) { return Arrays.asList(method.getParameterTypes()).contains(type); }
Helper method to extract the original exception that can possibly occur during a reflection call.
Params:
  • ex –
Throws:
/** * Helper method to extract the original exception that can possibly occur during a reflection call. * * @param ex * @throws Throwable */
public static void unwrapReflectionException(Exception ex) throws Throwable { if (ex instanceof InvocationTargetException) { throw ((InvocationTargetException) ex).getTargetException(); } throw ex; } private static TypeInformation<?> getEffectivelyReturnedTypeFrom(Method method) { TypeInformation<?> returnType = ClassTypeInformation.fromReturnTypeOf(method); return QueryExecutionConverters.supports(returnType.getType()) ? returnType.getRequiredComponentType() : returnType; } }