From d36dd397769037f270051ecca355809ad2c7baef Mon Sep 17 00:00:00 2001 From: Kay-Uwe Janssen Date: Sun, 7 Jun 2015 23:21:28 +0200 Subject: [PATCH 1/6] allow processing of method parameters --- .../internal/process/ModelProcessor.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/internal/process/ModelProcessor.java b/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/internal/process/ModelProcessor.java index 6d72dc6162..54d38ce432 100644 --- a/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/internal/process/ModelProcessor.java +++ b/AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/internal/process/ModelProcessor.java @@ -19,6 +19,7 @@ import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; import javax.lang.model.element.NestingKind; import javax.lang.model.element.TypeElement; @@ -110,6 +111,12 @@ public ProcessResult process(AnnotationElements validatedModel) throws Exception enclosingElement = annotatedElement; } else { enclosingElement = annotatedElement.getEnclosingElement(); + /* + * we are processing a method parameter + */ + if (enclosingElement instanceof ExecutableElement) { + enclosingElement = enclosingElement.getEnclosingElement(); + } } /* From 184c5eea578ff35742ff44191d7653a788449578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Simon?= Date: Sat, 10 Oct 2015 12:43:53 +0200 Subject: [PATCH 2/6] Extract Field and Part handlers --- .../rest/spring/RestSpringPlugin.java | 4 ++ .../spring/handler/AbstractParamHandler.java | 57 ++++++++++++++++ .../rest/spring/handler/FieldHandler.java | 36 ++++++++++ .../rest/spring/handler/PartHandler.java | 36 ++++++++++ .../rest/spring/handler/PostHandler.java | 68 +------------------ 5 files changed, 134 insertions(+), 67 deletions(-) create mode 100644 AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/AbstractParamHandler.java create mode 100644 AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/FieldHandler.java create mode 100644 AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PartHandler.java diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/RestSpringPlugin.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/RestSpringPlugin.java index b8638f954e..2db4df7a8d 100644 --- a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/RestSpringPlugin.java +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/RestSpringPlugin.java @@ -22,11 +22,13 @@ import org.androidannotations.handler.AnnotationHandler; import org.androidannotations.plugin.AndroidAnnotationsPlugin; import org.androidannotations.rest.spring.handler.DeleteHandler; +import org.androidannotations.rest.spring.handler.FieldHandler; import org.androidannotations.rest.spring.handler.GetHandler; import org.androidannotations.rest.spring.handler.HeadHandler; import org.androidannotations.rest.spring.handler.HeaderHandler; import org.androidannotations.rest.spring.handler.HeadersHandler; import org.androidannotations.rest.spring.handler.OptionsHandler; +import org.androidannotations.rest.spring.handler.PartHandler; import org.androidannotations.rest.spring.handler.PathHandler; import org.androidannotations.rest.spring.handler.PostHandler; import org.androidannotations.rest.spring.handler.PutHandler; @@ -46,6 +48,8 @@ public String getName() { public List> getHandlers(AndroidAnnotationsEnvironment androidAnnotationEnv) { List> annotationHandlers = new ArrayList<>(); annotationHandlers.add(new RestHandler(androidAnnotationEnv)); + annotationHandlers.add(new FieldHandler(androidAnnotationEnv)); + annotationHandlers.add(new PartHandler(androidAnnotationEnv)); annotationHandlers.add(new GetHandler(androidAnnotationEnv)); annotationHandlers.add(new PostHandler(androidAnnotationEnv)); annotationHandlers.add(new PutHandler(androidAnnotationEnv)); diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/AbstractParamHandler.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/AbstractParamHandler.java new file mode 100644 index 0000000000..b6b9cc2dcd --- /dev/null +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/AbstractParamHandler.java @@ -0,0 +1,57 @@ +/** + * Copyright (C) 2010-2015 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.spring.handler; + +import java.lang.annotation.Annotation; +import java.util.Arrays; +import java.util.List; + +import javax.lang.model.element.Element; + +import org.androidannotations.AndroidAnnotationsEnvironment; +import org.androidannotations.ElementValidation; +import org.androidannotations.handler.BaseAnnotationHandler; +import org.androidannotations.holder.GeneratedClassHolder; +import org.androidannotations.rest.spring.annotations.Patch; +import org.androidannotations.rest.spring.annotations.Post; +import org.androidannotations.rest.spring.annotations.Put; +import org.androidannotations.rest.spring.helper.RestSpringValidatorHelper; + +abstract class AbstractParamHandler extends BaseAnnotationHandler { + + public static final List> REST_METHOD_ANNOTATIONS_WITH_PARAM = Arrays.asList(Post.class, Put.class, Patch.class); + + protected final RestSpringValidatorHelper restSpringValidatorHelper; + + AbstractParamHandler(Class targetClass, AndroidAnnotationsEnvironment environment) { + super(targetClass, environment); + restSpringValidatorHelper = new RestSpringValidatorHelper(environment, getTarget()); + } + + @Override + protected void validate(Element element, ElementValidation validation) { + validatorHelper.enclosingElementHasOneOfAnnotations(element, REST_METHOD_ANNOTATIONS_WITH_PARAM, validation); + + restSpringValidatorHelper.doesNotHavePathAnnotation(element, validation); + + restSpringValidatorHelper.restInterfaceHasFormConverter(element, validation); + } + + @Override + public void process(Element element, GeneratedClassHolder holder) throws Exception { + // Don't do anything here. + } +} diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/FieldHandler.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/FieldHandler.java new file mode 100644 index 0000000000..8ed3395328 --- /dev/null +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/FieldHandler.java @@ -0,0 +1,36 @@ +/** + * Copyright (C) 2010-2015 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.spring.handler; + +import javax.lang.model.element.Element; + +import org.androidannotations.AndroidAnnotationsEnvironment; +import org.androidannotations.ElementValidation; +import org.androidannotations.rest.spring.annotations.Field; + +public class FieldHandler extends AbstractParamHandler { + + public FieldHandler(AndroidAnnotationsEnvironment environment) { + super(Field.class, environment); + } + + @Override + protected void validate(Element element, ElementValidation validation) { + super.validate(element, validation); + + restSpringValidatorHelper.doesNotHavePartAnnotation(element, validation); + } +} diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PartHandler.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PartHandler.java new file mode 100644 index 0000000000..f334c46b4c --- /dev/null +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PartHandler.java @@ -0,0 +1,36 @@ +/** + * Copyright (C) 2010-2015 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.spring.handler; + +import javax.lang.model.element.Element; + +import org.androidannotations.AndroidAnnotationsEnvironment; +import org.androidannotations.ElementValidation; +import org.androidannotations.rest.spring.annotations.Part; + +public class PartHandler extends AbstractParamHandler { + + public PartHandler(AndroidAnnotationsEnvironment environment) { + super(Part.class, environment); + } + + @Override + protected void validate(Element element, ElementValidation validation) { + super.validate(element, validation); + + restSpringValidatorHelper.doesNotHaveFieldAnnotation(element, validation); + } +} diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PostHandler.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PostHandler.java index 363c0f9165..727487f853 100644 --- a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PostHandler.java +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PostHandler.java @@ -15,7 +15,6 @@ */ package org.androidannotations.rest.spring.handler; -import java.util.Arrays; import java.util.Map; import java.util.SortedMap; @@ -24,12 +23,6 @@ import org.androidannotations.AndroidAnnotationsEnvironment; import org.androidannotations.ElementValidation; -import org.androidannotations.handler.AnnotationHandler; -import org.androidannotations.handler.BaseAnnotationHandler; -import org.androidannotations.handler.HasParameterHandlers; -import org.androidannotations.holder.GeneratedClassHolder; -import org.androidannotations.rest.spring.annotations.Field; -import org.androidannotations.rest.spring.annotations.Part; import org.androidannotations.rest.spring.annotations.Post; import org.androidannotations.rest.spring.helper.RestSpringClasses; import org.androidannotations.rest.spring.holder.RestHolder; @@ -40,20 +33,10 @@ import com.helger.jcodemodel.JExpr; import com.helger.jcodemodel.JVar; -public class PostHandler extends RestMethodHandler implements HasParameterHandlers { - - private FieldHandler fieldHandler; - private PartHandler partHandler; +public class PostHandler extends RestMethodHandler { public PostHandler(AndroidAnnotationsEnvironment environment) { super(Post.class, environment); - fieldHandler = new FieldHandler(environment); - partHandler = new PartHandler(environment); - } - - @Override - public Iterable getParameterHandlers() { - return Arrays. asList(fieldHandler, partHandler); } @Override @@ -93,53 +76,4 @@ protected IJExpression getRequestEntity(ExecutableElement element, RestHolder ho return restAnnotationHelper.declareHttpEntity(methodBody, entitySentToServer, httpHeaders); } - - private abstract class AbstractPostParamHandler extends BaseAnnotationHandler { - - AbstractPostParamHandler(Class targetClass, AndroidAnnotationsEnvironment environment) { - super(targetClass, environment); - } - - @Override - protected void validate(Element element, ElementValidation validation) { - validatorHelper.enclosingElementHasAnnotation(Post.class, element, validation); - - restSpringValidatorHelper.doesNotHavePathAnnotation(element, validation); - - restSpringValidatorHelper.restInterfaceHasFormConverter(element, validation); - } - - @Override - public void process(Element element, GeneratedClassHolder holder) throws Exception { - // Don't do anything here. - } - } - - public class FieldHandler extends AbstractPostParamHandler { - - public FieldHandler(AndroidAnnotationsEnvironment environment) { - super(Field.class, environment); - } - - @Override - protected void validate(Element element, ElementValidation validation) { - super.validate(element, validation); - - restSpringValidatorHelper.doesNotHavePartAnnotation(element, validation); - } - } - - public class PartHandler extends AbstractPostParamHandler { - - public PartHandler(AndroidAnnotationsEnvironment environment) { - super(Part.class, environment); - } - - @Override - protected void validate(Element element, ElementValidation validation) { - super.validate(element, validation); - - restSpringValidatorHelper.doesNotHaveFieldAnnotation(element, validation); - } - } } From 1a4a95b78ef844c48985e7f6c4dbec0cdfb145b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Simon?= Date: Sat, 10 Oct 2015 13:27:32 +0200 Subject: [PATCH 3/6] Create abstract handler to method with parameters --- ...bstractRestMethodWithParameterHandler.java | 72 +++++++++++++++++++ .../rest/spring/handler/PostHandler.java | 47 +----------- .../rest/spring/handler/PutHandler.java | 13 +--- .../spring/helper/RestAnnotationHelper.java | 16 ++--- .../helper/RestSpringValidatorHelper.java | 10 +-- 5 files changed, 87 insertions(+), 71 deletions(-) create mode 100644 AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/AbstractRestMethodWithParameterHandler.java diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/AbstractRestMethodWithParameterHandler.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/AbstractRestMethodWithParameterHandler.java new file mode 100644 index 0000000000..815d2cd21d --- /dev/null +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/AbstractRestMethodWithParameterHandler.java @@ -0,0 +1,72 @@ +/** + * Copyright (C) 2010-2015 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.spring.handler; + +import java.util.Map; +import java.util.SortedMap; + +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; + +import org.androidannotations.AndroidAnnotationsEnvironment; +import org.androidannotations.ElementValidation; +import org.androidannotations.rest.spring.helper.RestSpringClasses; +import org.androidannotations.rest.spring.holder.RestHolder; + +import com.helger.jcodemodel.AbstractJClass; +import com.helger.jcodemodel.IJExpression; +import com.helger.jcodemodel.JBlock; +import com.helger.jcodemodel.JExpr; +import com.helger.jcodemodel.JVar; + +public abstract class AbstractRestMethodWithParameterHandler extends RestMethodHandler { + + public AbstractRestMethodWithParameterHandler(Class targetClass, AndroidAnnotationsEnvironment environment) { + super(targetClass, environment); + } + + @Override + public void validate(Element element, ElementValidation validation) { + super.validate(element, validation); + + validatorHelper.doesNotReturnPrimitive((ExecutableElement) element, validation); + + restSpringValidatorHelper.urlVariableNamesExistInParametersAndHasOnlyOneEntityParameterOrOneOrMoreParameter((ExecutableElement) element, validation); + + restSpringValidatorHelper.doesNotMixPartAndFieldAnnotations((ExecutableElement) element, validation); + } + + @Override + protected IJExpression getRequestEntity(ExecutableElement element, RestHolder holder, JBlock methodBody, SortedMap params) { + JVar httpHeaders = restAnnotationHelper.declareHttpHeaders(element, holder, methodBody); + JVar entitySentToServer = restAnnotationHelper.getEntitySentToServer(element, params); + + if (entitySentToServer == null) { + Map parameters = restAnnotationHelper.extractFieldAndPartParameters(element); + + if (parameters != null) { + AbstractJClass hashMapClass = getJClass(RestSpringClasses.LINKED_MULTI_VALUE_MAP).narrow(String.class, Object.class); + entitySentToServer = methodBody.decl(hashMapClass, "parameters", JExpr._new(hashMapClass)); + + for (Map.Entry parameter : parameters.entrySet()) { + methodBody.add(entitySentToServer.invoke("add").arg(JExpr.lit(parameter.getKey())).arg(params.get(parameter.getValue()))); + } + } + } + + return restAnnotationHelper.declareHttpEntity(methodBody, entitySentToServer, httpHeaders); + } +} diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PostHandler.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PostHandler.java index 727487f853..652dbe4c67 100644 --- a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PostHandler.java +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PostHandler.java @@ -15,65 +15,20 @@ */ package org.androidannotations.rest.spring.handler; -import java.util.Map; -import java.util.SortedMap; - import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; import org.androidannotations.AndroidAnnotationsEnvironment; -import org.androidannotations.ElementValidation; import org.androidannotations.rest.spring.annotations.Post; -import org.androidannotations.rest.spring.helper.RestSpringClasses; -import org.androidannotations.rest.spring.holder.RestHolder; - -import com.helger.jcodemodel.AbstractJClass; -import com.helger.jcodemodel.IJExpression; -import com.helger.jcodemodel.JBlock; -import com.helger.jcodemodel.JExpr; -import com.helger.jcodemodel.JVar; -public class PostHandler extends RestMethodHandler { +public class PostHandler extends AbstractRestMethodWithParameterHandler { public PostHandler(AndroidAnnotationsEnvironment environment) { super(Post.class, environment); } - @Override - public void validate(Element element, ElementValidation validation) { - super.validate(element, validation); - - validatorHelper.doesNotReturnPrimitive((ExecutableElement) element, validation); - - restSpringValidatorHelper.urlVariableNamesExistInParametersAndHasOnlyOneEntityParameterOrOneOrMorePostParameter((ExecutableElement) element, validation); - - restSpringValidatorHelper.doesNotMixPartAndFieldAnnotations((ExecutableElement) element, validation); - } - @Override protected String getUrlSuffix(Element element) { Post annotation = element.getAnnotation(Post.class); return annotation.value(); } - - @Override - protected IJExpression getRequestEntity(ExecutableElement element, RestHolder holder, JBlock methodBody, SortedMap params) { - JVar httpHeaders = restAnnotationHelper.declareHttpHeaders(element, holder, methodBody); - JVar entitySentToServer = restAnnotationHelper.getEntitySentToServer(element, params); - - if (entitySentToServer == null) { - Map postParameters = restAnnotationHelper.extractPostParameters(element); - - if (postParameters != null) { - AbstractJClass hashMapClass = getJClass(RestSpringClasses.LINKED_MULTI_VALUE_MAP).narrow(String.class, Object.class); - entitySentToServer = methodBody.decl(hashMapClass, "postParameters", JExpr._new(hashMapClass)); - - for (Map.Entry postParameter : postParameters.entrySet()) { - methodBody.add(entitySentToServer.invoke("add").arg(JExpr.lit(postParameter.getKey())).arg(params.get(postParameter.getValue()))); - } - } - } - - return restAnnotationHelper.declareHttpEntity(methodBody, entitySentToServer, httpHeaders); - } } diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PutHandler.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PutHandler.java index 0d89ae98d0..d7bef33024 100644 --- a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PutHandler.java +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PutHandler.java @@ -16,27 +16,16 @@ package org.androidannotations.rest.spring.handler; import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; import org.androidannotations.AndroidAnnotationsEnvironment; -import org.androidannotations.ElementValidation; import org.androidannotations.rest.spring.annotations.Put; -public class PutHandler extends RestMethodHandler { +public class PutHandler extends AbstractRestMethodWithParameterHandler { public PutHandler(AndroidAnnotationsEnvironment environment) { super(Put.class, environment); } - @Override - public void validate(Element element, ElementValidation validation) { - super.validate(element, validation); - - validatorHelper.doesNotReturnPrimitive((ExecutableElement) element, validation); - - restSpringValidatorHelper.urlVariableNamesExistInParametersAndHasOnlyOneMoreParameter((ExecutableElement) element, validation); - } - @Override protected String getUrlSuffix(Element element) { Put annotation = element.getAnnotation(Put.class); 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 c176b8942d..46d57749c5 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 @@ -573,30 +573,30 @@ public IJExpression nullCastedToNarrowedClass(RestHolder holder) { * Returns the post parameter name to method parameter name mapping, or null * if duplicate names found. */ - public Map extractPostParameters(ExecutableElement element) { + public Map extractFieldAndPartParameters(ExecutableElement element) { Map postParameterNameToElementName = new HashMap(); for (VariableElement parameter : element.getParameters()) { - String postParameterName = null; + String parameterName = null; if (parameter.getAnnotation(Field.class) != null) { - postParameterName = extractPostParameter(parameter, Field.class); + parameterName = extractParameter(parameter, Field.class); } else if (parameter.getAnnotation(Part.class) != null) { - postParameterName = extractPostParameter(parameter, Part.class); + parameterName = extractParameter(parameter, Part.class); } - if (postParameterName != null) { - if (postParameterNameToElementName.containsKey(postParameterName)) { + if (parameterName != null) { + if (postParameterNameToElementName.containsKey(parameterName)) { return null; } - postParameterNameToElementName.put(postParameterName, parameter.getSimpleName().toString()); + postParameterNameToElementName.put(parameterName, parameter.getSimpleName().toString()); } } return postParameterNameToElementName; } - private String extractPostParameter(VariableElement parameter, Class clazz) { + private String extractParameter(VariableElement parameter, Class clazz) { String value = extractAnnotationParameter(parameter, clazz.getCanonicalName(), "value"); return !value.equals("") ? value : parameter.getSimpleName().toString(); diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/helper/RestSpringValidatorHelper.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/helper/RestSpringValidatorHelper.java index cb58c000d6..697cd90bad 100644 --- a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/helper/RestSpringValidatorHelper.java +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/helper/RestSpringValidatorHelper.java @@ -419,26 +419,26 @@ public void urlVariableNamesExistInParametersAndHasOnlyOneMoreParameter(Executab } } - public void urlVariableNamesExistInParametersAndHasOnlyOneEntityParameterOrOneOrMorePostParameter(ExecutableElement element, ElementValidation validation) { + public void urlVariableNamesExistInParametersAndHasOnlyOneEntityParameterOrOneOrMoreParameter(ExecutableElement element, ElementValidation validation) { if (validation.isValid()) { Set variableNames = restAnnotationHelper.extractUrlVariableNames(element); urlVariableNamesExistInParameters(element, variableNames, validation); if (validation.isValid()) { List parameters = element.getParameters(); - Map postParameters = restAnnotationHelper.extractPostParameters(element); + Map fieldAndPartParameters = restAnnotationHelper.extractFieldAndPartParameters(element); - if (postParameters == null) { + if (fieldAndPartParameters == null) { validation.addError(element, "%s annotated method has multiple form parameters with the same name"); return; } - if (!postParameters.isEmpty() && postParameters.size() + variableNames.size() < parameters.size()) { + if (!fieldAndPartParameters.isEmpty() && fieldAndPartParameters.size() + variableNames.size() < parameters.size()) { validation.addError(element, "%s method cannot have both entity parameter and @Field annotated parameters"); return; } - if (postParameters.isEmpty() && parameters.size() > variableNames.size() + 1) { + if (fieldAndPartParameters.isEmpty() && parameters.size() > variableNames.size() + 1) { validation.addError(element, "%s annotated method has more than one entity parameter"); } } From 38229c2baffe1badccb511f9d1e1f392a538ae62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Simon?= Date: Sat, 10 Oct 2015 13:28:00 +0200 Subject: [PATCH 4/6] Create @Patch Rest method --- .../rest/spring/annotations/Patch.java | 67 +++++++++++++++++++ .../rest/spring/RestSpringPlugin.java | 2 + .../rest/spring/handler/PatchHandler.java | 42 ++++++++++++ .../helper/RestSpringValidatorHelper.java | 6 ++ 4 files changed, 117 insertions(+) create mode 100644 AndroidAnnotations/androidannotations-rest-spring/rest-spring-api/src/main/java/org/androidannotations/rest/spring/annotations/Patch.java create mode 100644 AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PatchHandler.java diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring-api/src/main/java/org/androidannotations/rest/spring/annotations/Patch.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring-api/src/main/java/org/androidannotations/rest/spring/annotations/Patch.java new file mode 100644 index 0000000000..aaf69a1899 --- /dev/null +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring-api/src/main/java/org/androidannotations/rest/spring/annotations/Patch.java @@ -0,0 +1,67 @@ +/** + * Copyright (C) 2010-2015 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.spring.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + *

+ * Use on methods in {@link Rest} annotated class to add a new rest service of + * type PATCH. + *

+ *

+ * This annotation as the EXACT same constraints as {@link Post}. + *

+ *
+ * + * Example : + * + *
+ * @Rest(rootUrl = "http://myserver", converters = MappingJacksonHttpMessageConverter.class)
+ * public interface MyRestClient {
+ * 
+ * 	@Patch("/events/update/last")
+ * 	Event updateEvent();
+ * 
+ * 	@Patch("/events/update/{id}")
+ * 	void updateEvent(Event event, int id);
+ * }
+ * 
+ * + *
+ * + * @see Rest + * @see Put + * @see Get + * @see Post + * @see Delete + * @see Head + * @see Options + */ +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.METHOD) +public @interface Patch { + + /** + * The URI or the full URL of the web service. + * + * @return the address of the web service + */ + String value(); +} diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/RestSpringPlugin.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/RestSpringPlugin.java index 2db4df7a8d..32f41a479e 100644 --- a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/RestSpringPlugin.java +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/RestSpringPlugin.java @@ -29,6 +29,7 @@ import org.androidannotations.rest.spring.handler.HeadersHandler; import org.androidannotations.rest.spring.handler.OptionsHandler; import org.androidannotations.rest.spring.handler.PartHandler; +import org.androidannotations.rest.spring.handler.PatchHandler; import org.androidannotations.rest.spring.handler.PathHandler; import org.androidannotations.rest.spring.handler.PostHandler; import org.androidannotations.rest.spring.handler.PutHandler; @@ -53,6 +54,7 @@ public List> getHandlers(AndroidAnnotationsEnvironment andr annotationHandlers.add(new GetHandler(androidAnnotationEnv)); annotationHandlers.add(new PostHandler(androidAnnotationEnv)); annotationHandlers.add(new PutHandler(androidAnnotationEnv)); + annotationHandlers.add(new PatchHandler(androidAnnotationEnv)); annotationHandlers.add(new DeleteHandler(androidAnnotationEnv)); annotationHandlers.add(new HeadHandler(androidAnnotationEnv)); annotationHandlers.add(new OptionsHandler(androidAnnotationEnv)); diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PatchHandler.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PatchHandler.java new file mode 100644 index 0000000000..ce8f2b2812 --- /dev/null +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/handler/PatchHandler.java @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2010-2015 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.spring.handler; + +import javax.lang.model.element.Element; + +import org.androidannotations.AndroidAnnotationsEnvironment; +import org.androidannotations.ElementValidation; +import org.androidannotations.rest.spring.annotations.Patch; + +public class PatchHandler extends AbstractRestMethodWithParameterHandler { + + public PatchHandler(AndroidAnnotationsEnvironment environment) { + super(Patch.class, environment); + } + + @Override + public void validate(Element element, ElementValidation validation) { + super.validate(element, validation); + + restSpringValidatorHelper.usesSpringAndroid2(element, validation); + } + + @Override + protected String getUrlSuffix(Element element) { + Patch annotation = element.getAnnotation(Patch.class); + return annotation.value(); + } +} diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/helper/RestSpringValidatorHelper.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/helper/RestSpringValidatorHelper.java index 697cd90bad..67305834ff 100644 --- a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/helper/RestSpringValidatorHelper.java +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/main/java/org/androidannotations/rest/spring/helper/RestSpringValidatorHelper.java @@ -567,4 +567,10 @@ public void restInterfaceHasFormConverter(Element element, ElementValidation val public void elementHasOneOfRestMethodAnnotations(Element element, ElementValidation validation) { hasOneOfAnnotations(element, element, REST_ANNOTATION_CLASSES, validation); } + + public void usesSpringAndroid2(Element element, ElementValidation validation) { + if (environment().getProcessingEnvironment().getElementUtils().getTypeElement(RestSpringClasses.PARAMETERIZED_TYPE_REFERENCE) != null) { + validation.addError(element, "To use %s annotated method you must add Spring Android Rest Template 2.0 to your classpath"); + } + } } From 64b57128e23c903a9523727634ffc8005f8b8c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Simon?= Date: Sat, 10 Oct 2015 16:27:37 +0200 Subject: [PATCH 5/6] Update JavaDoc for Field and Part --- .../rest/spring/annotations/Field.java | 8 +++++--- .../rest/spring/annotations/Part.java | 20 ++++++++++--------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring-api/src/main/java/org/androidannotations/rest/spring/annotations/Field.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring-api/src/main/java/org/androidannotations/rest/spring/annotations/Field.java index 6ddf056d1b..00e1535108 100644 --- a/AndroidAnnotations/androidannotations-rest-spring/rest-spring-api/src/main/java/org/androidannotations/rest/spring/annotations/Field.java +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring-api/src/main/java/org/androidannotations/rest/spring/annotations/Field.java @@ -25,9 +25,9 @@ * from a method parameter. The annotation value should be the name of the * form-encoded parameter, if not specified, the method parameter name will be * used as the name of the form-encoded parameter. This annotation only can be - * used with POST requests, hence the method must be annotated with {@link Post} - * . To use this annotation, you must add FormHttpMessageConverter - * to the list of converters. + * used with a method which be annotated with {@link Post}, {@link Put} or + * {@link Patch}. To use this annotation, you must add + * FormHttpMessageConverter to the list of converters. * *
* @@ -46,6 +46,8 @@ * * @see Rest * @see Post + * @see Put + * @see Patch * @see Part */ @Retention(RetentionPolicy.CLASS) diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring-api/src/main/java/org/androidannotations/rest/spring/annotations/Part.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring-api/src/main/java/org/androidannotations/rest/spring/annotations/Part.java index 5c0738c71c..b21aed29a4 100644 --- a/AndroidAnnotations/androidannotations-rest-spring/rest-spring-api/src/main/java/org/androidannotations/rest/spring/annotations/Part.java +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring-api/src/main/java/org/androidannotations/rest/spring/annotations/Part.java @@ -21,13 +21,13 @@ import java.lang.annotation.Target; /** - * This annotation can be used to add a multi-part parameter to the POST request - * from a method parameter. The annotation value should be the name of the - * multi-part parameter, if not specified, the method parameter name will be - * used as the name of the multi-part parameter. This annotation only can be - * used with POST requests, hence the method must be annotated with {@link Post} - * . To use this annotation, you must add FormHttpMessageConverter - * to the list of converters. + * This annotation can be used to add a multi-part parameter to the POST, PUT or + * PATCH request from a method parameter. The annotation value should be the + * name of the multi-part parameter, if not specified, the method parameter name + * will be used as the name of the multi-part parameter. This annotation only + * can be used with a method which be annotated with {@link Post}, {@link Put} + * or {@link Patch}. To use this annotation, you must add + * FormHttpMessageConverter to the list of converters. * *
* @@ -44,9 +44,11 @@ * *
* - * @see Post - * @see Part * @see Rest + * @see Post + * @see Put + * @see Patch + * @see Field */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.PARAMETER) From 18377141ab80eedea24ca739b4934751efe94c4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Simon?= Date: Sat, 10 Oct 2015 21:44:12 +0200 Subject: [PATCH 6/6] Compile test for @Part and @Param with @Put --- .../rest/spring/ClientWithParameters.java | 38 +++++++++++++++++++ .../rest/spring/RestTest.java | 6 +++ 2 files changed, 44 insertions(+) create mode 100644 AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/test/java/org/androidannotations/rest/spring/ClientWithParameters.java diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/test/java/org/androidannotations/rest/spring/ClientWithParameters.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/test/java/org/androidannotations/rest/spring/ClientWithParameters.java new file mode 100644 index 0000000000..0bbade12b1 --- /dev/null +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/test/java/org/androidannotations/rest/spring/ClientWithParameters.java @@ -0,0 +1,38 @@ +/** + * Copyright (C) 2010-2015 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.spring; + +import org.androidannotations.rest.spring.annotations.Field; +import org.androidannotations.rest.spring.annotations.Put; +import org.androidannotations.rest.spring.annotations.Rest; +import org.springframework.http.converter.FormHttpMessageConverter; + +@Rest(converters = FormHttpMessageConverter.class) +public interface ClientWithParameters { + + @Put("/") + void oneParameter(@Field int id); + + @Put("/") + void oneParameterWithName(@Field("identifier") int id); + + @Put("/") + void moreParameter(@Field int id, @Field String str); + + @Put("/{url}") + void oneParameterWithUrl(@Field int id, String url); + +} diff --git a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/test/java/org/androidannotations/rest/spring/RestTest.java b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/test/java/org/androidannotations/rest/spring/RestTest.java index 6d220c83ba..9287e8df53 100644 --- a/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/test/java/org/androidannotations/rest/spring/RestTest.java +++ b/AndroidAnnotations/androidannotations-rest-spring/rest-spring/src/test/java/org/androidannotations/rest/spring/RestTest.java @@ -112,6 +112,12 @@ public void clientWithWrongPostParameters() throws IOException { assertCompilationErrorCount(11, result); } + @Test + public void clientWithParameters() throws IOException { + CompileResult result = compileFiles(ClientWithParameters.class); + assertCompilationSuccessful(result); + } + @Test public void fieldPathParamOnSameArgument() throws IOException { CompileResult result = compileFiles(FieldPathParamOnSameArgument.class);