diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring-test/src/main/java/org/androidannotations/rest/spring/test/MyService.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring-test/src/main/java/org/androidannotations/rest/spring/test/MyService.java index 14d49a8f17..aa22427ed9 100644 --- a/AndroidAnnotations/androidannotations-rest-spring/rest-spring-test/src/main/java/org/androidannotations/rest/spring/test/MyService.java +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring-test/src/main/java/org/androidannotations/rest/spring/test/MyService.java @@ -86,6 +86,9 @@ public interface MyService { @Get("/events/{year}/{location}") List[] getEventsGenericsArrayList(String location, int year) throws RestClientException; + @Get("/events/{year}/{location}") + List[][] getEventsGenericsArrayList2(String location, int year) throws RestClientException; + @Get("/events/{year}/{location}") List> getEventsGenericsListListEvent(String location, int year) throws RestClientException; diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/helper/RestAnnotationHelper.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/helper/RestAnnotationHelper.java index 93b1e37601..d29c6c8ac2 100644 --- a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/helper/RestAnnotationHelper.java +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/helper/RestAnnotationHelper.java @@ -287,6 +287,11 @@ public JExpression getResponseClass(Element element, RestHolder holder) { JExpression responseClassExpr = nullCastedToNarrowedClass(holder); TypeMirror returnType = executableElement.getReturnType(); if (returnType.getKind() != TypeKind.VOID) { + if (getElementUtils().getTypeElement(RestSpringClasses.PARAMETERIZED_TYPE_REFERENCE) != null && !returnType.toString().startsWith(RestSpringClasses.RESPONSE_ENTITY) + && checkIfParameterizedTypeReferenceShouldBeUsed(returnType)) { + return createParameterizedTypeReferenceAnonymousSubclassInstance(returnType); + } + JClass responseClass = retrieveResponseClass(returnType, holder); if (responseClass != null) { responseClassExpr = responseClass.dotclass(); @@ -295,6 +300,25 @@ public JExpression getResponseClass(Element element, RestHolder holder) { return responseClassExpr; } + private boolean checkIfParameterizedTypeReferenceShouldBeUsed(TypeMirror returnType) { + switch (returnType.getKind()) { + case DECLARED: + return !((DeclaredType) returnType).getTypeArguments().isEmpty(); + + case ARRAY: + ArrayType arrayType = (ArrayType) returnType; + TypeMirror componentType = arrayType.getComponentType(); + return checkIfParameterizedTypeReferenceShouldBeUsed(componentType); + } + return false; + } + + public JExpression createParameterizedTypeReferenceAnonymousSubclassInstance(TypeMirror returnType) { + JClass narrowedTypeReference = getEnvironment().getJClass(RestSpringClasses.PARAMETERIZED_TYPE_REFERENCE).narrow(codeModelHelper.typeMirrorToJClass(returnType)); + JDefinedClass anonymousClass = getEnvironment().getCodeModel().anonymousClass(narrowedTypeReference); + return JExpr._new(anonymousClass); + } + public JClass retrieveResponseClass(TypeMirror returnType, RestHolder holder) { String returnTypeString = returnType.toString(); @@ -303,12 +327,12 @@ public JClass retrieveResponseClass(TypeMirror returnType, RestHolder holder) { if (returnTypeString.startsWith(RESPONSE_ENTITY)) { DeclaredType declaredReturnType = (DeclaredType) returnType; if (declaredReturnType.getTypeArguments().size() > 0) { - responseClass = resolveResponseClass(declaredReturnType.getTypeArguments().get(0), holder); + responseClass = resolveResponseClass(declaredReturnType.getTypeArguments().get(0), holder, false); } else { responseClass = getEnvironment().getJClass(RESPONSE_ENTITY); } } else { - responseClass = resolveResponseClass(returnType, holder); + responseClass = resolveResponseClass(returnType, holder, true); } return responseClass; @@ -336,7 +360,7 @@ public JClass retrieveResponseClass(TypeMirror returnType, RestHolder holder) { * * */ - private JClass resolveResponseClass(TypeMirror expectedType, RestHolder holder) { + private JClass resolveResponseClass(TypeMirror expectedType, RestHolder holder, boolean useTypeReference) { // is a class or an interface if (expectedType.getKind() == TypeKind.DECLARED) { DeclaredType declaredType = (DeclaredType) expectedType; @@ -351,6 +375,10 @@ private JClass resolveResponseClass(TypeMirror expectedType, RestHolder holder) // is a generics, must generate a new super class TypeElement declaredElement = (TypeElement) declaredType.asElement(); + if (useTypeReference && getElementUtils().getTypeElement(RestSpringClasses.PARAMETERIZED_TYPE_REFERENCE) != null) { + return codeModelHelper.typeMirrorToJClass(declaredType); + } + JClass baseClass = codeModelHelper.typeMirrorToJClass(declaredType).erasure(); JClass decoratedExpectedClass = retrieveDecoratedResponseClass(declaredType, declaredElement, holder); if (decoratedExpectedClass == null) { @@ -359,7 +387,8 @@ private JClass resolveResponseClass(TypeMirror expectedType, RestHolder holder) return decoratedExpectedClass; } else if (expectedType.getKind() == TypeKind.ARRAY) { ArrayType arrayType = (ArrayType) expectedType; - return resolveResponseClass(arrayType.getComponentType(), holder).array(); + TypeMirror componentType = arrayType.getComponentType(); + return resolveResponseClass(componentType, holder, false).array(); } // is not a class nor an interface, return directly diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/helper/RestSpringClasses.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/helper/RestSpringClasses.java index 6eff694ed9..c158630c7a 100644 --- a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/helper/RestSpringClasses.java +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/helper/RestSpringClasses.java @@ -31,6 +31,7 @@ public final class RestSpringClasses { public static final String REST_CLIENT_EXCEPTION = "org.springframework.web.client.RestClientException"; public static final String NESTED_RUNTIME_EXCEPTION = "org.springframework.core.NestedRuntimeException"; public static final String RESPONSE_ERROR_HANDLER = "org.springframework.web.client.ResponseErrorHandler"; + public static final String PARAMETERIZED_TYPE_REFERENCE = "org.springframework.core.ParameterizedTypeReference"; private RestSpringClasses() {