diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/AndroidAnnotationProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/AndroidAnnotationProcessor.java
index ee2e3eee84..5982e7e25d 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/AndroidAnnotationProcessor.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/AndroidAnnotationProcessor.java
@@ -549,14 +549,14 @@ private ModelProcessor buildModelProcessor(IRClass rClass, AndroidSystemServices
modelProcessor.register(new ExtraProcessor(processingEnv));
modelProcessor.register(new FragmentArgProcessor(processingEnv));
modelProcessor.register(new SystemServiceProcessor(androidSystemServices));
- RestImplementationsHolder restImplementationHolder = new RestImplementationsHolder();
- modelProcessor.register(new RestProcessor(processingEnv, restImplementationHolder));
- modelProcessor.register(new GetProcessor(processingEnv, restImplementationHolder));
- modelProcessor.register(new PostProcessor(processingEnv, restImplementationHolder));
- modelProcessor.register(new PutProcessor(processingEnv, restImplementationHolder));
- modelProcessor.register(new DeleteProcessor(processingEnv, restImplementationHolder));
- modelProcessor.register(new HeadProcessor(processingEnv, restImplementationHolder));
- modelProcessor.register(new OptionsProcessor(processingEnv, restImplementationHolder));
+ RestImplementationsHolder restImplementationsHolder = new RestImplementationsHolder();
+ modelProcessor.register(new RestProcessor(processingEnv, restImplementationsHolder));
+ modelProcessor.register(new GetProcessor(processingEnv, restImplementationsHolder));
+ modelProcessor.register(new PostProcessor(processingEnv, restImplementationsHolder));
+ modelProcessor.register(new PutProcessor(processingEnv, restImplementationsHolder));
+ modelProcessor.register(new DeleteProcessor(processingEnv, restImplementationsHolder));
+ modelProcessor.register(new HeadProcessor(processingEnv, restImplementationsHolder));
+ modelProcessor.register(new OptionsProcessor(processingEnv, restImplementationsHolder));
modelProcessor.register(new AppProcessor());
modelProcessor.register(new OptionsMenuProcessor(processingEnv, rClass));
modelProcessor.register(new OptionsItemProcessor(processingEnv, rClass));
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/APTCodeModelHelper.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/APTCodeModelHelper.java
index f8e79f5f50..83d9546267 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/APTCodeModelHelper.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/APTCodeModelHelper.java
@@ -34,9 +34,11 @@
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.WildcardType;
import org.androidannotations.processing.EBeanHolder;
import org.androidannotations.processing.EBeansHolder.Classes;
+
import com.sun.codemodel.JBlock;
import com.sun.codemodel.JCatchBlock;
import com.sun.codemodel.JClass;
@@ -78,6 +80,16 @@ public JClass typeMirrorToJClass(TypeMirror type, EBeanHolder holder) {
}
return declaredClass;
+ } else if (type instanceof WildcardType) {
+ // TODO : At his time (01/2013), it is not possible to handle the
+ // super bound because code model does not offer a way to model
+ // statement like " ? super X"
+ // (see http://java.net/jira/browse/CODEMODEL-11)
+ WildcardType wildcardType = (WildcardType) type;
+
+ TypeMirror extendsBound = wildcardType.getExtendsBound();
+
+ return typeMirrorToJClass(extendsBound, holder).wildcard();
} else if (type instanceof ArrayType) {
ArrayType arrayType = (ArrayType) type;
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/CanonicalNameConstants.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/CanonicalNameConstants.java
index df038444fb..fc4d8aa281 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/CanonicalNameConstants.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/CanonicalNameConstants.java
@@ -17,7 +17,10 @@
import java.net.URI;
import java.sql.SQLException;
+import java.util.Collection;
import java.util.Collections;
+import java.util.List;
+import java.util.Map;
import java.util.Set;
public final class CanonicalNameConstants {
@@ -25,8 +28,12 @@ public final class CanonicalNameConstants {
/*
* Java
*/
+ public static final String OBJECT = Object.class.getCanonicalName();
public static final String URI = URI.class.getCanonicalName();
+ public static final String MAP = Map.class.getCanonicalName();
public static final String SET = Set.class.getCanonicalName();
+ public static final String LIST = List.class.getCanonicalName();
+ public static final String COLLECTION = Collection.class.getCanonicalName();
public static final String COLLECTIONS = Collections.class.getCanonicalName();
public static final String STRING = String.class.getCanonicalName();
public static final String CHAR_SEQUENCE = CharSequence.class.getCanonicalName();
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/Option.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/Option.java
index 9d06e14cc5..7f3573fc35 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/Option.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/Option.java
@@ -1,3 +1,18 @@
+/**
+ * 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.helper;
/**
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EBeanHolder.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EBeanHolder.java
index 62dbeb33a6..a80f3733ce 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EBeanHolder.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EBeanHolder.java
@@ -140,6 +140,10 @@ public JClass refClass(Class> clazz) {
return eBeansHolder.refClass(clazz);
}
+ public JDefinedClass definedClass(String fullyQualifiedClassName) {
+ return eBeansHolder.definedClass(fullyQualifiedClassName);
+ }
+
public void generateApiClass(Element originatingElement, Class> apiClass) {
eBeansHolder.generateApiClass(originatingElement, apiClass);
}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EBeansHolder.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EBeansHolder.java
index 090d001e82..afd39e6924 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EBeansHolder.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EBeansHolder.java
@@ -30,6 +30,7 @@
import org.androidannotations.helper.CanonicalNameConstants;
import com.sun.codemodel.JClass;
+import com.sun.codemodel.JClassAlreadyExistsException;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
@@ -178,6 +179,10 @@ public EBeanHolder getEBeanHolder(Element element) {
return eBeanHolders.get(element);
}
+ public JClass refClass(Class> clazz) {
+ return codeModel.ref(clazz);
+ }
+
public JClass refClass(String fullyQualifiedClassName) {
int arrayCounter = 0;
@@ -200,8 +205,33 @@ public JClass refClass(String fullyQualifiedClassName) {
return refClass;
}
- public JClass refClass(Class> clazz) {
- return codeModel.ref(clazz);
+ public JDefinedClass definedClass(String fullyQualifiedClassName) {
+ JDefinedClass refClass = (JDefinedClass) loadedClasses.get(fullyQualifiedClassName);
+ if (refClass == null) {
+ try {
+ refClass = codeModel._class(fullyQualifiedClassName);
+ } catch (JClassAlreadyExistsException e) {
+ refClass = (JDefinedClass) refClass(fullyQualifiedClassName);
+ }
+ loadedClasses.put(fullyQualifiedClassName, refClass);
+ }
+ return refClass;
+ }
+
+ /**
+ * Return a unique JClass reference by using {@link JCodeModel#ref(String)}
+ * and keeping a buffer.
+ *
+ * @param fullyQualifiedClassName
+ * @return
+ */
+ JClass uniqueClass(String fullyQualifiedClassName) {
+ JClass refClass = loadedClasses.get(fullyQualifiedClassName);
+ if (refClass == null) {
+ refClass = codeModel.directClass(fullyQualifiedClassName);
+ loadedClasses.put(fullyQualifiedClassName, refClass);
+ }
+ return refClass;
}
public JCodeModel codeModel() {
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/DeleteProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/DeleteProcessor.java
index 24d20051c9..a75803b49f 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/DeleteProcessor.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/DeleteProcessor.java
@@ -23,18 +23,13 @@
import org.androidannotations.annotations.rest.Delete;
import org.androidannotations.processing.EBeanHolder;
-import com.sun.codemodel.JBlock;
+
import com.sun.codemodel.JCodeModel;
-import com.sun.codemodel.JExpr;
-import com.sun.codemodel.JInvocation;
-import com.sun.codemodel.JVar;
public class DeleteProcessor extends MethodProcessor {
- private EBeanHolder holder;
-
- public DeleteProcessor(ProcessingEnvironment processingEnv, RestImplementationsHolder restImplementationHolder) {
- super(processingEnv, restImplementationHolder);
+ public DeleteProcessor(ProcessingEnvironment processingEnv, RestImplementationsHolder restImplementationsHolder) {
+ super(processingEnv, restImplementationsHolder);
}
@Override
@@ -45,7 +40,6 @@ public Class extends Annotation> getTarget() {
@Override
public void process(Element element, JCodeModel codeModel, EBeanHolder holder) throws Exception {
- this.holder = holder;
ExecutableElement executableElement = (ExecutableElement) element;
Delete deleteAnnotation = element.getAnnotation(Delete.class);
@@ -54,25 +48,4 @@ public void process(Element element, JCodeModel codeModel, EBeanHolder holder) t
generateRestTemplateCallBlock(new MethodProcessorHolder(holder, executableElement, urlSuffix, null, null, codeModel));
}
- @Override
- protected JInvocation addHttpEntityVar(JInvocation restCall, MethodProcessorHolder methodHolder) {
- return restCall.arg(JExpr._null());
- }
-
- @Override
- protected JInvocation addResponseEntityArg(JInvocation restCall, MethodProcessorHolder methodHolder) {
- return restCall.arg(JExpr._null());
-
- }
-
- @Override
- protected JInvocation addResultCallMethod(JInvocation restCall, MethodProcessorHolder methodHolder) {
- return restCall;
- }
-
- @Override
- protected JVar addHttpHeadersVar(JBlock body, ExecutableElement executableElement) {
- return generateHttpHeadersVar(holder, body, executableElement);
- }
-
}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/GetPostProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/GetPostProcessor.java
new file mode 100644
index 0000000000..55fececf57
--- /dev/null
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/GetPostProcessor.java
@@ -0,0 +1,283 @@
+/**
+ * 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.processing.rest;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.WildcardType;
+
+import org.androidannotations.helper.APTCodeModelHelper;
+import org.androidannotations.helper.CanonicalNameConstants;
+import org.androidannotations.processing.EBeanHolder;
+
+import com.sun.codemodel.JClass;
+import com.sun.codemodel.JCodeModel;
+import com.sun.codemodel.JDefinedClass;
+import com.sun.codemodel.JExpr;
+import com.sun.codemodel.JInvocation;
+import com.sun.codemodel.JPackage;
+
+public abstract class GetPostProcessor extends MethodProcessor {
+
+ protected EBeanHolder holder;
+
+ /**
+ * Will be use to generate specific classes
+ */
+ protected JPackage restClientPackage;
+
+ protected APTCodeModelHelper helper;
+
+ public GetPostProcessor(ProcessingEnvironment processingEnv, RestImplementationsHolder restImplementationsHolder) {
+ super(processingEnv, restImplementationsHolder);
+ helper = new APTCodeModelHelper();
+ }
+
+ @Override
+ public void process(Element element, JCodeModel codeModel, EBeanHolder holder) {
+ this.holder = holder;
+ restClientPackage = restImplementationsHolder.getEnclosingHolder(element).restImplementationClass._package();
+
+ String urlSuffix = retrieveUrlSuffix(element);
+
+ ExecutableElement executableElement = (ExecutableElement) element;
+ MethodProcessorHolder processorHolder = new MethodProcessorHolder(holder, executableElement, urlSuffix, null, null, codeModel);
+
+ // Retrieve return type
+ TypeMirror returnType = executableElement.getReturnType();
+ if (returnType.getKind() != TypeKind.VOID) {
+ retrieveReturnAndExpectedClasses(returnType, processorHolder);
+ }
+
+ generateRestTemplateCallBlock(processorHolder);
+ }
+
+ public abstract String retrieveUrlSuffix(Element element);
+
+ /**
+ * Retrieve the expected and method return classes to use in generated code.
+ *
+ * If the annotated method return a ResponseEntity<T> then :
+ *
+ *
+ * expectedClass = T.class, methodReturnClass = ResponseEntity<T>
+ *
+ *
+ *
+ * @param returnType
+ * @param processorHolder
+ */
+ public void retrieveReturnAndExpectedClasses(TypeMirror returnType, MethodProcessorHolder processorHolder) {
+ String returnTypeString = returnType.toString();
+
+ JClass expectedClass = null;
+ JClass returnClass = helper.typeMirrorToJClass(returnType, holder);
+
+ if (returnTypeString.startsWith(CanonicalNameConstants.RESPONSE_ENTITY)) {
+ DeclaredType declaredReturnType = (DeclaredType) returnType;
+ if (declaredReturnType.getTypeArguments().size() > 0) {
+ expectedClass = resolveExpectedClass(declaredReturnType.getTypeArguments().get(0));
+ } else {
+ expectedClass = holder.refClass(CanonicalNameConstants.RESPONSE_ENTITY);
+ }
+ } else {
+ expectedClass = resolveExpectedClass(returnType);
+ }
+
+ processorHolder.setExpectedClass(expectedClass);
+ processorHolder.setMethodReturnClass(returnClass);
+ }
+
+ /**
+ * Resolve the expected class for the input type according to the following
+ * rules :
+ *
+ * - The type is a primitive : Directly return the JClass as usual
+ * - The type is NOT a generics : Directly return the JClass as usual
+ * - The type is a generics and enclosing type is a class C<T> :
+ * Generate a subclass of C<T> and return it
+ * - The type is a generics and enclosing type is an interface I<T>
+ * : Looking the inheritance tree, then
+ *
+ * - One of the parent is a {@link Map} : Generate a subclass of
+ * {@link LinkedHashMap}<T> one and return it
+ * - One of the parent is a {@link Set} : Generate a subclass of
+ * {@link TreeSet}<T> one and return it
+ * - One of the parent is a {@link Collection} : Generate a subclass of
+ * {@link ArrayList}<T> one and return it
+ * - Return {@link Object} definition
+ *
+ *
+ *
+ * @param expectedType
+ */
+ private JClass resolveExpectedClass(TypeMirror expectedType) {
+ // is a class or an interface
+ if (expectedType.getKind() == TypeKind.DECLARED) {
+ DeclaredType declaredType = (DeclaredType) expectedType;
+
+ List extends TypeMirror> typeArguments = declaredType.getTypeArguments();
+
+ // is NOT a generics, return directly
+ if (typeArguments.isEmpty()) {
+ return helper.typeMirrorToJClass(declaredType, holder);
+ }
+
+ // is a generics, must generate a new super class
+ TypeElement declaredElement = (TypeElement) declaredType.asElement();
+
+ JClass baseClass = helper.typeMirrorToJClass(declaredType, holder).erasure();
+ JClass decoratedExpectedClass = retrieveDecoratedExpectedClass(declaredType, declaredElement);
+ if (decoratedExpectedClass == null) {
+ decoratedExpectedClass = baseClass;
+ }
+ return decoratedExpectedClass;
+ } else if (expectedType.getKind() == TypeKind.ARRAY) {
+ ArrayType arrayType = (ArrayType) expectedType;
+ return resolveExpectedClass(arrayType.getComponentType()).array();
+ }
+
+ // is not a class nor an interface, return directly
+ return helper.typeMirrorToJClass(expectedType, holder);
+ }
+
+ /**
+ * Recursive method used to find if one of the grand-parent of the
+ * enclosingJClass is {@link Map}, {@link Set} or
+ * {@link Collection}.
+ *
+ * @param declaredType
+ * @param currentClass
+ * @return
+ */
+ private JClass retrieveDecoratedExpectedClass(DeclaredType declaredType, TypeElement typeElement) {
+ String classTypeBaseName = typeElement.toString();
+
+ // Looking for basic java.util interfaces to set a default
+ // implementation
+ String decoratedClassName = null;
+
+ if (typeElement.getKind() == ElementKind.INTERFACE) {
+ if (classTypeBaseName.equals(CanonicalNameConstants.MAP)) {
+ decoratedClassName = LinkedHashMap.class.getCanonicalName();
+ } else if (classTypeBaseName.equals(CanonicalNameConstants.SET)) {
+ decoratedClassName = TreeSet.class.getCanonicalName();
+ } else if (classTypeBaseName.equals(CanonicalNameConstants.LIST)) {
+ decoratedClassName = ArrayList.class.getCanonicalName();
+ } else if (classTypeBaseName.equals(CanonicalNameConstants.COLLECTION)) {
+ decoratedClassName = ArrayList.class.getCanonicalName();
+ }
+ } else {
+ decoratedClassName = typeElement.getQualifiedName().toString();
+ }
+
+ if (decoratedClassName != null) {
+ // Configure the super class of the final decorated class
+ String decoratedClassNameSuffix = "";
+ JClass decoratedSuperClass = holder.refClass(decoratedClassName);
+ for (TypeMirror typeArgument : declaredType.getTypeArguments()) {
+ if (typeArgument instanceof WildcardType) {
+ WildcardType wildcardType = (WildcardType) typeArgument;
+ if (wildcardType.getExtendsBound() != null) {
+ typeArgument = wildcardType.getExtendsBound();
+ } else if (wildcardType.getSuperBound() != null) {
+ typeArgument = wildcardType.getSuperBound();
+ }
+ }
+ JClass narrowJClass = helper.typeMirrorToJClass(typeArgument, holder);
+ decoratedSuperClass = decoratedSuperClass.narrow(narrowJClass);
+ decoratedClassNameSuffix += plainName(narrowJClass);
+ }
+
+ String decoratedFinalClassName = classTypeBaseName + "_" + decoratedClassNameSuffix;
+ decoratedFinalClassName = decoratedFinalClassName.replaceAll("\\[\\]", "s");
+ decoratedFinalClassName = restClientPackage.name() + "." + decoratedFinalClassName;
+ JDefinedClass decoratedJClass = holder.definedClass(decoratedFinalClassName);
+ decoratedJClass._extends(decoratedSuperClass);
+
+ return decoratedJClass;
+ }
+
+ // Try to find the superclass and make a recursive call to the this
+ // method
+ TypeMirror enclosingSuperJClass = typeElement.getSuperclass();
+ if (enclosingSuperJClass != null && enclosingSuperJClass.getKind() == TypeKind.DECLARED) {
+ DeclaredType declaredEnclosingSuperJClass = (DeclaredType) enclosingSuperJClass;
+ return retrieveDecoratedExpectedClass(declaredType, (TypeElement) declaredEnclosingSuperJClass.asElement());
+ }
+
+ // Falling back to the current enclosingJClass if Class can't be found
+ return null;
+ }
+
+ protected String plainName(JClass jClass) {
+ String plainName = jClass.erasure().name();
+ List typeParameters = jClass.getTypeParameters();
+ if (typeParameters.size() > 0) {
+ plainName += "_";
+ for (JClass typeParameter : typeParameters) {
+ plainName += plainName(typeParameter);
+ }
+ }
+ return plainName;
+ }
+
+ @Override
+ protected JInvocation addHttpEntityVar(JInvocation restCall, MethodProcessorHolder methodHolder) {
+ return restCall.arg(generateHttpEntityVar(methodHolder));
+ }
+
+ @Override
+ protected JInvocation addResponseEntityArg(JInvocation restCall, MethodProcessorHolder methodHolder) {
+ JClass expectedClass = methodHolder.getExpectedClass();
+
+ if (expectedClass != null) {
+ return restCall.arg(expectedClass.dotclass());
+ } else {
+ return restCall.arg(JExpr._null());
+ }
+ }
+
+ @Override
+ protected JInvocation addResultCallMethod(JInvocation restCall, MethodProcessorHolder methodHolder) {
+ JClass generatedReturnType = methodHolder.getMethodReturnClass();
+ if (generatedReturnType == null) {
+ return restCall;
+ }
+
+ if (!generatedReturnType.fullName().startsWith(CanonicalNameConstants.RESPONSE_ENTITY)) {
+ restCall = JExpr.invoke(restCall, "getBody");
+ }
+
+ return restCall;
+ }
+
+}
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 de16597a96..1db14ed9ad 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
@@ -19,24 +19,10 @@
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
import org.androidannotations.annotations.rest.Get;
-import org.androidannotations.helper.CanonicalNameConstants;
-import org.androidannotations.processing.EBeanHolder;
-import com.sun.codemodel.JBlock;
-import com.sun.codemodel.JClass;
-import com.sun.codemodel.JCodeModel;
-import com.sun.codemodel.JExpr;
-import com.sun.codemodel.JInvocation;
-import com.sun.codemodel.JVar;
-public class GetProcessor extends MethodProcessor {
-
- private EBeanHolder holder;
+public class GetProcessor extends GetPostProcessor {
public GetProcessor(ProcessingEnvironment processingEnv, RestImplementationsHolder restImplementationHolder) {
super(processingEnv, restImplementationHolder);
@@ -48,66 +34,9 @@ public Class extends Annotation> getTarget() {
}
@Override
- public void process(Element element, JCodeModel codeModel, EBeanHolder holder) {
-
- this.holder = holder;
- ExecutableElement executableElement = (ExecutableElement) element;
-
- TypeMirror returnType = executableElement.getReturnType();
-
- JClass generatedReturnType = null;
- String returnTypeString = returnType.toString();
- JClass expectedClass = null;
-
- if (returnType.getKind() != TypeKind.VOID) {
- if (returnTypeString.startsWith(CanonicalNameConstants.RESPONSE_ENTITY)) {
- DeclaredType declaredReturnedType = (DeclaredType) returnType;
- TypeMirror typeParameter = declaredReturnedType.getTypeArguments().get(0);
- expectedClass = holder.refClass(typeParameter.toString());
- generatedReturnType = holder.refClass(CanonicalNameConstants.RESPONSE_ENTITY).narrow(expectedClass);
- } else {
- generatedReturnType = holder.refClass(returnTypeString);
- expectedClass = generatedReturnType;
- }
- }
-
+ public String retrieveUrlSuffix(Element element) {
Get getAnnotation = element.getAnnotation(Get.class);
- String urlSuffix = getAnnotation.value();
-
- generateRestTemplateCallBlock(new MethodProcessorHolder(holder, executableElement, urlSuffix, expectedClass, generatedReturnType, codeModel));
- }
-
- @Override
- protected JInvocation addResultCallMethod(JInvocation restCall, MethodProcessorHolder methodHolder) {
- JClass expectedClass = methodHolder.getExpectedClass();
- JClass generatedReturnType = methodHolder.getGeneratedReturnType();
-
- if (expectedClass == generatedReturnType) {
- restCall = JExpr.invoke(restCall, "getBody");
- }
-
- return restCall;
- }
-
- @Override
- protected JInvocation addHttpEntityVar(JInvocation restCall, MethodProcessorHolder methodHolder) {
- return restCall.arg(generateHttpEntityVar(methodHolder));
- }
-
- @Override
- protected JInvocation addResponseEntityArg(JInvocation restCall, MethodProcessorHolder methodHolder) {
- JClass expectedClass = methodHolder.getExpectedClass();
-
- if (expectedClass != null) {
- return restCall.arg(expectedClass.dotclass());
- } else {
- return restCall.arg(JExpr._null());
- }
- }
-
- @Override
- protected JVar addHttpHeadersVar(JBlock body, ExecutableElement executableElement) {
- return generateHttpHeadersVar(holder, body, executableElement);
+ return getAnnotation.value();
}
}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/HeadProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/HeadProcessor.java
index abd0c38afc..a9d9c11978 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/HeadProcessor.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/HeadProcessor.java
@@ -24,19 +24,16 @@
import org.androidannotations.annotations.rest.Head;
import org.androidannotations.processing.EBeanHolder;
-import com.sun.codemodel.JBlock;
+
import com.sun.codemodel.JClass;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JInvocation;
-import com.sun.codemodel.JVar;
public class HeadProcessor extends MethodProcessor {
- private EBeanHolder holder;
-
- public HeadProcessor(ProcessingEnvironment processingEnv, RestImplementationsHolder restImplementationHolder) {
- super(processingEnv, restImplementationHolder);
+ public HeadProcessor(ProcessingEnvironment processingEnv, RestImplementationsHolder restImplementationsHolder) {
+ super(processingEnv, restImplementationsHolder);
}
@Override
@@ -47,7 +44,6 @@ public Class extends Annotation> getTarget() {
@Override
public void process(Element element, JCodeModel codeModel, EBeanHolder holder) throws Exception {
- this.holder = holder;
ExecutableElement executableElement = (ExecutableElement) element;
TypeMirror returnType = executableElement.getReturnType();
@@ -65,19 +61,4 @@ protected JInvocation addResultCallMethod(JInvocation restCall, MethodProcessorH
return JExpr.invoke(restCall, "getHeaders");
}
- @Override
- protected JInvocation addHttpEntityVar(JInvocation restCall, MethodProcessorHolder methodHolder) {
- return restCall.arg(JExpr._null());
- }
-
- @Override
- protected JInvocation addResponseEntityArg(JInvocation restCall, MethodProcessorHolder methodHolder) {
- return restCall.arg(JExpr._null());
- }
-
- @Override
- protected JVar addHttpHeadersVar(JBlock body, ExecutableElement executableElement) {
- return generateHttpHeadersVar(holder, body, executableElement);
- }
-
}
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 d140bf77c0..842b24b93b 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
@@ -15,7 +15,6 @@
*/
package org.androidannotations.processing.rest;
-import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@@ -23,15 +22,15 @@
import java.util.TreeMap;
import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.VariableElement;
import org.androidannotations.annotations.rest.Accept;
import org.androidannotations.helper.CanonicalNameConstants;
import org.androidannotations.helper.RestAnnotationHelper;
-import org.androidannotations.processing.EBeanHolder;
import org.androidannotations.processing.DecoratingElementProcessor;
+import org.androidannotations.processing.EBeanHolder;
+
import com.sun.codemodel.JBlock;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JCodeModel;
@@ -47,75 +46,98 @@ public abstract class MethodProcessor implements DecoratingElementProcessor {
protected final RestImplementationsHolder restImplementationsHolder;
protected final RestAnnotationHelper restAnnotationHelper;
- public MethodProcessor(ProcessingEnvironment processingEnv, RestImplementationsHolder restImplementationHolder) {
- restImplementationsHolder = restImplementationHolder;
+ public MethodProcessor(ProcessingEnvironment processingEnv, RestImplementationsHolder restImplementationsHolder) {
+ this.restImplementationsHolder = restImplementationsHolder;
restAnnotationHelper = new RestAnnotationHelper(processingEnv, getTarget());
}
protected void generateRestTemplateCallBlock(MethodProcessorHolder methodHolder) {
RestImplementationHolder holder = restImplementationsHolder.getEnclosingHolder(methodHolder.getElement());
ExecutableElement executableElement = (ExecutableElement) methodHolder.getElement();
+ EBeanHolder eBeanHolder = methodHolder.getHolder();
JClass expectedClass = methodHolder.getExpectedClass();
- JClass generatedReturnType = methodHolder.getGeneratedReturnType();
+ JClass methodReturnClass = methodHolder.getMethodReturnClass();
+ // Creating method signature
JMethod method;
String methodName = executableElement.getSimpleName().toString();
- boolean methodReturnVoid = generatedReturnType == null && expectedClass == null;
+ boolean methodReturnVoid = methodReturnClass == null && expectedClass == null;
if (methodReturnVoid) {
method = holder.restImplementationClass.method(JMod.PUBLIC, void.class, methodName);
} else {
- method = holder.restImplementationClass.method(JMod.PUBLIC, methodHolder.getGeneratedReturnType(), methodName);
+ method = holder.restImplementationClass.method(JMod.PUBLIC, methodHolder.getMethodReturnClass(), methodName);
}
method.annotate(Override.class);
+ if (expectedClass != methodReturnClass && !methodReturnClass.fullName().startsWith(CanonicalNameConstants.RESPONSE_ENTITY)) {
+ method.annotate(SuppressWarnings.class).param("value", "unchecked");
+ }
+ // Keep a reference on method's body
JBlock body = method.body();
+ methodHolder.setBody(body);
- // exchange method call
+ // Keep a reference on method's parameters
+ TreeMap methodParams = extractMethodParamsVar(eBeanHolder, method, executableElement, holder);
+ methodHolder.setMethodParams(methodParams);
+
+ // RestTemplate exchange() method call
JInvocation restCall = JExpr.invoke(holder.restTemplateField, "exchange");
- // concat root url + suffix
+ // RestTemplate exchange() 1st arg : concat root url + suffix
JInvocation concatCall = JExpr.invoke(holder.rootUrlField, "concat");
- // add url param
+ // RestTemplate exchange() 2nd arg : add url param
restCall.arg(concatCall.arg(JExpr.lit(methodHolder.getUrlSuffix())));
- EBeanHolder eBeanHolder = methodHolder.getHolder();
+ // RestTemplate exchange() 3rd arg : add HttpMethod type param
JClass httpMethod = eBeanHolder.refClass(CanonicalNameConstants.HTTP_METHOD);
+
// add method type param
String restMethodInCapitalLetters = getTarget().getSimpleName().toUpperCase(Locale.ENGLISH);
- restCall.arg(httpMethod.staticRef(restMethodInCapitalLetters));
-
- TreeMap methodParams = (TreeMap) generateMethodParamsVar(eBeanHolder, method, executableElement, holder);
-
- // update method holder
- methodHolder.setBody(body);
- methodHolder.setMethodParams(methodParams);
- JVar hashMapVar = generateHashMapVar(methodHolder);
+ restCall.arg(httpMethod.staticRef(restMethodInCapitalLetters));
restCall = addHttpEntityVar(restCall, methodHolder);
restCall = addResponseEntityArg(restCall, methodHolder);
- boolean hasParametersInUrl = hashMapVar != null;
- if (hasParametersInUrl) {
+ JVar hashMapVar = generateHashMapVar(methodHolder);
+ if (hashMapVar != null) {
restCall.arg(hashMapVar);
}
- restCall = addResultCallMethod(restCall, methodHolder);
-
- insertRestCallInBody(body, restCall, methodReturnVoid);
+ insertRestCallInBody(body, restCall, methodHolder, methodReturnVoid);
}
- protected abstract JInvocation addHttpEntityVar(JInvocation restCall, MethodProcessorHolder methodHolder);
+ /**
+ * Add the HttpEntity attribute to restTemplate.exchange() method. By
+ * default, the value will be null (for DELETE, HEAD and
+ * OPTIONS method type)
+ */
+ protected JInvocation addHttpEntityVar(JInvocation restCall, MethodProcessorHolder methodHolder) {
+ return restCall.arg(JExpr._null());
+ }
- protected abstract JInvocation addResponseEntityArg(JInvocation restCall, MethodProcessorHolder methodHolder);
+ /**
+ * Add the response type to restTemplate.exchange() method. This is used to
+ * bind the response into a specific Java object.
+ */
+ protected JInvocation addResponseEntityArg(JInvocation restCall, MethodProcessorHolder methodHolder) {
+ return restCall.arg(JExpr._null());
+ }
- protected abstract JInvocation addResultCallMethod(JInvocation restCall, MethodProcessorHolder methodHolder);
+ /**
+ * Add an extra method calls on the result of restTemplate.exchange(). By
+ * default, just return the result
+ */
+ protected JInvocation addResultCallMethod(JInvocation restCall, MethodProcessorHolder methodHolder) {
+ return restCall;
+ }
- private void insertRestCallInBody(JBlock body, JInvocation restCall, boolean methodReturnVoid) {
+ private void insertRestCallInBody(JBlock body, JInvocation restCall, MethodProcessorHolder methodHolder, boolean methodReturnVoid) {
if (methodReturnVoid) {
body.add(restCall);
} else {
+ restCall = addResultCallMethod(restCall, methodHolder);
body._return(restCall);
}
}
@@ -124,7 +146,7 @@ private JVar generateHashMapVar(MethodProcessorHolder methodHolder) {
ExecutableElement element = (ExecutableElement) methodHolder.getElement();
JCodeModel codeModel = methodHolder.getCodeModel();
JBlock body = methodHolder.getBody();
- TreeMap methodParams = methodHolder.getMethodParams();
+ Map methodParams = methodHolder.getMethodParams();
JVar hashMapVar = null;
List urlVariables = restAnnotationHelper.extractUrlVariableNames(element);
@@ -217,7 +239,7 @@ private String retrieveAcceptAnnotationValue(ExecutableElement executableElement
}
}
- private Map generateMethodParamsVar(EBeanHolder eBeanHolder, JMethod method, ExecutableElement executableElement, RestImplementationHolder holder) {
+ private TreeMap extractMethodParamsVar(EBeanHolder eBeanHolder, JMethod method, ExecutableElement executableElement, RestImplementationHolder holder) {
List extends VariableElement> params = executableElement.getParameters();
TreeMap methodParams = new TreeMap();
for (VariableElement parameter : params) {
@@ -233,12 +255,4 @@ private Map generateMethodParamsVar(EBeanHolder eBeanHolder, JMeth
return methodParams;
}
- protected abstract JVar addHttpHeadersVar(JBlock body, ExecutableElement executableElement);
-
- @Override
- public abstract Class extends Annotation> getTarget();
-
- @Override
- public abstract void process(Element element, JCodeModel codeModel, EBeanHolder eBeanHolder) throws Exception;
-
}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/MethodProcessorHolder.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/MethodProcessorHolder.java
index 4d4e7da010..e34827ed6b 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/MethodProcessorHolder.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/MethodProcessorHolder.java
@@ -30,7 +30,7 @@ public class MethodProcessorHolder {
private Element element;
private String urlSuffix;
private JClass expectedClass;
- private JClass generatedReturnType;
+ private JClass methodReturnClass;
private JCodeModel codeModel;
private JBlock body;
@@ -42,7 +42,7 @@ public MethodProcessorHolder(EBeanHolder holder, Element element, String urlSuff
this.element = element;
this.urlSuffix = urlSuffix;
this.expectedClass = expectedClass;
- this.generatedReturnType = generatedReturnType;
+ this.methodReturnClass = generatedReturnType;
this.codeModel = codeModel;
}
@@ -58,8 +58,16 @@ public JClass getExpectedClass() {
return expectedClass;
}
- public JClass getGeneratedReturnType() {
- return generatedReturnType;
+ public void setExpectedClass(JClass expectedClass) {
+ this.expectedClass = expectedClass;
+ }
+
+ public JClass getMethodReturnClass() {
+ return methodReturnClass;
+ }
+
+ public void setMethodReturnClass(JClass methodReturnClass) {
+ this.methodReturnClass = methodReturnClass;
}
public JCodeModel getCodeModel() {
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/OptionsProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/OptionsProcessor.java
index d463d338c4..40e66de552 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/OptionsProcessor.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/OptionsProcessor.java
@@ -26,19 +26,16 @@
import org.androidannotations.annotations.rest.Options;
import org.androidannotations.helper.CanonicalNameConstants;
import org.androidannotations.processing.EBeanHolder;
-import com.sun.codemodel.JBlock;
+
import com.sun.codemodel.JClass;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JInvocation;
-import com.sun.codemodel.JVar;
public class OptionsProcessor extends MethodProcessor {
- private EBeanHolder holder;
-
- public OptionsProcessor(ProcessingEnvironment processingEnv, RestImplementationsHolder restImplementationHolder) {
- super(processingEnv, restImplementationHolder);
+ public OptionsProcessor(ProcessingEnvironment processingEnv, RestImplementationsHolder restImplementationsHolder) {
+ super(processingEnv, restImplementationsHolder);
}
@Override
@@ -49,7 +46,6 @@ public Class extends Annotation> getTarget() {
@Override
public void process(Element element, JCodeModel codeModel, EBeanHolder holder) throws Exception {
- this.holder = holder;
ExecutableElement executableElement = (ExecutableElement) element;
TypeMirror returnType = executableElement.getReturnType();
@@ -75,19 +71,4 @@ protected JInvocation addResultCallMethod(JInvocation restCall, MethodProcessorH
return restCall;
}
- @Override
- protected JInvocation addHttpEntityVar(JInvocation restCall, MethodProcessorHolder methodHolder) {
- return restCall.arg(JExpr._null());
- }
-
- @Override
- protected JInvocation addResponseEntityArg(JInvocation restCall, MethodProcessorHolder methodHolder) {
- return restCall.arg(JExpr._null());
- }
-
- @Override
- protected JVar addHttpHeadersVar(JBlock body, ExecutableElement executableElement) {
- return generateHttpHeadersVar(holder, body, executableElement);
- }
-
}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/PostProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/PostProcessor.java
index d275d752d0..545652608e 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/PostProcessor.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/PostProcessor.java
@@ -19,24 +19,10 @@
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
import org.androidannotations.annotations.rest.Post;
-import org.androidannotations.helper.CanonicalNameConstants;
-import org.androidannotations.processing.EBeanHolder;
-import com.sun.codemodel.JBlock;
-import com.sun.codemodel.JClass;
-import com.sun.codemodel.JCodeModel;
-import com.sun.codemodel.JExpr;
-import com.sun.codemodel.JInvocation;
-import com.sun.codemodel.JVar;
-public class PostProcessor extends MethodProcessor {
-
- private EBeanHolder holder;
+public class PostProcessor extends GetPostProcessor {
public PostProcessor(ProcessingEnvironment processingEnv, RestImplementationsHolder restImplementationHolder) {
super(processingEnv, restImplementationHolder);
@@ -48,73 +34,9 @@ public Class extends Annotation> getTarget() {
}
@Override
- public void process(Element element, JCodeModel codeModel, EBeanHolder holder) {
-
- this.holder = holder;
- ExecutableElement executableElement = (ExecutableElement) element;
-
- TypeMirror returnType = executableElement.getReturnType();
-
- JClass generatedReturnType = null;
- String returnTypeString = returnType.toString();
- JClass expectedClass = null;
-
- if (returnType.getKind() != TypeKind.VOID) {
- if (returnTypeString.startsWith(CanonicalNameConstants.URI)) {
- DeclaredType declaredReturnedType = (DeclaredType) returnType;
- TypeMirror typeParameter = declaredReturnedType.getTypeArguments().get(0);
- expectedClass = holder.refClass(typeParameter.toString());
- generatedReturnType = holder.refClass(CanonicalNameConstants.URI);
- } else if (returnTypeString.startsWith(CanonicalNameConstants.RESPONSE_ENTITY)) {
- DeclaredType declaredReturnedType = (DeclaredType) returnType;
- TypeMirror typeParameter = declaredReturnedType.getTypeArguments().get(0);
- expectedClass = holder.refClass(typeParameter.toString());
- generatedReturnType = holder.refClass(CanonicalNameConstants.RESPONSE_ENTITY).narrow(expectedClass);
- } else {
- generatedReturnType = holder.refClass(returnTypeString);
- expectedClass = generatedReturnType;
- }
- }
-
- Post postAnnotation = element.getAnnotation(Post.class);
- String urlSuffix = postAnnotation.value();
-
- generateRestTemplateCallBlock(new MethodProcessorHolder(holder, executableElement, urlSuffix, expectedClass, generatedReturnType, codeModel));
- }
-
- @Override
- protected JInvocation addHttpEntityVar(JInvocation restCall, MethodProcessorHolder methodHolder) {
- return restCall.arg(generateHttpEntityVar(methodHolder));
- }
-
- @Override
- protected JInvocation addResponseEntityArg(JInvocation restCall, MethodProcessorHolder methodHolder) {
- JClass expectedClass = methodHolder.getExpectedClass();
-
- if (expectedClass != null) {
- restCall.arg(expectedClass.dotclass());
- } else {
- restCall.arg(JExpr._null());
- }
-
- return restCall;
- }
-
- @Override
- protected JInvocation addResultCallMethod(JInvocation restCall, MethodProcessorHolder methodHolder) {
- JClass expectedClass = methodHolder.getExpectedClass();
- JClass generatedReturnType = methodHolder.getGeneratedReturnType();
-
- if (expectedClass == generatedReturnType && expectedClass != null) {
- restCall = JExpr.invoke(restCall, "getBody");
- }
-
- return restCall;
- }
-
- @Override
- protected JVar addHttpHeadersVar(JBlock body, ExecutableElement executableElement) {
- return generateHttpHeadersVar(holder, body, executableElement);
+ public String retrieveUrlSuffix(Element element) {
+ Post getAnnotation = element.getAnnotation(Post.class);
+ return getAnnotation.value();
}
}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/PutProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/PutProcessor.java
index 6dcb945b2a..691cd29c2a 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/PutProcessor.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/PutProcessor.java
@@ -23,18 +23,14 @@
import org.androidannotations.annotations.rest.Put;
import org.androidannotations.processing.EBeanHolder;
-import com.sun.codemodel.JBlock;
+
import com.sun.codemodel.JCodeModel;
-import com.sun.codemodel.JExpr;
import com.sun.codemodel.JInvocation;
-import com.sun.codemodel.JVar;
public class PutProcessor extends MethodProcessor {
- private EBeanHolder holder;
-
- public PutProcessor(ProcessingEnvironment processingEnv, RestImplementationsHolder restImplementationHolder) {
- super(processingEnv, restImplementationHolder);
+ public PutProcessor(ProcessingEnvironment processingEnv, RestImplementationsHolder restImplementationsHolder) {
+ super(processingEnv, restImplementationsHolder);
}
@Override
@@ -45,7 +41,6 @@ public Class extends Annotation> getTarget() {
@Override
public void process(Element element, JCodeModel codeModel, EBeanHolder holder) throws Exception {
- this.holder = holder;
ExecutableElement executableElement = (ExecutableElement) element;
Put putAnnotation = element.getAnnotation(Put.class);
@@ -54,24 +49,9 @@ public void process(Element element, JCodeModel codeModel, EBeanHolder holder) t
generateRestTemplateCallBlock(new MethodProcessorHolder(holder, executableElement, urlSuffix, null, null, codeModel));
}
- @Override
- protected JInvocation addResultCallMethod(JInvocation restCall, MethodProcessorHolder methodHolder) {
- return restCall;
- }
-
@Override
protected JInvocation addHttpEntityVar(JInvocation restCall, MethodProcessorHolder methodHolder) {
return restCall.arg(generateHttpEntityVar(methodHolder));
}
- @Override
- protected JInvocation addResponseEntityArg(JInvocation restCall, MethodProcessorHolder methodHolder) {
- return restCall.arg(JExpr._null());
- }
-
- @Override
- protected JVar addHttpHeadersVar(JBlock body, ExecutableElement executableElement) {
- return generateHttpHeadersVar(holder, body, executableElement);
- }
-
}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/RestProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/RestProcessor.java
index 301cf1e19a..16cce5c74e 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/RestProcessor.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/rest/RestProcessor.java
@@ -50,12 +50,12 @@
public class RestProcessor implements GeneratingElementProcessor {
- private final RestImplementationsHolder restImplementationHolder;
+ private final RestImplementationsHolder restImplementationsHolder;
private AnnotationHelper annotationHelper;
- public RestProcessor(ProcessingEnvironment processingEnv, RestImplementationsHolder restImplementationHolder) {
+ public RestProcessor(ProcessingEnvironment processingEnv, RestImplementationsHolder restImplementationsHolder) {
annotationHelper = new AnnotationHelper(processingEnv);
- this.restImplementationHolder = restImplementationHolder;
+ this.restImplementationsHolder = restImplementationsHolder;
}
@Override
@@ -66,7 +66,7 @@ public Class extends Annotation> getTarget() {
@Override
public void process(Element element, JCodeModel codeModel, EBeansHolder eBeansHolder) throws Exception {
- RestImplementationHolder holder = restImplementationHolder.create(element);
+ RestImplementationHolder holder = restImplementationsHolder.create(element);
TypeElement typeElement = (TypeElement) element;
String interfaceName = typeElement.getQualifiedName().toString();
@@ -152,5 +152,4 @@ public void process(Element element, JCodeModel codeModel, EBeansHolder eBeansHo
}
}
-
}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/rest/GetValidator.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/rest/GetValidator.java
index 3d102b52f9..43384bd371 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/rest/GetValidator.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/rest/GetValidator.java
@@ -58,10 +58,8 @@ public boolean validate(Element element, AnnotationElements validatedElements) {
validatorHelper.throwsOnlyRestClientException(executableElement, valid);
- validatorHelper.returnTypeNotGenericUnlessResponseEntity(executableElement, valid);
-
validatorHelper.doesNotReturnPrimitive(executableElement, valid);
-
+
restAnnotationHelper.urlVariableNamesExistInParametersAndHasNoOneMoreParameter(executableElement, valid);
return valid.isValid();
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/rest/PostValidator.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/rest/PostValidator.java
index 38d1695208..5ce032db10 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/rest/PostValidator.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/rest/PostValidator.java
@@ -57,10 +57,8 @@ public boolean validate(Element element, AnnotationElements validatedElements) {
ExecutableElement executableElement = (ExecutableElement) element;
validatorHelper.throwsOnlyRestClientException(executableElement, valid);
-
+
validatorHelper.doesNotReturnPrimitive(executableElement, valid);
-
- validatorHelper.returnTypeNotGenericUnlessResponseEntity(executableElement, valid);
restAnnotationHelper.urlVariableNamesExistInParametersAndHasOnlyOneMoreParameter(executableElement, valid);
diff --git a/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/processing/EBeansHolderTests.java b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/processing/EBeansHolderTests.java
new file mode 100644
index 0000000000..4fe54998f4
--- /dev/null
+++ b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/processing/EBeansHolderTests.java
@@ -0,0 +1,101 @@
+/**
+ * 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.processing;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import com.sun.codemodel.JClass;
+import com.sun.codemodel.JCodeModel;
+
+public class EBeansHolderTests {
+
+ private EBeansHolder eBeansHolder;
+
+ public EBeansHolderTests() {
+ eBeansHolder = new EBeansHolder(new JCodeModel());
+ }
+
+ private void checkForFullyQualifiedClassName(String fullyQualifiedClassName) {
+ checkForFullyQualifiedClassName(fullyQualifiedClassName, fullyQualifiedClassName);
+ }
+
+ private void checkForFullyQualifiedClassName(String fullyQualifiedClassName, String expetedClassName) {
+ JClass refClass = eBeansHolder.refClass(fullyQualifiedClassName);
+ Assert.assertEquals(expetedClassName, refClass.fullName());
+ }
+
+ @Test
+ public void testRefClass_primitive() {
+ checkForFullyQualifiedClassName("int");
+ }
+
+ @Test
+ public void testRefClass_generics_one_arg() {
+ checkForFullyQualifiedClassName("java.util.List");
+ checkForFullyQualifiedClassName("java.util.List");
+ checkForFullyQualifiedClassName("java.util.List[]");
+ checkForFullyQualifiedClassName("java.util.List[][]");
+ checkForFullyQualifiedClassName("java.util.List");
+ checkForFullyQualifiedClassName("java.util.List[]");
+ }
+
+ @Test
+ public void testRefClass_generics_multiple_args() {
+ checkForFullyQualifiedClassName("java.util.Map");
+ checkForFullyQualifiedClassName("java.util.Map[]");
+ checkForFullyQualifiedClassName("java.util.Map[][]");
+ checkForFullyQualifiedClassName("java.util.Map");
+ checkForFullyQualifiedClassName("java.util.Map");
+ checkForFullyQualifiedClassName("java.util.Map[]");
+
+ checkForFullyQualifiedClassName("java.util.Map", "java.util.Map");
+ checkForFullyQualifiedClassName("java.util.Map[]", "java.util.Map[]");
+ }
+
+ @Test
+ public void testRefClass_generics_inner_args() {
+ checkForFullyQualifiedClassName("java.util.Map,java.lang.Integer>");
+ checkForFullyQualifiedClassName("java.util.Map[],java.lang.Integer>");
+ checkForFullyQualifiedClassName("java.util.Map[],java.lang.Integer>[]");
+
+ checkForFullyQualifiedClassName("java.util.Map < java.util.Set < java.lang.String > , java.lang.Integer >", "java.util.Map,java.lang.Integer>");
+ }
+
+ @Test
+ public void testRefClass_wildcards() {
+ checkForFullyQualifiedClassName("java.util.List>", "java.util.List extends java.lang.Object>");
+ checkForFullyQualifiedClassName("java.util.Map,?>", "java.util.Map extends java.lang.Object,? extends java.lang.Object>");
+ checkForFullyQualifiedClassName("java.util.Map", "java.util.Map");
+ }
+
+ @Test
+ public void testRefClass_typevar_simple() {
+ checkForFullyQualifiedClassName("java.util.List");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testRefClass_typevar_extends() {
+ checkForFullyQualifiedClassName("java.util.Set");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testRefClass_typevar_multiple() {
+ checkForFullyQualifiedClassName("java.util.Map");
+ }
+
+}
diff --git a/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rclass/RClassFinderTest.java b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rclass/RClassFinderTest.java
index 6b20155d7c..1ddc92340d 100644
--- a/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rclass/RClassFinderTest.java
+++ b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/rclass/RClassFinderTest.java
@@ -1,3 +1,18 @@
+/**
+ * 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.rclass;
import org.androidannotations.AndroidAnnotationProcessor;
diff --git a/AndroidAnnotations/functional-test-1-5-tests/pom.xml b/AndroidAnnotations/functional-test-1-5-tests/pom.xml
index fbfbbe1bd9..98033ef359 100644
--- a/AndroidAnnotations/functional-test-1-5-tests/pom.xml
+++ b/AndroidAnnotations/functional-test-1-5-tests/pom.xml
@@ -52,7 +52,12 @@
bcprov-jdk16
140
-
+
+
+ org.codehaus.jackson
+ jackson-mapper-asl
+ 1.9.6
+
diff --git a/AndroidAnnotations/functional-test-1-5-tests/src/test/java/org/androidannotations/test15/rest/MyServiceTest.java b/AndroidAnnotations/functional-test-1-5-tests/src/test/java/org/androidannotations/test15/rest/MyServiceTest.java
index a135d3472d..ccd3d9dbce 100644
--- a/AndroidAnnotations/functional-test-1-5-tests/src/test/java/org/androidannotations/test15/rest/MyServiceTest.java
+++ b/AndroidAnnotations/functional-test-1-5-tests/src/test/java/org/androidannotations/test15/rest/MyServiceTest.java
@@ -15,37 +15,132 @@
*/
package org.androidannotations.test15.rest;
+import static junit.framework.Assert.assertEquals;
import static org.mockito.Matchers.startsWith;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import java.util.List;
import java.util.Map;
+import org.androidannotations.test15.AndroidAnnotationsTestRunner;
+import org.apache.http.message.BasicHeader;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
-import org.androidannotations.test15.AndroidAnnotationsTestRunner;
+import com.xtremelabs.robolectric.Robolectric;
@RunWith(AndroidAnnotationsTestRunner.class)
public class MyServiceTest {
+ private MyService_ myService = new MyService_();
+
+ private void addPendingResponse(String jsonResponse) {
+ Robolectric.addPendingHttpResponse(HttpStatus.OK.value(), jsonResponse.replaceAll("'", "\""), new BasicHeader("content-type", "application/json"));
+ }
+
@Test
public void can_override_root_url() {
MyService_ myService = new MyService_();
-
+
RestTemplate restTemplate = mock(RestTemplate.class);
myService.setRestTemplate(restTemplate);
-
myService.setRootUrl("http://newRootUrl");
-
+
myService.removeEvent(42);
-
- verify(restTemplate).exchange(startsWith("http://newRootUrl"), Mockito. any(), Mockito.> any(), Mockito.> any(), Mockito.