diff --git a/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/EIntentService.java b/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/EIntentService.java
new file mode 100644
index 0000000000..534d537fb3
--- /dev/null
+++ b/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/EIntentService.java
@@ -0,0 +1,29 @@
+/**
+ * Copyright (C) 2010-2013 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Use this annotation to enhance an Android IntentService
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.TYPE)
+public @interface EIntentService {
+}
diff --git a/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/ServiceAction.java b/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/ServiceAction.java
new file mode 100644
index 0000000000..ede444ba3c
--- /dev/null
+++ b/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/ServiceAction.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright (C) 2010-2013 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import android.app.IntentService;
+
+/**
+ * Should be used on a method that must respond to a specific action in an
+ * enhanced {@link IntentService}. The method name will be used as action name
+ * unless the {@link #value()} field is set.
+ *
+ * The method signature (with attributes) will be a part of the IntentBuilder
+ * generated for the {@link EIntentService}.
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.METHOD)
+public @interface ServiceAction {
+
+ /**
+ * Define the action's name. If this field isn't set the annotated method
+ * name will be used.
+ */
+ String value() default "";
+
+}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/AndroidAnnotationProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/AndroidAnnotationProcessor.java
index 2dd88dae43..d80624f0bf 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/AndroidAnnotationProcessor.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/AndroidAnnotationProcessor.java
@@ -54,6 +54,7 @@
import org.androidannotations.annotations.EApplication;
import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.EFragment;
+import org.androidannotations.annotations.EIntentService;
import org.androidannotations.annotations.EProvider;
import org.androidannotations.annotations.EReceiver;
import org.androidannotations.annotations.EService;
@@ -85,6 +86,7 @@
import org.androidannotations.annotations.SeekBarProgressChange;
import org.androidannotations.annotations.SeekBarTouchStart;
import org.androidannotations.annotations.SeekBarTouchStop;
+import org.androidannotations.annotations.ServiceAction;
import org.androidannotations.annotations.SystemService;
import org.androidannotations.annotations.TextChange;
import org.androidannotations.annotations.Touch;
@@ -147,6 +149,7 @@
import org.androidannotations.processing.EApplicationProcessor;
import org.androidannotations.processing.EBeanProcessor;
import org.androidannotations.processing.EFragmentProcessor;
+import org.androidannotations.processing.EIntentServiceProcessor;
import org.androidannotations.processing.EProviderProcessor;
import org.androidannotations.processing.EReceiverProcessor;
import org.androidannotations.processing.EServiceProcessor;
@@ -184,6 +187,7 @@
import org.androidannotations.processing.SeekBarProgressChangeProcessor;
import org.androidannotations.processing.SeekBarTouchStartProcessor;
import org.androidannotations.processing.SeekBarTouchStopProcessor;
+import org.androidannotations.processing.ServiceActionProcessor;
import org.androidannotations.processing.SharedPrefProcessor;
import org.androidannotations.processing.SubscribeProcessor;
import org.androidannotations.processing.SystemServiceProcessor;
@@ -219,6 +223,7 @@
import org.androidannotations.validation.EApplicationValidator;
import org.androidannotations.validation.EBeanValidator;
import org.androidannotations.validation.EFragmentValidator;
+import org.androidannotations.validation.EIntentServiceValidator;
import org.androidannotations.validation.EProviderValidator;
import org.androidannotations.validation.EReceiverValidator;
import org.androidannotations.validation.EServiceValidator;
@@ -256,6 +261,7 @@
import org.androidannotations.validation.SeekBarProgressChangeValidator;
import org.androidannotations.validation.SeekBarTouchStartValidator;
import org.androidannotations.validation.SeekBarTouchStopValidator;
+import org.androidannotations.validation.ServiceActionValidator;
import org.androidannotations.validation.SharedPrefValidator;
import org.androidannotations.validation.SubscribeValidator;
import org.androidannotations.validation.SystemServiceValidator;
@@ -416,6 +422,7 @@ private ModelValidator buildModelValidator(IRClass rClass, AndroidSystemServices
modelValidator.register(new EApplicationValidator(processingEnv, androidManifest));
modelValidator.register(new EActivityValidator(processingEnv, rClass, androidManifest));
modelValidator.register(new EServiceValidator(processingEnv, androidManifest));
+ modelValidator.register(new EIntentServiceValidator(processingEnv, androidManifest));
modelValidator.register(new EReceiverValidator(processingEnv, androidManifest));
modelValidator.register(new EProviderValidator(processingEnv, androidManifest));
modelValidator.register(new EFragmentValidator(processingEnv, rClass));
@@ -471,6 +478,7 @@ private ModelValidator buildModelValidator(IRClass rClass, AndroidSystemServices
modelValidator.register(new SeekBarProgressChangeValidator(processingEnv, rClass));
modelValidator.register(new SeekBarTouchStartValidator(processingEnv, rClass));
modelValidator.register(new SeekBarTouchStopValidator(processingEnv, rClass));
+ modelValidator.register(new ServiceActionValidator(processingEnv));
/*
* Any view injection or listener binding should occur before
* AfterViewsValidator
@@ -513,6 +521,7 @@ private ModelProcessor buildModelProcessor(IRClass rClass, AndroidSystemServices
modelProcessor.register(new EApplicationProcessor());
modelProcessor.register(new EActivityProcessor(processingEnv, rClass));
modelProcessor.register(new EServiceProcessor(processingEnv));
+ modelProcessor.register(new EIntentServiceProcessor(processingEnv));
modelProcessor.register(new EReceiverProcessor());
modelProcessor.register(new EProviderProcessor());
modelProcessor.register(new EFragmentProcessor(processingEnv, rClass));
@@ -568,6 +577,7 @@ private ModelProcessor buildModelProcessor(IRClass rClass, AndroidSystemServices
modelProcessor.register(new SeekBarProgressChangeProcessor(processingEnv, rClass));
modelProcessor.register(new SeekBarTouchStartProcessor(processingEnv, rClass));
modelProcessor.register(new SeekBarTouchStopProcessor(processingEnv, rClass));
+ modelProcessor.register(new ServiceActionProcessor(processingEnv));
/*
* Any view injection or listener binding should occur before
* AfterViewsProcessor
@@ -677,6 +687,8 @@ public Set getSupportedAnnotationTypes() {
Bean.class, //
AfterInject.class, //
EService.class, //
+ EIntentService.class, //
+ ServiceAction.class, //
EReceiver.class, //
EProvider.class, //
Trace.class, //
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 4a31a6fc40..c0174e71bd 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/APTCodeModelHelper.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/APTCodeModelHelper.java
@@ -23,19 +23,25 @@
import static com.sun.codemodel.JMod.PUBLIC;
import static com.sun.codemodel.JMod.STATIC;
import static javax.lang.model.element.ElementKind.CONSTRUCTOR;
+import static org.androidannotations.helper.CanonicalNameConstants.PARCELABLE;
+import static org.androidannotations.helper.CanonicalNameConstants.SERIALIZABLE;
+import static org.androidannotations.helper.CanonicalNameConstants.STRING;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
+import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.VariableElement;
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 javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
import org.androidannotations.processing.EBeanHolder;
@@ -54,6 +60,7 @@
import com.sun.codemodel.JMod;
import com.sun.codemodel.JStatement;
import com.sun.codemodel.JType;
+import com.sun.codemodel.JTypeVar;
import com.sun.codemodel.JVar;
public class APTCodeModelHelper {
@@ -238,7 +245,7 @@ public JDefinedClass createDelegatingAnonymousRunnableClass(EBeanHolder holder,
JMethod runMethod = anonymousRunnableClass.method(JMod.PUBLIC, codeModel.VOID, "run");
runMethod.annotate(Override.class);
- runMethod.body().add( previousMethodBody );
+ runMethod.body().add(previousMethodBody);
return anonymousRunnableClass;
}
@@ -415,6 +422,49 @@ private void addIntentBuilder(JCodeModel codeModel, EBeanHolder holder, Annotati
}
}
+ public JInvocation addIntentBuilderPutExtraMethod(JCodeModel codeModel, EBeanHolder holder, APTCodeModelHelper helper, ProcessingEnvironment processingEnv, JMethod method, TypeMirror elementType, String parameterName, String extraName) {
+ boolean castToSerializable = false;
+ boolean castToParcelable = false;
+ if (elementType.getKind() == TypeKind.DECLARED) {
+ Elements elementUtils = processingEnv.getElementUtils();
+ Types typeUtils = processingEnv.getTypeUtils();
+ TypeMirror parcelableType = elementUtils.getTypeElement(PARCELABLE).asType();
+ if (!typeUtils.isSubtype(elementType, parcelableType)) {
+ TypeMirror stringType = elementUtils.getTypeElement(STRING).asType();
+ if (!typeUtils.isSubtype(elementType, stringType)) {
+ castToSerializable = true;
+ }
+ } else {
+ TypeMirror serializableType = elementUtils.getTypeElement(SERIALIZABLE).asType();
+ if (typeUtils.isSubtype(elementType, serializableType)) {
+ castToParcelable = true;
+ }
+ }
+ }
+
+ JClass parameterClass = helper.typeMirrorToJClass(elementType, holder);
+ JVar extraParameterVar = method.param(parameterClass, parameterName);
+ JBlock body = method.body();
+ JInvocation invocation = body.invoke(holder.intentField, "putExtra").arg(extraName);
+ if (castToSerializable) {
+ return invocation.arg(cast(holder.classes().SERIALIZABLE, extraParameterVar));
+ } else if (castToParcelable) {
+ return invocation.arg(cast(holder.classes().PARCELABLE, extraParameterVar));
+ }
+ return invocation.arg(extraParameterVar);
+ }
+
+ public void addCastMethod(JCodeModel codeModel, EBeanHolder holder) {
+ JType objectType = codeModel._ref(Object.class);
+ JMethod method = holder.generatedClass.method(JMod.PRIVATE, objectType, "cast_");
+ JTypeVar genericType = method.generify("T");
+ method.type(genericType);
+ JVar objectParam = method.param(objectType, "object");
+ method.annotate(SuppressWarnings.class).param("value", "unchecked");
+ method.body()._return(JExpr.cast(genericType, objectParam));
+ holder.cast = method;
+ }
+
private JFieldVar addIntentBuilderFragmentConstructor(EBeanHolder holder, JClass fragmentClass, String fieldName, JFieldVar contextField) {
JFieldVar fragmentField = holder.intentBuilderClass.field(PRIVATE, fragmentClass, fieldName);
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/AnnotationHelper.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/AnnotationHelper.java
index 1e3951adad..325f2bac2e 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/AnnotationHelper.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/AnnotationHelper.java
@@ -400,6 +400,12 @@ public boolean enclosingElementHasEnhancedComponentAnnotation(Element element) {
return hasOneOfClassAnnotations(enclosingElement, VALID_ENHANCED_COMPONENT_ANNOTATIONS);
}
+ public boolean hasOneOfClassAnnotations(Element element, Class extends Annotation> validAnnotation) {
+ List> annotations = new ArrayList>();
+ annotations.add(validAnnotation);
+ return hasOneOfClassAnnotations(element, annotations);
+ }
+
public boolean hasOneOfClassAnnotations(Element element, List> validAnnotations) {
for (Class extends Annotation> validAnnotation : validAnnotations) {
if (element.getAnnotation(validAnnotation) != null) {
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 a854a50955..43cec1ed7b 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/CanonicalNameConstants.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/CanonicalNameConstants.java
@@ -91,6 +91,7 @@ public final class CanonicalNameConstants {
public static final String MOTION_EVENT = "android.view.MotionEvent";
public static final String HANDLER = "android.os.Handler";
public static final String SERVICE = "android.app.Service";
+ public static final String INTENT_SERVICE = "android.app.IntentService";
public static final String BROADCAST_RECEIVER = "android.content.BroadcastReceiver";
public static final String CONTENT_PROVIDER = "android.content.ContentProvider";
public static final String SQLITE_DATABASE = "android.database.sqlite.SQLiteDatabase";
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/CaseHelper.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/CaseHelper.java
index 29324824d0..522c678c22 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/CaseHelper.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/CaseHelper.java
@@ -60,4 +60,14 @@ public static String camelCaseToUpperSnakeCase(String camelCase) {
return camelCaseToSnakeCase(camelCase).toUpperCase();
}
+ public static String camelCaseToUpperSnakeCase(String prefix, String camelCase, String suffix) {
+ if (prefix != null && !camelCase.startsWith(prefix)) {
+ camelCase = prefix + "_" + camelCase;
+ }
+ if (suffix != null && !camelCase.toLowerCase().endsWith(suffix.toLowerCase())) {
+ camelCase = camelCase + "_" + suffix;
+ }
+ return camelCaseToUpperSnakeCase(camelCase);
+ }
+
}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/ModelConstants.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/ModelConstants.java
index 8abc7ff15b..8962e7091c 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/ModelConstants.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/ModelConstants.java
@@ -24,6 +24,7 @@
import org.androidannotations.annotations.EApplication;
import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.EFragment;
+import org.androidannotations.annotations.EIntentService;
import org.androidannotations.annotations.EProvider;
import org.androidannotations.annotations.EReceiver;
import org.androidannotations.annotations.EService;
@@ -40,7 +41,7 @@ public abstract class ModelConstants {
public static final List> VALID_ENHANCED_VIEW_SUPPORT_ANNOTATIONS = asList(EActivity.class, EViewGroup.class, EView.class, EBean.class, EFragment.class);
@SuppressWarnings("unchecked")
- public static final List> VALID_ENHANCED_COMPONENT_ANNOTATIONS = asList(EApplication.class, EActivity.class, EViewGroup.class, EView.class, EBean.class, EService.class, EReceiver.class, EProvider.class, EFragment.class);
+ public static final List> VALID_ENHANCED_COMPONENT_ANNOTATIONS = asList(EApplication.class, EActivity.class, EViewGroup.class, EView.class, EBean.class, EService.class, EIntentService.class, EReceiver.class, EProvider.class, EFragment.class);
private ModelConstants() {
}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/ValidatorHelper.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/ValidatorHelper.java
index f7a6fad810..234c7fffa6 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/ValidatorHelper.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/ValidatorHelper.java
@@ -34,6 +34,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Set;
+import java.util.TreeSet;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
@@ -53,6 +54,8 @@
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.EFragment;
+import org.androidannotations.annotations.EIntentService;
+import org.androidannotations.annotations.ServiceAction;
import org.androidannotations.annotations.Trace;
import org.androidannotations.annotations.ViewById;
import org.androidannotations.annotations.rest.Delete;
@@ -205,6 +208,11 @@ public void enclosingElementHasEFragment(Element element, AnnotationElements val
hasClassAnnotation(element, enclosingElement, validatedElements, EFragment.class, valid);
}
+ public void enclosingElementHasEIntentService(Element element, AnnotationElements validatedElements, IsValid valid) {
+ Element enclosingElement = element.getEnclosingElement();
+ hasClassAnnotation(element, enclosingElement, validatedElements, EIntentService.class, valid);
+ }
+
public void hasEActivity(Element element, AnnotationElements validatedElements, IsValid valid) {
hasClassAnnotation(element, element, validatedElements, EActivity.class, valid);
}
@@ -494,6 +502,10 @@ public void extendsService(Element element, IsValid valid) {
extendsType(element, CanonicalNameConstants.SERVICE, valid);
}
+ public void extendsIntentService(Element element, IsValid valid) {
+ extendsType(element, CanonicalNameConstants.INTENT_SERVICE, valid);
+ }
+
public void extendsReceiver(Element element, IsValid valid) {
extendsType(element, CanonicalNameConstants.BROADCAST_RECEIVER, valid);
}
@@ -1178,4 +1190,23 @@ public void validateInterceptors(Element element, IsValid valid) {
}
}
+ public void hasNotMultipleAnnotatedMethodWithSameName(Element element, IsValid valid, Class extends Annotation> annotation) {
+ Set actionNames = new TreeSet();
+
+ List extends Element> enclosedElements = element.getEnclosedElements();
+ for (Element enclosedElement : enclosedElements) {
+ if (enclosedElement.getKind() != ElementKind.METHOD || !annotationHelper.hasOneOfClassAnnotations(enclosedElement, annotation)) {
+ continue;
+ }
+
+ String enclosedElementName = enclosedElement.getSimpleName().toString();
+ if (actionNames.contains(enclosedElementName)) {
+ valid.invalidate();
+ annotationHelper.printError(enclosedElement, "The " + TargetAnnotationHelper.annotationName(ServiceAction.class) + " annotated method must have unique name even if the signature is not the same");
+ } else {
+ actionNames.add(enclosedElementName);
+ }
+ }
+ }
+
}
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 cf1792c191..7ca53b6c71 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EBeanHolder.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EBeanHolder.java
@@ -130,6 +130,9 @@ public class EBeanHolder {
private ViewChangedHolder viewChangedHolder;
+ public JVar onHandleIntentIntent;
+ public JBlock onHandleIntentBody;
+
/**
* Only defined in beans that implement {@link HasViews}
*/
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EIntentServiceProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EIntentServiceProcessor.java
new file mode 100644
index 0000000000..341498f748
--- /dev/null
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EIntentServiceProcessor.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (C) 2010-2013 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 static com.sun.codemodel.JExpr._this;
+import static com.sun.codemodel.JMod.FINAL;
+import static com.sun.codemodel.JMod.PRIVATE;
+import static com.sun.codemodel.JMod.PUBLIC;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+
+import org.androidannotations.annotations.EIntentService;
+import org.androidannotations.helper.ModelConstants;
+
+import com.sun.codemodel.ClassType;
+import com.sun.codemodel.JBlock;
+import com.sun.codemodel.JClass;
+import com.sun.codemodel.JCodeModel;
+import com.sun.codemodel.JDefinedClass;
+import com.sun.codemodel.JExpr;
+import com.sun.codemodel.JMethod;
+import com.sun.codemodel.JVar;
+
+public class EIntentServiceProcessor extends EServiceProcessor {
+
+ public EIntentServiceProcessor(ProcessingEnvironment processingEnv) {
+ super(processingEnv);
+ }
+
+ @Override
+ public String getTarget() {
+ return EIntentService.class.getName();
+ }
+
+ @Override
+ public void process(Element element, JCodeModel codeModel, EBeansHolder eBeansHolder) throws Exception {
+
+ TypeElement typeElement = (TypeElement) element;
+
+ String annotatedComponentQualifiedName = typeElement.getQualifiedName().toString();
+
+ String generatedComponentQualifiedName = annotatedComponentQualifiedName + ModelConstants.GENERATION_SUFFIX;
+
+ JDefinedClass generatedClass = codeModel._class(PUBLIC | FINAL, generatedComponentQualifiedName, ClassType.CLASS);
+
+ EBeanHolder holder = eBeansHolder.create(element, EIntentService.class, generatedClass);
+
+ JClass annotatedComponent = codeModel.directClass(annotatedComponentQualifiedName);
+
+ holder.generatedClass._extends(annotatedComponent);
+
+ holder.contextRef = _this();
+
+ JMethod init = holder.generatedClass.method(PRIVATE, codeModel.VOID, "init_");
+ holder.initBody = init.body();
+ {
+ // onCreate
+ JMethod onCreate = holder.generatedClass.method(PUBLIC, codeModel.VOID, "onCreate");
+ onCreate.annotate(Override.class);
+ JBlock onCreateBody = onCreate.body();
+ onCreateBody.invoke(init);
+ onCreateBody.invoke(JExpr._super(), onCreate);
+ }
+
+ {
+ // onHandleIntent
+ JMethod onHandleIntent = holder.generatedClass.method(PUBLIC, codeModel.VOID, "onHandleIntent");
+ JVar intent = onHandleIntent.param(eBeansHolder.classes().INTENT, "intent");
+ onHandleIntent.annotate(Override.class);
+ JBlock onHandleIntentBody = onHandleIntent.body();
+ aptCodeModelHelper.callSuperMethod(onHandleIntent, holder, onHandleIntentBody);
+
+ holder.onHandleIntentIntent = intent;
+ holder.onHandleIntentBody = onHandleIntentBody;
+ }
+
+ {
+ /*
+ * Setting to null shouldn't be a problem as long as we don't allow
+ *
+ * @App and @Extra on this component
+ */
+ holder.initIfActivityBody = null;
+ holder.initActivityRef = null;
+ }
+
+ aptCodeModelHelper.addServiceIntentBuilder(codeModel, holder, annotationHelper);
+ }
+}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EServiceProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EServiceProcessor.java
index 00c5aa53a4..53c0ac7832 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EServiceProcessor.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/EServiceProcessor.java
@@ -39,9 +39,9 @@
public class EServiceProcessor implements GeneratingElementProcessor {
- private final APTCodeModelHelper aptCodeModelHelper;
+ final APTCodeModelHelper aptCodeModelHelper;
- private final AnnotationHelper annotationHelper;
+ final AnnotationHelper annotationHelper;
public EServiceProcessor(ProcessingEnvironment processingEnv) {
aptCodeModelHelper = new APTCodeModelHelper();
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/ExtraProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/ExtraProcessor.java
index 2e92d3c51f..ae4a458801 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/ExtraProcessor.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/ExtraProcessor.java
@@ -18,23 +18,16 @@
import static com.sun.codemodel.JExpr._null;
import static com.sun.codemodel.JExpr._super;
import static com.sun.codemodel.JExpr._this;
-import static com.sun.codemodel.JExpr.cast;
import static com.sun.codemodel.JExpr.invoke;
import static com.sun.codemodel.JExpr.lit;
import static com.sun.codemodel.JMod.FINAL;
import static com.sun.codemodel.JMod.PRIVATE;
import static com.sun.codemodel.JMod.PUBLIC;
import static com.sun.codemodel.JMod.STATIC;
-import static org.androidannotations.helper.CanonicalNameConstants.PARCELABLE;
-import static org.androidannotations.helper.CanonicalNameConstants.SERIALIZABLE;
-import static org.androidannotations.helper.CanonicalNameConstants.STRING;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
-import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.Elements;
-import javax.lang.model.util.Types;
import org.androidannotations.annotations.Extra;
import org.androidannotations.helper.APTCodeModelHelper;
@@ -50,11 +43,9 @@
import com.sun.codemodel.JFieldVar;
import com.sun.codemodel.JInvocation;
import com.sun.codemodel.JMethod;
-import com.sun.codemodel.JMod;
import com.sun.codemodel.JPrimitiveType;
import com.sun.codemodel.JTryBlock;
import com.sun.codemodel.JType;
-import com.sun.codemodel.JTypeVar;
import com.sun.codemodel.JVar;
public class ExtraProcessor implements DecoratingElementProcessor {
@@ -87,19 +78,14 @@ public void process(Element element, JCodeModel codeModel, EBeanHolder holder) {
Classes classes = holder.classes();
if (!isPrimitive && holder.cast == null) {
- generateCastMethod(codeModel, holder);
+ helper.addCastMethod(codeModel, holder);
}
if (holder.extras == null) {
injectExtras(holder, codeModel);
}
- String staticFieldName;
- if (fieldName.endsWith("Extra")) {
- staticFieldName = CaseHelper.camelCaseToUpperSnakeCase(fieldName);
- } else {
- staticFieldName = CaseHelper.camelCaseToUpperSnakeCase(fieldName + "Extra");
- }
+ String staticFieldName = CaseHelper.camelCaseToUpperSnakeCase(null, fieldName, "Extra");
JFieldVar extraKeyField = holder.generatedClass.field(PUBLIC | STATIC | FINAL, classes.STRING, staticFieldName, lit(extraKey));
@@ -137,53 +123,15 @@ public void process(Element element, JCodeModel codeModel, EBeanHolder holder) {
// flags()
JMethod method = holder.intentBuilderClass.method(PUBLIC, holder.intentBuilderClass, fieldName);
- boolean castToSerializable = false;
- boolean castToParcelable = false;
- TypeMirror extraType = elementType;
- if (extraType.getKind() == TypeKind.DECLARED) {
- Elements elementUtils = processingEnv.getElementUtils();
- Types typeUtils = processingEnv.getTypeUtils();
- TypeMirror parcelableType = elementUtils.getTypeElement(PARCELABLE).asType();
- if (!typeUtils.isSubtype(extraType, parcelableType)) {
- TypeMirror stringType = elementUtils.getTypeElement(STRING).asType();
- if (!typeUtils.isSubtype(extraType, stringType)) {
- castToSerializable = true;
- }
- } else {
- TypeMirror serializableType = elementUtils.getTypeElement(SERIALIZABLE).asType();
- if (typeUtils.isSubtype(extraType, serializableType)) {
- castToParcelable = true;
- }
- }
- }
- JClass paramClass = helper.typeMirrorToJClass(extraType, holder);
- JVar extraParam = method.param(paramClass, fieldName);
+ helper.addIntentBuilderPutExtraMethod(codeModel, holder, helper, processingEnv, method, elementType, fieldName, staticFieldName);
+
JBlock body = method.body();
- JInvocation invocation = body.invoke(holder.intentField, "putExtra").arg(extraKeyField);
- if (castToSerializable) {
- invocation.arg(cast(classes.SERIALIZABLE, extraParam));
- } else if (castToParcelable) {
- invocation.arg(cast(classes.PARCELABLE, extraParam));
- } else {
- invocation.arg(extraParam);
- }
body._return(_this());
}
}
}
- private void generateCastMethod(JCodeModel codeModel, EBeanHolder holder) {
- JType objectType = codeModel._ref(Object.class);
- JMethod method = holder.generatedClass.method(JMod.PRIVATE, objectType, "cast_");
- JTypeVar genericType = method.generify("T");
- method.type(genericType);
- JVar objectParam = method.param(objectType, "object");
- method.annotate(SuppressWarnings.class).param("value", "unchecked");
- method.body()._return(JExpr.cast(genericType, objectParam));
- holder.cast = method;
- }
-
/**
* Adds call to injectExtras_() in onCreate and setIntent() methods.
*/
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/ServiceActionProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/ServiceActionProcessor.java
new file mode 100644
index 0000000000..305c572534
--- /dev/null
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/ServiceActionProcessor.java
@@ -0,0 +1,167 @@
+/**
+ * Copyright (C) 2010-2013 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 static com.sun.codemodel.JExpr._null;
+import static com.sun.codemodel.JExpr.lit;
+import static com.sun.codemodel.JMod.FINAL;
+import static com.sun.codemodel.JMod.PUBLIC;
+import static com.sun.codemodel.JMod.STATIC;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.ServiceAction;
+import org.androidannotations.helper.APTCodeModelHelper;
+import org.androidannotations.helper.CaseHelper;
+import org.androidannotations.processing.EBeansHolder.Classes;
+
+import com.sun.codemodel.JBlock;
+import com.sun.codemodel.JClass;
+import com.sun.codemodel.JCodeModel;
+import com.sun.codemodel.JExpr;
+import com.sun.codemodel.JExpression;
+import com.sun.codemodel.JFieldVar;
+import com.sun.codemodel.JInvocation;
+import com.sun.codemodel.JMethod;
+import com.sun.codemodel.JPrimitiveType;
+import com.sun.codemodel.JType;
+import com.sun.codemodel.JVar;
+
+public class ServiceActionProcessor implements DecoratingElementProcessor {
+
+ private final APTCodeModelHelper helper = new APTCodeModelHelper();
+ private final ProcessingEnvironment processingEnv;
+
+ public ServiceActionProcessor(ProcessingEnvironment processingEnv) {
+ this.processingEnv = processingEnv;
+ }
+
+ @Override
+ public String getTarget() {
+ return ServiceAction.class.getName();
+ }
+
+ @Override
+ public void process(Element element, JCodeModel codeModel, EBeanHolder holder) {
+ ExecutableElement executableElement = (ExecutableElement) element;
+ String methodName = element.getSimpleName().toString();
+
+ Classes classes = holder.classes();
+
+ // Action field
+ ServiceAction annotation = element.getAnnotation(ServiceAction.class);
+ String extraKey = annotation.value();
+ if (extraKey.isEmpty()) {
+ extraKey = methodName;
+ }
+
+ String staticFieldName = CaseHelper.camelCaseToUpperSnakeCase("action", methodName, null);
+
+ JFieldVar actionKeyField = holder.generatedClass.field(PUBLIC | STATIC | FINAL, classes.STRING, staticFieldName, lit(extraKey));
+
+ if (holder.onHandleIntentBody != null) {
+ JBlock actionBlock = holder.onHandleIntentBody.block();
+
+ // getAction
+ JInvocation getActionInvok = holder.onHandleIntentIntent.invoke("getAction");
+ JVar actionVar = actionBlock.decl(classes.STRING, "action", getActionInvok);
+
+ // If action match, call the method
+ JBlock callActionBlock = actionBlock._if(actionKeyField.invoke("equals").arg(actionVar))._then();
+ JInvocation callActionInvok = JExpr._super().invoke(methodName);
+
+ // For each method params, we get back value from extras and put it
+ // in super calls
+ List extends VariableElement> methodParameters = executableElement.getParameters();
+ if (methodParameters.size() > 0) {
+ if (holder.cast == null) {
+ helper.addCastMethod(codeModel, holder);
+ }
+
+ // Extras
+ JVar extras = callActionBlock.decl(classes.BUNDLE, "extras");
+ extras.init(holder.onHandleIntentIntent.invoke("getExtras"));
+ JBlock extrasNotNullBlock = callActionBlock._if(extras.ne(_null()))._then();
+
+ List extraFields = new ArrayList();
+
+ // Extras params
+ for (VariableElement param : methodParameters) {
+ holder.onHandleIntentIntent.invoke("getStringExtra");
+
+ String paramName = param.getSimpleName().toString();
+ String extraParamName = paramName + "Extra";
+ JClass extraParamClass = helper.typeMirrorToJClass(param.asType(), holder);
+ boolean isPrimitive = param.asType().getKind().isPrimitive();
+
+ JExpression extraInvok;
+ if (isPrimitive) {
+ JPrimitiveType primitiveType = JType.parse(codeModel, param.asType().toString());
+ JClass wrapperType = primitiveType.boxify();
+ extraInvok = JExpr.cast(wrapperType, extras.invoke("get").arg(paramName));
+ } else {
+ extraInvok = JExpr.invoke(holder.cast).arg(extras.invoke("get").arg(paramName));
+ }
+ JVar extraField = extrasNotNullBlock.decl(extraParamClass, extraParamName, extraInvok);
+ extraFields.add(extraField);
+ }
+
+ for (JVar extraField : extraFields) {
+ callActionInvok.arg(extraField);
+ }
+ extrasNotNullBlock.add(callActionInvok);
+ } else {
+ callActionBlock.add(callActionInvok);
+ }
+
+ callActionBlock._return();
+ }
+
+ /*
+ * holder.intentBuilderClass may be null if the annotated component is
+ * an abstract activity
+ */
+ if (holder.intentBuilderClass != null) {
+ // flags()
+ JMethod method = holder.intentBuilderClass.method(PUBLIC, holder.intentBuilderClass, methodName);
+ JBlock body = method.body();
+
+ // setAction
+ body.invoke(holder.intentField, "setAction").arg(actionKeyField);
+
+ // For each method params, we get put value into extras
+ List extends VariableElement> methodParameters = executableElement.getParameters();
+ if (methodParameters.size() > 0) {
+
+ // Extras params
+ for (VariableElement param : methodParameters) {
+ String paramName = param.getSimpleName().toString();
+
+ helper.addIntentBuilderPutExtraMethod(codeModel, holder, helper, processingEnv, method, param.asType(), paramName, paramName);
+ }
+
+ }
+ body._return(JExpr._this());
+ }
+
+ }
+}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/EIntentServiceValidator.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/EIntentServiceValidator.java
new file mode 100644
index 0000000000..af6822e277
--- /dev/null
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/EIntentServiceValidator.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (C) 2010-2013 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.validation;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.Element;
+
+import org.androidannotations.annotations.EIntentService;
+import org.androidannotations.annotations.ServiceAction;
+import org.androidannotations.helper.AndroidManifest;
+import org.androidannotations.helper.TargetAnnotationHelper;
+import org.androidannotations.helper.ValidatorHelper;
+import org.androidannotations.model.AnnotationElements;
+
+public class EIntentServiceValidator implements ElementValidator {
+
+ private final ValidatorHelper validatorHelper;
+ private final AndroidManifest androidManifest;
+
+ public EIntentServiceValidator(ProcessingEnvironment processingEnv, AndroidManifest androidManifest) {
+ this.androidManifest = androidManifest;
+ TargetAnnotationHelper annotationHelper = new TargetAnnotationHelper(processingEnv, getTarget());
+ validatorHelper = new ValidatorHelper(annotationHelper);
+ }
+
+ @Override
+ public String getTarget() {
+ return EIntentService.class.getName();
+ }
+
+ @Override
+ public boolean validate(Element element, AnnotationElements validatedElements) {
+
+ IsValid valid = new IsValid();
+
+ validatorHelper.extendsIntentService(element, valid);
+
+ validatorHelper.hasNotMultipleAnnotatedMethodWithSameName(element, valid, ServiceAction.class);
+
+ validatorHelper.isNotFinal(element, valid);
+
+ validatorHelper.componentRegistered(element, androidManifest, valid);
+
+ return valid.isValid();
+ }
+
+}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/ServiceActionValidator.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/ServiceActionValidator.java
new file mode 100644
index 0000000000..3c218cc756
--- /dev/null
+++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/ServiceActionValidator.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright (C) 2010-2013 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.validation;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+
+import org.androidannotations.annotations.ServiceAction;
+import org.androidannotations.helper.TargetAnnotationHelper;
+import org.androidannotations.helper.ValidatorHelper;
+import org.androidannotations.model.AnnotationElements;
+
+public class ServiceActionValidator implements ElementValidator {
+
+ private ValidatorHelper validatorHelper;
+
+ public ServiceActionValidator(ProcessingEnvironment processingEnv) {
+ TargetAnnotationHelper annotationHelper = new TargetAnnotationHelper(processingEnv, getTarget());
+ validatorHelper = new ValidatorHelper(annotationHelper);
+ }
+
+ @Override
+ public String getTarget() {
+ return ServiceAction.class.getName();
+ }
+
+ @Override
+ public boolean validate(Element element, AnnotationElements validatedElements) {
+ IsValid valid = new IsValid();
+
+ validatorHelper.enclosingElementHasEIntentService(element, validatedElements, valid);
+
+ ExecutableElement executableElement = (ExecutableElement) element;
+ validatorHelper.returnTypeIsVoid(executableElement, valid);
+
+ validatorHelper.isNotPrivate(element, valid);
+
+ return valid.isValid();
+ }
+
+}
diff --git a/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/helper/CaseHelperTest.java b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/helper/CaseHelperTest.java
new file mode 100644
index 0000000000..15f1c60aa6
--- /dev/null
+++ b/AndroidAnnotations/androidannotations/src/test/java/org/androidannotations/helper/CaseHelperTest.java
@@ -0,0 +1,26 @@
+package org.androidannotations.helper;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+public class CaseHelperTest {
+
+ @Test
+ public void testCamelCaseToUpperSnakeCaseString() throws Exception {
+ Assert.assertEquals("CAMEL_CASE", CaseHelper.camelCaseToUpperSnakeCase("camelCase"));
+ Assert.assertEquals("CAMEL_CASE", CaseHelper.camelCaseToUpperSnakeCase("camel_case"));
+ Assert.assertEquals("CAMEL_CASE", CaseHelper.camelCaseToUpperSnakeCase("Camel_Case"));
+ }
+
+ @Test
+ public void testCamelCaseToUpperSnakeCaseStringStringString() throws Exception {
+ Assert.assertEquals("CAMEL_CASE", CaseHelper.camelCaseToUpperSnakeCase(null, "camelCase", null));
+ Assert.assertEquals("PREFIX_CAMEL_CASE", CaseHelper.camelCaseToUpperSnakeCase("prefix", "camelCase", null));
+ Assert.assertEquals("PREFIX_CAMEL_CASE", CaseHelper.camelCaseToUpperSnakeCase("prefix", "prefixCamelCase", null));
+ Assert.assertEquals("CAMEL_CASE_SUFFIX", CaseHelper.camelCaseToUpperSnakeCase(null, "camelCase", "suffix"));
+ Assert.assertEquals("CAMEL_CASE_SUFFIX", CaseHelper.camelCaseToUpperSnakeCase(null, "camelCaseSuffix", "suffix"));
+ Assert.assertEquals("PREFIX_CAMEL_CASE_SUFFIX", CaseHelper.camelCaseToUpperSnakeCase("prefix", "camelCase", "suffix"));
+ }
+
+}
diff --git a/AndroidAnnotations/functional-test-1-5-tests/src/test/java/org/androidannotations/test15/eintentservice/MyIntentServiceTest.java b/AndroidAnnotations/functional-test-1-5-tests/src/test/java/org/androidannotations/test15/eintentservice/MyIntentServiceTest.java
new file mode 100644
index 0000000000..bd629074ab
--- /dev/null
+++ b/AndroidAnnotations/functional-test-1-5-tests/src/test/java/org/androidannotations/test15/eintentservice/MyIntentServiceTest.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright (C) 2010-2013 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.test15.eintentservice;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+import org.androidannotations.test15.AndroidAnnotationsTestRunner;
+import org.androidannotations.test15.EmptyActivityWithoutLayout;
+import org.androidannotations.test15.EmptyActivityWithoutLayout_;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.content.Intent;
+
+@RunWith(AndroidAnnotationsTestRunner.class)
+public class MyIntentServiceTest {
+
+ @Test
+ public void testAction() {
+ IntentServiceHandledAction.actionForTestHandled = null;
+
+ // Simulate call to intent builder and retrieve the configured Intent
+ EmptyActivityWithoutLayout context = new EmptyActivityWithoutLayout_();
+ Intent intent = IntentServiceHandledAction_.intent(context) //
+ .MyActionOneParam("test") //
+ .get();
+
+ // Simulate the creation of IntentService by Android
+ IntentServiceHandledAction intentServiceHandledAction = new IntentServiceHandledAction_();
+ intentServiceHandledAction.onHandleIntent(intent);
+
+ assertThat(IntentServiceHandledAction_.actionForTestHandled).isEqualTo("test");
+ }
+
+}
diff --git a/AndroidAnnotations/functional-test-1-5/AndroidManifest.xml b/AndroidAnnotations/functional-test-1-5/AndroidManifest.xml
index 209067cb91..ea5df88fd4 100644
--- a/AndroidAnnotations/functional-test-1-5/AndroidManifest.xml
+++ b/AndroidAnnotations/functional-test-1-5/AndroidManifest.xml
@@ -1,6 +1,5 @@
-
-
+
+
@@ -93,6 +91,15 @@
+
+
+
diff --git a/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/eintentservice/IntentServiceHandledAction.java b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/eintentservice/IntentServiceHandledAction.java
new file mode 100644
index 0000000000..b22a1f5621
--- /dev/null
+++ b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/eintentservice/IntentServiceHandledAction.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright (C) 2010-2013 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.test15.eintentservice;
+
+import org.androidannotations.annotations.Bean;
+import org.androidannotations.annotations.EIntentService;
+import org.androidannotations.annotations.ServiceAction;
+import org.androidannotations.test15.ebean.EnhancedClass;
+
+import android.app.IntentService;
+import android.content.Intent;
+
+@EIntentService
+public class IntentServiceHandledAction extends IntentService {
+
+ public static Object actionForTestHandled = null;
+
+ @Bean
+ EnhancedClass dependency;
+
+ public IntentServiceHandledAction() {
+ super(IntentServiceHandledAction.class.getSimpleName());
+ }
+
+ @ServiceAction
+ void myAction() {
+ actionForTestHandled = new Object();
+ }
+
+ @ServiceAction
+ void MyActionOneParam(String valueString) {
+ actionForTestHandled = valueString;
+ }
+
+ @ServiceAction("myAction")
+ void myActionTwoParams(String valueString, long valueLong) {
+ actionForTestHandled = valueString;
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ // Do nothing here
+ }
+
+}
diff --git a/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/eintentservice/MyIntentService.java b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/eintentservice/MyIntentService.java
new file mode 100644
index 0000000000..e4e3c9f067
--- /dev/null
+++ b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/eintentservice/MyIntentService.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright (C) 2010-2013 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.test15.eintentservice;
+
+import org.androidannotations.annotations.Bean;
+import org.androidannotations.annotations.EIntentService;
+import org.androidannotations.annotations.ServiceAction;
+import org.androidannotations.test15.ebean.EnhancedClass;
+
+import android.app.IntentService;
+import android.content.Intent;
+
+@EIntentService
+public class MyIntentService extends IntentService {
+
+ @Bean
+ EnhancedClass dependency;
+
+ public MyIntentService() {
+ super(MyIntentService.class.getSimpleName());
+ }
+
+ @ServiceAction
+ void myAction() {
+
+ }
+
+ @ServiceAction
+ void actionOne(String valueString) {
+
+ }
+
+ @ServiceAction("myAction")
+ void actionThree(String valueString, long valueLong) {
+
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ // Do nothing here
+ }
+
+}
diff --git a/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/eservice/MySimpleIntentService.java b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/eservice/MySimpleIntentService.java
new file mode 100644
index 0000000000..5f299bc4e2
--- /dev/null
+++ b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/eservice/MySimpleIntentService.java
@@ -0,0 +1,73 @@
+/**
+ * Copyright (C) 2010-2013 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.test15.eservice;
+
+import android.app.IntentService;
+import android.app.NotificationManager;
+import android.content.Intent;
+import android.util.Log;
+import android.widget.Toast;
+
+import org.androidannotations.annotations.Background;
+import org.androidannotations.annotations.Bean;
+import org.androidannotations.annotations.EService;
+import org.androidannotations.annotations.OrmLiteDao;
+import org.androidannotations.annotations.SystemService;
+import org.androidannotations.annotations.Trace;
+import org.androidannotations.annotations.UiThread;
+import org.androidannotations.test15.ebean.EnhancedClass;
+import org.androidannotations.test15.ormlite.DatabaseHelper;
+import org.androidannotations.test15.ormlite.User;
+import org.androidannotations.test15.ormlite.UserDao;
+
+@EService
+public class MySimpleIntentService extends IntentService {
+
+ @SystemService
+ NotificationManager notificationManager;
+
+ @Bean
+ EnhancedClass dependency;
+
+ @OrmLiteDao(helper = DatabaseHelper.class, model = User.class)
+ UserDao userDao;
+
+ public MySimpleIntentService() {
+ super(MySimpleIntentService.class.getSimpleName());
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ // Do some stuff...
+
+ showToast();
+ workInBackground();
+ }
+
+ @Trace
+ @UiThread
+ void showToast() {
+ Toast.makeText(getApplicationContext(), "Hello World!",
+ Toast.LENGTH_LONG).show();
+ }
+
+ @Trace
+ @Background
+ void workInBackground() {
+ Log.d(MySimpleIntentService.class.getSimpleName(), "Doing some background work.");
+ }
+
+}