1 package org.apache.commons.ognl.internal.entry;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import org.apache.commons.ognl.internal.CacheException;
27
28 import java.lang.reflect.Array;
29 import java.lang.reflect.GenericArrayType;
30 import java.lang.reflect.ParameterizedType;
31 import java.lang.reflect.Type;
32 import java.lang.reflect.TypeVariable;
33
34 public class GenericMethodParameterTypeFactory
35 implements CacheEntryFactory<GenericMethodParameterTypeCacheEntry, Class<?>[]>
36 {
37 public Class<?>[] create( GenericMethodParameterTypeCacheEntry entry )
38 throws CacheException
39 {
40 Class<?>[] types;
41
42 ParameterizedType param = (ParameterizedType) entry.type.getGenericSuperclass();
43 Type[] genTypes = entry.method.getGenericParameterTypes();
44 TypeVariable<?>[] declaredTypes = entry.method.getDeclaringClass().getTypeParameters();
45
46 types = new Class[genTypes.length];
47
48 for ( int i = 0; i < genTypes.length; i++ )
49 {
50 TypeVariable<?> paramType = null;
51
52 if ( TypeVariable.class.isInstance( genTypes[i] ) )
53 {
54 paramType = (TypeVariable<?>) genTypes[i];
55 }
56 else if ( GenericArrayType.class.isInstance( genTypes[i] ) )
57 {
58 paramType = (TypeVariable<?>) ( (GenericArrayType) genTypes[i] ).getGenericComponentType();
59 }
60 else if ( ParameterizedType.class.isInstance( genTypes[i] ) )
61 {
62 types[i] = (Class<?>) ( (ParameterizedType) genTypes[i] ).getRawType();
63 continue;
64 }
65 else if ( Class.class.isInstance( genTypes[i] ) )
66 {
67 types[i] = (Class<?>) genTypes[i];
68 continue;
69 }
70
71 Class<?> resolved = resolveType( param, paramType, declaredTypes );
72
73 if ( resolved != null )
74 {
75 if ( GenericArrayType.class.isInstance( genTypes[i] ) )
76 {
77 resolved = Array.newInstance( resolved, 0 ).getClass();
78 }
79
80 types[i] = resolved;
81 continue;
82 }
83 types[i] = entry.method.getParameterTypes()[i];
84 }
85
86 return types;
87 }
88
89 private Class<?> resolveType( ParameterizedType param, TypeVariable<?> var, TypeVariable<?>[] declaredTypes )
90 {
91 if ( param.getActualTypeArguments().length < 1 )
92 {
93 return null;
94 }
95
96 for ( int i = 0; i < declaredTypes.length; i++ )
97 {
98 if ( !TypeVariable.class.isInstance( param.getActualTypeArguments()[i] )
99 && declaredTypes[i].getName().equals( var.getName() ) )
100 {
101 return (Class<?>) param.getActualTypeArguments()[i];
102 }
103 }
104
105 return null;
106 }
107 }