1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.util.internal;
17
18 import java.lang.reflect.AccessibleObject;
19 import java.lang.reflect.Array;
20 import java.lang.reflect.GenericArrayType;
21 import java.lang.reflect.ParameterizedType;
22 import java.lang.reflect.Type;
23 import java.lang.reflect.TypeVariable;
24
25 public final class ReflectionUtil {
26
27 private ReflectionUtil() { }
28
29
30
31
32
33
34 public static Throwable trySetAccessible(AccessibleObject object, boolean checkAccessible) {
35 if (checkAccessible && !PlatformDependent0.isExplicitTryReflectionSetAccessible()) {
36 return new UnsupportedOperationException("Reflective setAccessible(true) disabled");
37 }
38 try {
39 object.setAccessible(true);
40 return null;
41 } catch (SecurityException e) {
42 return e;
43 } catch (RuntimeException e) {
44 return handleInaccessibleObjectException(e);
45 }
46 }
47
48 private static RuntimeException handleInaccessibleObjectException(RuntimeException e) {
49
50
51
52 if ("java.lang.reflect.InaccessibleObjectException".equals(e.getClass().getName())) {
53 return e;
54 }
55 throw e;
56 }
57
58 private static Class<?> fail(Class<?> type, String typeParamName) {
59 throw new IllegalStateException(
60 "cannot determine the type of the type parameter '" + typeParamName + "': " + type);
61 }
62
63
64
65
66
67
68
69
70
71 public static Class<?> resolveTypeParameter(final Object object,
72 Class<?> parametrizedSuperclass,
73 String typeParamName) {
74 final Class<?> thisClass = object.getClass();
75 Class<?> currentClass = thisClass;
76 for (;;) {
77 if (currentClass.getSuperclass() == parametrizedSuperclass) {
78 int typeParamIndex = -1;
79 TypeVariable<?>[] typeParams = currentClass.getSuperclass().getTypeParameters();
80 for (int i = 0; i < typeParams.length; i ++) {
81 if (typeParamName.equals(typeParams[i].getName())) {
82 typeParamIndex = i;
83 break;
84 }
85 }
86
87 if (typeParamIndex < 0) {
88 throw new IllegalStateException(
89 "unknown type parameter '" + typeParamName + "': " + parametrizedSuperclass);
90 }
91
92 Type genericSuperType = currentClass.getGenericSuperclass();
93 if (!(genericSuperType instanceof ParameterizedType)) {
94 return Object.class;
95 }
96
97 Type[] actualTypeParams = ((ParameterizedType) genericSuperType).getActualTypeArguments();
98
99 Type actualTypeParam = actualTypeParams[typeParamIndex];
100 if (actualTypeParam instanceof ParameterizedType) {
101 actualTypeParam = ((ParameterizedType) actualTypeParam).getRawType();
102 }
103 if (actualTypeParam instanceof Class) {
104 return (Class<?>) actualTypeParam;
105 }
106 if (actualTypeParam instanceof GenericArrayType) {
107 Type componentType = ((GenericArrayType) actualTypeParam).getGenericComponentType();
108 if (componentType instanceof ParameterizedType) {
109 componentType = ((ParameterizedType) componentType).getRawType();
110 }
111 if (componentType instanceof Class) {
112 return Array.newInstance((Class<?>) componentType, 0).getClass();
113 }
114 }
115 if (actualTypeParam instanceof TypeVariable) {
116
117 TypeVariable<?> v = (TypeVariable<?>) actualTypeParam;
118 if (!(v.getGenericDeclaration() instanceof Class)) {
119 return Object.class;
120 }
121
122 currentClass = thisClass;
123 parametrizedSuperclass = (Class<?>) v.getGenericDeclaration();
124 typeParamName = v.getName();
125 if (parametrizedSuperclass.isAssignableFrom(thisClass)) {
126 continue;
127 }
128 return Object.class;
129 }
130
131 return fail(thisClass, typeParamName);
132 }
133 currentClass = currentClass.getSuperclass();
134 if (currentClass == null) {
135 return fail(thisClass, typeParamName);
136 }
137 }
138 }
139 }