Java tutorial
/* * Copyright 2002-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.integration.util; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.function.Function; import java.util.function.Supplier; import org.springframework.lang.Nullable; import org.springframework.util.ReflectionUtils; /** * @author Mark Fisher * @author Artem Bilan * * @since 2.0 */ public abstract class ClassUtils { /** * Map with primitive wrapper type as key and corresponding primitive * type as value, for example: Integer.class -> int.class. */ private static final Map<Class<?>, Class<?>> PRIMITIVE_WRAPPER_TYPE_MAP = new HashMap<>(8); /** * The {@link Function#apply(Object)} method object. */ public static final Method FUNCTION_APPLY_METHOD = ReflectionUtils.findMethod(Function.class, "apply", (Class<?>[]) null); /** * The {@link Supplier#get()} method object. */ public static final Method SUPPLIER_GET_METHOD = ReflectionUtils.findMethod(Supplier.class, "get", (Class<?>[]) null); /** * The {@code org.springframework.integration.core.GenericSelector#accept(Object)} method object. */ public static final Method SELECTOR_ACCEPT_METHOD; /** * The {@code org.springframework.integration.transformer.GenericTransformer#transform(Object)} method object. */ public static final Method TRANSFORMER_TRANSFORM_METHOD; /** * The {@code org.springframework.integration.handler.GenericHandler#handle(Object, Map)} method object. */ public static final Method HANDLER_HANDLE_METHOD; /** * The {@code kotlin.jvm.functions.Function0} class object. */ public static final Class<?> KOTLIN_FUNCTION_0_CLASS; /** * The {@code kotlin.jvm.functions.Function0#invoke} method object. */ public static final Method KOTLIN_FUNCTION_0_INVOKE_METHOD; /** * The {@code kotlin.jvm.functions.Function1} class object. */ public static final Class<?> KOTLIN_FUNCTION_1_CLASS; static { PRIMITIVE_WRAPPER_TYPE_MAP.put(Boolean.class, boolean.class); PRIMITIVE_WRAPPER_TYPE_MAP.put(Byte.class, byte.class); PRIMITIVE_WRAPPER_TYPE_MAP.put(Character.class, char.class); PRIMITIVE_WRAPPER_TYPE_MAP.put(Double.class, double.class); PRIMITIVE_WRAPPER_TYPE_MAP.put(Float.class, float.class); PRIMITIVE_WRAPPER_TYPE_MAP.put(Integer.class, int.class); PRIMITIVE_WRAPPER_TYPE_MAP.put(Long.class, long.class); PRIMITIVE_WRAPPER_TYPE_MAP.put(Short.class, short.class); Class<?> genericSelectorClass = null; try { genericSelectorClass = org.springframework.util.ClassUtils.forName( "org.springframework.integration.core.GenericSelector", org.springframework.util.ClassUtils.getDefaultClassLoader()); } catch (ClassNotFoundException e) { ReflectionUtils.rethrowRuntimeException(e); } SELECTOR_ACCEPT_METHOD = ReflectionUtils.findMethod(genericSelectorClass, "accept", (Class<?>[]) null); Class<?> genericTransformerClass = null; try { genericTransformerClass = org.springframework.util.ClassUtils.forName( "org.springframework.integration.transformer.GenericTransformer", org.springframework.util.ClassUtils.getDefaultClassLoader()); } catch (ClassNotFoundException e) { ReflectionUtils.rethrowRuntimeException(e); } TRANSFORMER_TRANSFORM_METHOD = ReflectionUtils.findMethod(genericTransformerClass, "transform", (Class<?>[]) null); Class<?> genericHandlerClass = null; try { genericHandlerClass = org.springframework.util.ClassUtils.forName( "org.springframework.integration.handler.GenericHandler", org.springframework.util.ClassUtils.getDefaultClassLoader()); } catch (ClassNotFoundException e) { ReflectionUtils.rethrowRuntimeException(e); } HANDLER_HANDLE_METHOD = ReflectionUtils.findMethod(genericHandlerClass, "handle", (Class<?>[]) null); Class<?> kotlinClass = null; Method kotlinMethod = null; try { kotlinClass = org.springframework.util.ClassUtils.forName("kotlin.jvm.functions.Function0", org.springframework.util.ClassUtils.getDefaultClassLoader()); kotlinMethod = ReflectionUtils.findMethod(kotlinClass, "invoke", (Class<?>[]) null); } catch (ClassNotFoundException e) { //Ignore: assume no Kotlin in classpath } finally { KOTLIN_FUNCTION_0_CLASS = kotlinClass; KOTLIN_FUNCTION_0_INVOKE_METHOD = kotlinMethod; } kotlinClass = null; kotlinMethod = null; try { kotlinClass = org.springframework.util.ClassUtils.forName("kotlin.jvm.functions.Function1", org.springframework.util.ClassUtils.getDefaultClassLoader()); } catch (ClassNotFoundException e) { //Ignore: assume no Kotlin in classpath } finally { KOTLIN_FUNCTION_1_CLASS = kotlinClass; } } public static Class<?> findClosestMatch(Class<?> type, Set<Class<?>> candidates, boolean failOnTie) { int minTypeDiffWeight = Integer.MAX_VALUE; Class<?> closestMatch = null; for (Class<?> candidate : candidates) { int typeDiffWeight = getTypeDifferenceWeight(candidate, type); if (typeDiffWeight < minTypeDiffWeight) { minTypeDiffWeight = typeDiffWeight; closestMatch = candidate; } else if (failOnTie && typeDiffWeight < Integer.MAX_VALUE && (typeDiffWeight == minTypeDiffWeight)) { throw new IllegalStateException( "Unresolvable ambiguity while attempting to find closest match for [" + type.getName() + "]. Candidate types [" + closestMatch.getName() + "] and [" + candidate.getName() + "] have equal weight."); } } return closestMatch; } private static int getTypeDifferenceWeight(Class<?> candidate, Class<?> type) { int result = 0; if (!org.springframework.util.ClassUtils.isAssignable(candidate, type)) { return Integer.MAX_VALUE; } Class<?> superClass = type.getSuperclass(); while (superClass != null) { if (type.equals(superClass)) { result = result + 2; superClass = null; } else if (org.springframework.util.ClassUtils.isAssignable(candidate, superClass)) { result = result + 2; superClass = superClass.getSuperclass(); } else { superClass = null; } } if (candidate.isInterface()) { result = result + 1; } return result; } /** * Resolve the given class if it is a primitive wrapper class, * returning the corresponding primitive type instead. * @param clazz the wrapper class to check * @return the corresponding primitive if the clazz is a wrapper, otherwise null */ @Nullable public static Class<?> resolvePrimitiveType(Class<?> clazz) { return PRIMITIVE_WRAPPER_TYPE_MAP.get(clazz); } /** * Check if class is Java lambda. * @param aClass the {@link Class} to check. * @return true if class is a Java lambda. * @since 5.2 */ public static boolean isLambda(Class<?> aClass) { return aClass.isSynthetic() && !aClass.isAnonymousClass() && !aClass.isLocalClass(); } /** * Check if class is {@code kotlin.jvm.functions.Function0}. * @param aClass the {@link Class} to check. * @return true if class is a {@code kotlin.jvm.functions.Function0} implementation. * @since 5.2 */ public static boolean isKotlinFaction0(Class<?> aClass) { return KOTLIN_FUNCTION_0_CLASS != null && KOTLIN_FUNCTION_0_CLASS.isAssignableFrom(aClass); } /** * Check if class is {@code kotlin.jvm.functions.Function1}. * @param aClass the {@link Class} to check. * @return true if class is a {@code kotlin.jvm.functions.Function1} implementation. * @since 5.2 */ public static boolean isKotlinFaction1(Class<?> aClass) { return KOTLIN_FUNCTION_1_CLASS != null && KOTLIN_FUNCTION_1_CLASS.isAssignableFrom(aClass); } }