1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
package org.apache.tapestry.enhance; |
15 |
|
|
16 |
|
import java.lang.reflect.Method; |
17 |
|
import java.lang.reflect.ParameterizedType; |
18 |
|
import java.lang.reflect.Type; |
19 |
|
import java.lang.reflect.TypeVariable; |
20 |
|
|
21 |
|
|
22 |
|
|
23 |
|
|
24 |
|
|
25 |
|
|
26 |
|
public class GenericsMethodSignatureImpl extends MethodSignatureImpl implements MethodSignature |
27 |
|
{ |
28 |
|
boolean _isGeneric; |
29 |
|
|
30 |
|
public GenericsMethodSignatureImpl(Class type, Method m) |
31 |
|
{ |
32 |
39 |
super(findReturnType(type, m), m.getName(), findParameterTypes(type, m), m.getExceptionTypes()); |
33 |
|
|
34 |
42 |
_isGeneric = type.getGenericSuperclass() != null && ParameterizedType.class.isInstance(type.getGenericSuperclass()); |
35 |
39 |
} |
36 |
|
|
37 |
|
public boolean isGeneric() |
38 |
|
{ |
39 |
0 |
return _isGeneric; |
40 |
|
} |
41 |
|
|
42 |
|
static Class findReturnType(Class type, Method m) |
43 |
|
{ |
44 |
39 |
Type ret = m.getGenericReturnType(); |
45 |
|
|
46 |
39 |
if (TypeVariable.class.isInstance(ret) |
47 |
|
&& type.getGenericSuperclass() != null |
48 |
|
&& ParameterizedType.class.isInstance(type.getGenericSuperclass())) { |
49 |
|
|
50 |
2 |
TypeVariable tvar = (TypeVariable)ret; |
51 |
2 |
ParameterizedType param = (ParameterizedType)type.getGenericSuperclass(); |
52 |
|
|
53 |
2 |
Class resolvedType = resolveType(param, tvar); |
54 |
2 |
if (resolvedType != null) |
55 |
0 |
return resolvedType; |
56 |
|
|
57 |
|
} |
58 |
|
|
59 |
39 |
return m.getReturnType(); |
60 |
|
} |
61 |
|
|
62 |
|
static Class resolveType(ParameterizedType param, TypeVariable var) |
63 |
|
{ |
64 |
7 |
if (param.getActualTypeArguments().length < 1) |
65 |
0 |
return null; |
66 |
|
|
67 |
14 |
for (int i=0; i < var.getBounds().length; i++) { |
68 |
|
|
69 |
7 |
Type t = var.getBounds()[i]; |
70 |
7 |
Class resolvedType = null; |
71 |
7 |
if (ParameterizedType.class.isInstance(t)) { |
72 |
|
|
73 |
3 |
ParameterizedType pparam = (ParameterizedType)t; |
74 |
6 |
for (int e=0; e < pparam.getActualTypeArguments().length; e++) { |
75 |
3 |
if (!TypeVariable.class.isInstance(pparam.getActualTypeArguments()[e])) |
76 |
0 |
continue; |
77 |
|
|
78 |
3 |
resolvedType = resolveType(pparam, (TypeVariable)pparam.getActualTypeArguments()[e]); |
79 |
|
} |
80 |
3 |
} else { |
81 |
|
|
82 |
4 |
resolvedType = findType(param.getActualTypeArguments(), (Class)t); |
83 |
|
} |
84 |
|
|
85 |
7 |
if (resolvedType != null) |
86 |
0 |
return resolvedType; |
87 |
|
} |
88 |
|
|
89 |
7 |
return null; |
90 |
|
} |
91 |
|
|
92 |
|
static Class findType(Type[] types, Class type) |
93 |
|
{ |
94 |
8 |
for (int i = 0; i < types.length; i++) { |
95 |
|
|
96 |
4 |
if (Class.class.isInstance(types[i]) && type.isAssignableFrom((Class)types[i])) |
97 |
0 |
return (Class)types[i]; |
98 |
|
} |
99 |
|
|
100 |
4 |
return null; |
101 |
|
} |
102 |
|
|
103 |
|
static Class[] findParameterTypes(Class type, Method m) |
104 |
|
{ |
105 |
39 |
if (type.getGenericSuperclass() == null |
106 |
|
|| !ParameterizedType.class.isInstance(type.getGenericSuperclass())) |
107 |
6 |
return m.getParameterTypes(); |
108 |
|
|
109 |
33 |
ParameterizedType param = (ParameterizedType)type.getGenericSuperclass(); |
110 |
33 |
Type[] genTypes = m.getGenericParameterTypes(); |
111 |
33 |
Class[] types = new Class[genTypes.length]; |
112 |
|
|
113 |
|
typeSearch: |
114 |
46 |
for (int i=0; i < genTypes.length; i++) { |
115 |
|
|
116 |
13 |
if (TypeVariable.class.isInstance(genTypes[i])) { |
117 |
|
|
118 |
2 |
Class resolved = resolveType(param, (TypeVariable)genTypes[i]); |
119 |
|
|
120 |
2 |
if (resolved != null) { |
121 |
0 |
types[i] = resolved; |
122 |
0 |
continue; |
123 |
|
} |
124 |
|
} |
125 |
|
|
126 |
13 |
types[i] = m.getParameterTypes()[i]; |
127 |
|
} |
128 |
|
|
129 |
33 |
return types; |
130 |
|
} |
131 |
|
|
132 |
|
|
133 |
|
} |