Skip to content

Commit fdb8d83

Browse files
committed
#321 follow-up. Added GenericArrayType support.
1 parent e88c98c commit fdb8d83

File tree

3 files changed

+93
-0
lines changed

3 files changed

+93
-0
lines changed

src/main/java/org/apache/ibatis/reflection/TypeParameterResolver.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package org.apache.ibatis.reflection;
1717

18+
import java.lang.reflect.Array;
19+
import java.lang.reflect.GenericArrayType;
1820
import java.lang.reflect.Method;
1921
import java.lang.reflect.ParameterizedType;
2022
import java.lang.reflect.Type;
@@ -38,12 +40,31 @@ public static Type resolveReturnType(Method method, Type mapper) {
3840
result = resolveTypeVar((TypeVariable<?>) returnType, mapper, declaringClass);
3941
} else if (returnType instanceof ParameterizedType) {
4042
result = resolveParameterizedType((ParameterizedType) returnType, mapper, declaringClass);
43+
} else if (returnType instanceof GenericArrayType) {
44+
result = resolveGenericArrayType((GenericArrayType) returnType, mapper, declaringClass);
4145
} else {
4246
result = returnType;
4347
}
4448
return result;
4549
}
4650

51+
private static Type resolveGenericArrayType(GenericArrayType genericArrayType, Type mapper, Class<?> declaringClass) {
52+
Type componentType = genericArrayType.getGenericComponentType();
53+
Type resolvedComponentType = null;
54+
if (componentType instanceof TypeVariable) {
55+
resolvedComponentType = resolveTypeVar((TypeVariable<?>) componentType, mapper, declaringClass);
56+
} else if (componentType instanceof GenericArrayType) {
57+
resolvedComponentType = resolveGenericArrayType((GenericArrayType) componentType, mapper, declaringClass);
58+
} else if (componentType instanceof ParameterizedType) {
59+
resolvedComponentType = resolveParameterizedType((ParameterizedType) componentType, mapper, declaringClass);
60+
}
61+
if (resolvedComponentType instanceof Class) {
62+
return Array.newInstance((Class<?>) resolvedComponentType, 0).getClass();
63+
} else {
64+
return new GenericArrayTypeImpl(resolvedComponentType);
65+
}
66+
}
67+
4768
private static ParameterizedType resolveParameterizedType(ParameterizedType parameterizedType, Type mapper, Class<?> declaringClass) {
4869
Class<?> rawType = (Class<?>) parameterizedType.getRawType();
4970
Type[] typeArgs = parameterizedType.getActualTypeArguments();
@@ -193,4 +214,18 @@ public Type[] getUpperBounds() {
193214
return upperBounds;
194215
}
195216
}
217+
218+
static class GenericArrayTypeImpl implements GenericArrayType {
219+
private Type genericComponentType;
220+
221+
private GenericArrayTypeImpl(Type genericComponentType) {
222+
super();
223+
this.genericComponentType = genericComponentType;
224+
}
225+
226+
@Override
227+
public Type getGenericComponentType() {
228+
return genericComponentType;
229+
}
230+
}
196231
}

src/test/java/org/apache/ibatis/reflection/TypeParameterResolverTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import static org.junit.Assert.*;
1919

20+
import java.lang.reflect.GenericArrayType;
2021
import java.lang.reflect.Method;
2122
import java.lang.reflect.ParameterizedType;
2223
import java.lang.reflect.Type;
@@ -116,6 +117,18 @@ public void testReturn_SimpleArray() throws Exception {
116117
assertEquals(String.class, resultClass.getComponentType());
117118
}
118119

120+
@Test
121+
public void testReturn_SimpleArrayOfArray() throws Exception {
122+
Class<?> clazz = Level1Mapper.class;
123+
Method method = clazz.getMethod("simpleSelectArrayOfArray");
124+
Type result = TypeParameterResolver.resolveReturnType(method, clazz);
125+
assertTrue(result instanceof Class);
126+
Class<?> resultClass = (Class<?>) result;
127+
assertTrue(resultClass.isArray());
128+
assertTrue(resultClass.getComponentType().isArray());
129+
assertEquals(String.class, resultClass.getComponentType().getComponentType());
130+
}
131+
119132
@Test
120133
public void testReturn_SimpleTypeVar() throws Exception {
121134
Class<?> clazz = Level1Mapper.class;
@@ -188,6 +201,43 @@ public void testReturn_Lv1List() throws Exception {
188201
assertEquals(String.class, type.getActualTypeArguments()[0]);
189202
}
190203

204+
@Test
205+
public void testReturn_Lv1Array() throws Exception {
206+
Class<?> clazz = Level1Mapper.class;
207+
Method method = clazz.getMethod("selectArray");
208+
Type result = TypeParameterResolver.resolveReturnType(method, clazz);
209+
assertTrue(result instanceof Class);
210+
Class<?> resultClass = (Class<?>) result;
211+
assertTrue(resultClass.isArray());
212+
assertEquals(String.class, resultClass.getComponentType());
213+
}
214+
215+
@Test
216+
public void testReturn_Lv2ArrayOfArray() throws Exception {
217+
Class<?> clazz = Level2Mapper.class;
218+
Method method = clazz.getMethod("selectArrayOfArray");
219+
Type result = TypeParameterResolver.resolveReturnType(method, clazz);
220+
assertTrue(result instanceof Class);
221+
Class<?> resultClass = (Class<?>) result;
222+
assertTrue(result instanceof Class);
223+
assertTrue(resultClass.isArray());
224+
assertTrue(resultClass.getComponentType().isArray());
225+
assertEquals(String.class, resultClass.getComponentType().getComponentType());
226+
}
227+
228+
@Test
229+
public void testReturn_Lv2ArrayOfList() throws Exception {
230+
Class<?> clazz = Level2Mapper.class;
231+
Method method = clazz.getMethod("selectArrayOfList");
232+
Type result = TypeParameterResolver.resolveReturnType(method, clazz);
233+
assertTrue(result instanceof GenericArrayType);
234+
GenericArrayType genericArrayType = (GenericArrayType) result;
235+
assertTrue(genericArrayType.getGenericComponentType() instanceof ParameterizedType);
236+
ParameterizedType paramType = (ParameterizedType) genericArrayType.getGenericComponentType();
237+
assertEquals(List.class, paramType.getRawType());
238+
assertEquals(String.class, paramType.getActualTypeArguments()[0]);
239+
}
240+
191241
@Test
192242
public void testReturn_Lv2WildcardList() throws Exception {
193243
Class<?> clazz = Level2Mapper.class;

src/test/java/org/apache/ibatis/reflection/typeparam/Level0Mapper.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public interface Level0Mapper<L, M, N> {
3232

3333
String[] simpleSelectArray();
3434

35+
String[][] simpleSelectArrayOfArray();
36+
3537
<K extends Calculator<?>> K simpleSelectTypeVar();
3638

3739
List<? extends String> simpleSelectWildcard();
@@ -44,6 +46,12 @@ public interface Level0Mapper<L, M, N> {
4446

4547
Map<N, M> selectMap();
4648

49+
N[] selectArray();
50+
51+
N[][] selectArrayOfArray();
52+
53+
List<N>[] selectArrayOfList();
54+
4755
Calculator<N> selectCalculator(Calculator<N> param);
4856

4957
List<Calculator<L>> selectCalculatorList();

0 commit comments

Comments
 (0)