1 package com.atlassian.plugin.util;
2
3 import java.lang.reflect.Array;
4 import java.lang.reflect.GenericArrayType;
5 import java.lang.reflect.ParameterizedType;
6 import java.lang.reflect.Type;
7 import java.lang.reflect.TypeVariable;
8 import java.util.ArrayList;
9 import java.util.HashMap;
10 import java.util.List;
11 import java.util.Map;
12 import java.util.Set;
13 import java.util.HashSet;
14
15
16
17
18 public class ClassUtils
19 {
20 private ClassUtils()
21 {
22 }
23
24
25
26
27
28
29
30 public static Set<Class> findAllTypes(Class cls)
31 {
32 Set<Class> types = new HashSet<Class>();
33 findAllTypes(cls, types);
34 return types;
35 }
36
37
38
39
40
41
42
43 public static void findAllTypes(Class cls, Set<Class> types)
44 {
45 if (cls == null)
46 {
47 return;
48 }
49
50
51 if (types.contains(cls))
52 {
53 return;
54 }
55
56 types.add(cls);
57
58 findAllTypes(cls.getSuperclass(), types);
59 for (int x = 0; x < cls.getInterfaces().length; x++)
60 {
61 findAllTypes(cls.getInterfaces()[x], types);
62 }
63 }
64
65
66
67
68
69
70
71 private static Class<?> getClass(Type type)
72 {
73 if (type instanceof Class)
74 {
75 return (Class) type;
76 }
77 else if (type instanceof ParameterizedType)
78 {
79 return getClass(((ParameterizedType) type).getRawType());
80 }
81 else if (type instanceof GenericArrayType)
82 {
83 Type componentType = ((GenericArrayType) type).getGenericComponentType();
84 Class<?> componentClass = getClass(componentType);
85 if (componentClass != null)
86 {
87 return Array.newInstance(componentClass, 0).getClass();
88 }
89 else
90 {
91 return null;
92 }
93 }
94 else
95 {
96 return null;
97 }
98 }
99
100
101
102
103
104
105
106
107
108
109 public static <T> List<Class<?>> getTypeArguments(
110 Class<T> baseClass, Class<? extends T> childClass)
111 {
112 Map<Type, Type> resolvedTypes = new HashMap<Type, Type>();
113 Type type = childClass;
114 Class typeClass = getClass(type);
115
116 while (!typeClass.equals(baseClass))
117 {
118 if (type instanceof Class)
119 {
120
121 type = ((Class) type).getGenericSuperclass();
122 }
123 else
124 {
125 ParameterizedType parameterizedType = (ParameterizedType) type;
126 Class<?> rawType = (Class) parameterizedType.getRawType();
127
128 Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
129 TypeVariable<?>[] typeParameters = rawType.getTypeParameters();
130 for (int i = 0; i < actualTypeArguments.length; i++)
131 {
132 resolvedTypes.put(typeParameters[i], actualTypeArguments[i]);
133 }
134
135 if (!rawType.equals(baseClass))
136 {
137 type = rawType.getGenericSuperclass();
138 }
139 }
140 typeClass = getClass(type);
141 if (typeClass == null)
142 {
143 throw new IllegalArgumentException("Unable to find the class for the type " + type);
144 }
145 }
146
147
148
149 Type[] actualTypeArguments;
150 if (type instanceof Class)
151 {
152 actualTypeArguments = ((Class) type).getTypeParameters();
153 }
154 else
155 {
156 actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
157 }
158 List<Class<?>> typeArgumentsAsClasses = new ArrayList<Class<?>>();
159
160 for (Type baseType : actualTypeArguments)
161 {
162 while (resolvedTypes.containsKey(baseType))
163 {
164 baseType = resolvedTypes.get(baseType);
165 }
166 typeArgumentsAsClasses.add(getClass(baseType));
167 }
168 return typeArgumentsAsClasses;
169 }
170 }