org.springframework.data.repository.util.ClassUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.data.repository.util.ClassUtils.java

Source

/*
 * Copyright 2008-2019 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
 */
public abstract class ClassUtils {

    /**
     * Private constructor to prevent instantiation.
     */
    private ClassUtils() {
    }

    /**
     * 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 {@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.
     *
     * @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 {@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 {@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 {@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 {@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.
     *
     * @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;
    }
}