diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/GetProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/GetProcessor.java index d7b5beb7d1..e22fa55b1e 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/GetProcessor.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/GetProcessor.java @@ -50,11 +50,10 @@ public String retrieveUrlSuffix(Element element) { } @Override - protected JVar generateHttpEntityVar(MethodProcessorHolder methodHolder) { + protected JExpression generateHttpEntityVar(MethodProcessorHolder methodHolder) { ExecutableElement executableElement = (ExecutableElement) methodHolder.getElement(); EBeanHolder holder = methodHolder.getHolder(); JClass httpEntity = holder.refClass(CanonicalNameConstants.HTTP_ENTITY); - JExpression httpEntityValue; JBlock body = methodHolder.getBody(); JVar httpHeadersVar = generateHttpHeadersVar(holder, body, executableElement); @@ -64,15 +63,12 @@ protected JVar generateHttpEntityVar(MethodProcessorHolder methodHolder) { if (hasHeaders) { JInvocation newHttpEntityVarCall = JExpr._new(httpEntity.narrow(Object.class)); newHttpEntityVarCall.arg(httpHeadersVar); - httpEntityValue = newHttpEntityVarCall; - } else { - httpEntityValue = httpEntity.staticRef("EMPTY"); - } - JVar httpEntityVar; - String httpEntityVarName = "requestEntity"; - httpEntityVar = body.decl(httpEntity.narrow(Object.class), httpEntityVarName, httpEntityValue); + String httpEntityVarName = "requestEntity"; - return httpEntityVar; + return body.decl(httpEntity.narrow(Object.class), httpEntityVarName, newHttpEntityVarCall); + } else { + return JExpr._null(); + } } } diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/MethodProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/MethodProcessor.java index f94e86026a..7bf5d7d46b 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/MethodProcessor.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/MethodProcessor.java @@ -27,6 +27,7 @@ import javax.lang.model.element.VariableElement; import org.androidannotations.annotations.rest.Accept; +import org.androidannotations.helper.APTCodeModelHelper; import org.androidannotations.helper.CanonicalNameConstants; import org.androidannotations.helper.RestAnnotationHelper; import org.androidannotations.processing.DecoratingElementProcessor; @@ -36,6 +37,7 @@ import com.sun.codemodel.JClass; import com.sun.codemodel.JCodeModel; import com.sun.codemodel.JExpr; +import com.sun.codemodel.JExpression; import com.sun.codemodel.JInvocation; import com.sun.codemodel.JMethod; import com.sun.codemodel.JMod; @@ -46,6 +48,7 @@ public abstract class MethodProcessor implements DecoratingElementProcessor { protected final RestImplementationsHolder restImplementationsHolder; protected final RestAnnotationHelper restAnnotationHelper; + protected final APTCodeModelHelper helper = new APTCodeModelHelper(); public MethodProcessor(ProcessingEnvironment processingEnv, RestImplementationsHolder restImplementationsHolder) { this.restImplementationsHolder = restImplementationsHolder; @@ -95,10 +98,11 @@ protected void generateRestTemplateCallBlock(MethodProcessorHolder methodHolder) restCall.arg(httpMethod.staticRef(restMethodInCapitalLetters)); + JVar hashMapVar = generateHashMapVar(methodHolder); + restCall = addHttpEntityVar(restCall, methodHolder); restCall = addResponseEntityArg(restCall, methodHolder); - JVar hashMapVar = generateHashMapVar(methodHolder); if (hashMapVar != null) { restCall.arg(hashMapVar); } @@ -161,7 +165,7 @@ private JVar generateHashMapVar(MethodProcessorHolder methodHolder) { return hashMapVar; } - protected JVar generateHttpEntityVar(MethodProcessorHolder methodHolder) { + protected JExpression generateHttpEntityVar(MethodProcessorHolder methodHolder) { ExecutableElement executableElement = (ExecutableElement) methodHolder.getElement(); EBeanHolder holder = methodHolder.getHolder(); JClass httpEntity = holder.refClass(CanonicalNameConstants.HTTP_ENTITY); @@ -176,6 +180,10 @@ protected JVar generateHttpEntityVar(MethodProcessorHolder methodHolder) { } if (entitySentToServer != null) { + if (entityType.isPrimitive()) { + // Don't narrow primitive types... + entityType = entityType.boxify(); + } newHttpEntityVarCall = JExpr._new(httpEntity.narrow(entityType)); } else { newHttpEntityVarCall = JExpr._new(httpEntity.narrow(Object.class)); @@ -211,11 +219,12 @@ protected JVar generateHttpHeadersVar(EBeanHolder holder, JBlock body, Executabl JVar httpHeadersVar = null; JClass httpHeadersClass = holder.refClass(CanonicalNameConstants.HTTP_HEADERS); - httpHeadersVar = body.decl(httpHeadersClass, "httpHeaders", JExpr._new(httpHeadersClass)); String mediaType = retrieveAcceptAnnotationValue(executableElement); boolean hasMediaTypeDefined = mediaType != null; if (hasMediaTypeDefined) { + httpHeadersVar = body.decl(httpHeadersClass, "httpHeaders", JExpr._new(httpHeadersClass)); + JClass collectionsClass = holder.refClass(CanonicalNameConstants.COLLECTIONS); JClass mediaTypeClass = holder.refClass(CanonicalNameConstants.MEDIA_TYPE); @@ -245,13 +254,16 @@ private TreeMap extractMethodParamsVar(EBeanHolder eBeanHolder, JM String paramName = parameter.getSimpleName().toString(); String paramType = parameter.asType().toString(); - // TODO check in validator that params are not generic. Or create a - // helper to fix that case and generate the right code. - JVar param = method.param(eBeanHolder.refClass(paramType), paramName); + JVar param = null; + if (parameter.asType().getKind().isPrimitive()) { + param = method.param(JType.parse(eBeanHolder.codeModel(), paramType), paramName); + } else { + JClass parameterClass = helper.typeMirrorToJClass(parameter.asType(), eBeanHolder); + param = method.param(parameterClass, paramName); + } methodParams.put(paramName, param); } return methodParams; } - } diff --git a/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/ClientWithPathVariable.java b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/ClientWithPathVariable.java new file mode 100644 index 0000000000..fbfecbd827 --- /dev/null +++ b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/ClientWithPathVariable.java @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2010-2012 eBusiness Information, Excilys Group + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed To in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package org.androidannotations.rest; + +import java.util.Set; + +import org.androidannotations.annotations.rest.Delete; +import org.androidannotations.annotations.rest.Get; +import org.androidannotations.annotations.rest.Head; +import org.androidannotations.annotations.rest.Options; +import org.androidannotations.annotations.rest.Post; +import org.androidannotations.annotations.rest.Put; +import org.androidannotations.annotations.rest.Rest; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter; + +@Rest(converters = MappingJacksonHttpMessageConverter.class) +public interface ClientWithPathVariable { + + @Delete("/test/{v1}/{v2}") + void deleteWithParameterEntity(int v1, String v2); + + @Get("/test/{v1}/{v2}") + void getWithParameterEntity(int v1, String v2); + + @Head("/test/{v1}/{v2}") + HttpHeaders headWithParameterEntity(int v1, String v2); + + @Options("/test/{v1}/{v2}") + Set optionsWithParameterEntity(int v1, String v2); + + @Post("/test/{v1}/{v2}") + void postWithParameterEntity(int v1, String v2); + + @Put("/test/{v1}/{v2}") + void putWithParameterEntity(int v1, String v2); + +} diff --git a/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/ClientWithPrimitiveReturnType.java b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/ClientWithPrimitiveReturnType.java new file mode 100644 index 0000000000..a66c0821dc --- /dev/null +++ b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/ClientWithPrimitiveReturnType.java @@ -0,0 +1,48 @@ +/** + * Copyright (C) 2010-2012 eBusiness Information, Excilys Group + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed To in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package org.androidannotations.rest; + +import org.androidannotations.annotations.rest.Delete; +import org.androidannotations.annotations.rest.Get; +import org.androidannotations.annotations.rest.Head; +import org.androidannotations.annotations.rest.Options; +import org.androidannotations.annotations.rest.Post; +import org.androidannotations.annotations.rest.Put; +import org.androidannotations.annotations.rest.Rest; +import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter; + +@Rest(converters = MappingJacksonHttpMessageConverter.class) +public interface ClientWithPrimitiveReturnType { + + @Delete("/test/") + int deleteWithPrimitiveReturnType(); + + @Get("/test/") + int getWithPrimitiveReturnType(); + + @Head("/test/") + int headWithPrimitiveReturnType(); + + @Options("/test/") + int optionsWithPrimitiveReturnType(); + + @Post("/test/") + int postWithPrimitiveReturnType(); + + @Put("/test/") + int putWithPrimitiveReturnType(); + +} diff --git a/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/ClientWithRequestEntity.java b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/ClientWithRequestEntity.java new file mode 100644 index 0000000000..36f7f567b1 --- /dev/null +++ b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/ClientWithRequestEntity.java @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2010-2012 eBusiness Information, Excilys Group + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed To in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package org.androidannotations.rest; + +import java.util.Set; + +import org.androidannotations.annotations.rest.Delete; +import org.androidannotations.annotations.rest.Get; +import org.androidannotations.annotations.rest.Head; +import org.androidannotations.annotations.rest.Options; +import org.androidannotations.annotations.rest.Post; +import org.androidannotations.annotations.rest.Put; +import org.androidannotations.annotations.rest.Rest; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter; + +@Rest(converters = MappingJacksonHttpMessageConverter.class) +public interface ClientWithRequestEntity { + + @Delete("/test/") + void deleteWithReturnType(Entity entity); + + @Get("/test/") + void getWithReturnType(Entity entity); + + @Head("/test/") + HttpHeaders headWithReturnType(Entity entity); + + @Options("/test/") + Set optionsWithReturnType(Entity entity); + + @Post("/test/") + void postWithReturnType(Entity entity); + + @Put("/test/") + void putWithReturnType(Entity entity); + +} diff --git a/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/ClientWithResponseEntity.java b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/ClientWithResponseEntity.java new file mode 100644 index 0000000000..339549b057 --- /dev/null +++ b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/ClientWithResponseEntity.java @@ -0,0 +1,48 @@ +/** + * Copyright (C) 2010-2012 eBusiness Information, Excilys Group + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed To in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package org.androidannotations.rest; + +import org.androidannotations.annotations.rest.Delete; +import org.androidannotations.annotations.rest.Get; +import org.androidannotations.annotations.rest.Head; +import org.androidannotations.annotations.rest.Options; +import org.androidannotations.annotations.rest.Post; +import org.androidannotations.annotations.rest.Put; +import org.androidannotations.annotations.rest.Rest; +import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter; + +@Rest(converters = MappingJacksonHttpMessageConverter.class) +public interface ClientWithResponseEntity { + + @Delete("/test/") + Entity deleteWithReturnType(); + + @Get("/test/") + Entity getWithReturnType(); + + @Head("/test/") + Entity headWithReturnType(); + + @Options("/test/") + Entity optionsWithReturnType(); + + @Post("/test/") + Entity postWithReturnType(); + + @Put("/test/") + Entity putWithReturnType(); + +} diff --git a/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/Entity.java b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/Entity.java new file mode 100644 index 0000000000..71e235c23e --- /dev/null +++ b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/Entity.java @@ -0,0 +1,15 @@ +package org.androidannotations.rest; + +public class Entity { + + private String message; + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/RestTest.java b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/RestTest.java index 7c381fd24e..99a41b1d30 100644 --- a/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/RestTest.java +++ b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rest/RestTest.java @@ -43,4 +43,42 @@ public void client_no_internet_permission_does_not_compile() throws IOException assertCompilationErrorOn(ClientWithNoConverters.class, "@Rest", result); } + @Test + public void client_with_return_type() throws IOException { + CompileResult result = compileFiles(ClientWithResponseEntity.class); + assertCompilationErrorOn(ClientWithResponseEntity.class, "@Put", result); + assertCompilationErrorOn(ClientWithResponseEntity.class, "@Delete", result); + assertCompilationErrorOn(ClientWithResponseEntity.class, "@Options", result); + assertCompilationErrorOn(ClientWithResponseEntity.class, "@Head", result); + assertCompilationErrorCount(4, result); + } + + @Test + public void client_with_request_entity() throws IOException { + CompileResult result = compileFiles(ClientWithRequestEntity.class); + assertCompilationErrorOn(ClientWithRequestEntity.class, "@Delete", result); + assertCompilationErrorOn(ClientWithRequestEntity.class, "@Get", result); + assertCompilationErrorOn(ClientWithRequestEntity.class, "@Head", result); + assertCompilationErrorOn(ClientWithRequestEntity.class, "@Options", result); + assertCompilationErrorCount(4, result); + } + + @Test + public void client_with_primitive_return_types() throws IOException { + CompileResult result = compileFiles(ClientWithPrimitiveReturnType.class); + assertCompilationErrorOn(ClientWithPrimitiveReturnType.class, "@Delete", result); + assertCompilationErrorOn(ClientWithPrimitiveReturnType.class, "@Get", result); + assertCompilationErrorOn(ClientWithPrimitiveReturnType.class, "@Head", result); + assertCompilationErrorOn(ClientWithPrimitiveReturnType.class, "@Options", result); + assertCompilationErrorOn(ClientWithPrimitiveReturnType.class, "@Post", result); + assertCompilationErrorOn(ClientWithPrimitiveReturnType.class, "@Put", result); + assertCompilationErrorCount(6, result); + } + + @Test + public void client_with_path_variables() throws IOException { + CompileResult result = compileFiles(ClientWithPathVariable.class); + assertCompilationSuccessful(result); + } + } diff --git a/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/rest/MyService.java b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/rest/MyService.java index bbbf790d47..bb5e901435 100644 --- a/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/rest/MyService.java +++ b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/rest/MyService.java @@ -126,6 +126,9 @@ ResponseEntity getEventsArrayOfArrays2(String location, int year) @Post("/events/{year}/") Event addEvent(Event event, int year); + @Post("/events/{year}/") + Event addEvent(int year); + @Post("/events/") ResponseEntity addEvent2(Event event); @@ -172,6 +175,9 @@ ResponseEntity getEventsArrayOfArrays2(String location, int year) @Put("/events/{id}") void updateEvent(Event event, int id); + @Put("/events/{date}") + void updateEvent(long date); + // *** DELETE *** // url variables are mapped to method parameter names. @@ -183,11 +189,17 @@ ResponseEntity getEventsArrayOfArrays2(String location, int year) @Head("/events/{year}/{location}") HttpHeaders getEventHeaders(String location, int year); + @Head("/events/{date}") + HttpHeaders getEventheaders(long date); + // *** OPTIONS *** @Options("/events/{year}/{location}") Set getEventOptions(String location, int year); + @Options("/events/{date}") + Set getEventOptions(long date); + // if you need to add some configuration to the Spring RestTemplate. RestTemplate getRestTemplate();