From 90431bea70d9da5348b909d1840d50bbb2a91555 Mon Sep 17 00:00:00 2001 From: mercyblitz Date: Mon, 20 May 2019 15:08:38 +0800 Subject: [PATCH] Polish apache/incubator-dubbo/#4096 : Add Utilities class --- .../dubbo/common/utils/ReflectUtils.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectUtils.java index ccec6875ca8..4d1c95e70b8 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectUtils.java @@ -28,19 +28,28 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.net.URL; import java.security.CodeSource; import java.security.ProtectionDomain; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static java.util.Arrays.asList; +import static java.util.Collections.unmodifiableSet; /** * ReflectUtils @@ -1096,4 +1105,61 @@ public static Map getBeanPropertyReadMethods(Class cl) { return properties; } + + /** + * Find the {@link Set} of {@link ParameterizedType} + * + * @param sourceClass the source {@link Class class} + * @return non-null read-only {@link Set} + * @since 2.7.2 + */ + public static Set findParameterizedTypes(Class sourceClass) { + // Add Generic Interfaces + List genericTypes = new LinkedList<>(asList(sourceClass.getGenericInterfaces())); + // Add Generic Super Class + genericTypes.add(sourceClass.getGenericSuperclass()); + + Set parameterizedTypes = genericTypes.stream() + .filter(type -> type instanceof ParameterizedType)// filter ParameterizedType + .map(type -> ParameterizedType.class.cast(type)) // cast to ParameterizedType + .collect(Collectors.toSet()); + + if (parameterizedTypes.isEmpty()) { // If not found, try to search super types recursively + genericTypes.stream() + .filter(type -> type instanceof Class) + .map(type -> Class.class.cast(type)) + .forEach(superClass -> { + parameterizedTypes.addAll(findParameterizedTypes(superClass)); + }); + } + + return unmodifiableSet(parameterizedTypes); // build as a Set + + } + + /** + * Find the hierarchical types form the source {@link Class class} by specified {@link Class type}. + * + * @param sourceClass the source {@link Class class} + * @param matchType the type to match + * @param the type to match + * @return non-null read-only {@link Set} + * @since 2.7.2 + */ + public static Set> findHierarchicalTypes(Class sourceClass, Class matchType) { + if (sourceClass == null) { + return Collections.emptySet(); + } + + Set> hierarchicalTypes = new LinkedHashSet<>(); + + if (matchType.isAssignableFrom(sourceClass)) { + hierarchicalTypes.add((Class) sourceClass); + } + + // Find all super classes + hierarchicalTypes.addAll(findHierarchicalTypes(sourceClass.getSuperclass(), matchType)); + + return unmodifiableSet(hierarchicalTypes); + } } \ No newline at end of file