From e22ca8e73787ef18e67d770c6c30734b7ab0570a Mon Sep 17 00:00:00 2001 From: Pierre-Yves Ricau Date: Tue, 5 Mar 2013 05:48:18 -0800 Subject: [PATCH 1/2] Otto integration: @Subscribe & @Produce methods are overriden to enable scanning of the subclass #272 --- .../AndroidAnnotationProcessor.java | 14 ++++ .../helper/AnnotationHelper.java | 10 +++ .../helper/CanonicalNameConstants.java | 6 ++ .../helper/ValidatorHelper.java | 24 +++++++ .../processing/ProduceProcessor.java | 48 +++++++++++++ .../processing/SubscribeProcessor.java | 48 +++++++++++++ .../validation/ProduceValidator.java | 69 +++++++++++++++++++ .../validation/SubscribeValidator.java | 69 +++++++++++++++++++ .../main/java/com/squareup/otto/Produce.java | 12 ++++ .../java/com/squareup/otto/Subscribe.java | 12 ++++ .../androidannotations/test15/otto/Event.java | 5 ++ .../test15/otto/OttoBean.java | 25 +++++++ 12 files changed, 342 insertions(+) create mode 100644 AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/ProduceProcessor.java create mode 100644 AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/SubscribeProcessor.java create mode 100644 AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/ProduceValidator.java create mode 100644 AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/SubscribeValidator.java create mode 100644 AndroidAnnotations/functional-test-1-5/src/main/java/com/squareup/otto/Produce.java create mode 100644 AndroidAnnotations/functional-test-1-5/src/main/java/com/squareup/otto/Subscribe.java create mode 100644 AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/otto/Event.java create mode 100644 AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/otto/OttoBean.java diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/AndroidAnnotationProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/AndroidAnnotationProcessor.java index 16b7a71d6b..a19e8b4553 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/AndroidAnnotationProcessor.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/AndroidAnnotationProcessor.java @@ -16,6 +16,8 @@ package org.androidannotations; import static org.androidannotations.helper.AndroidManifestFinder.ANDROID_MANIFEST_FILE_OPTION; +import static org.androidannotations.helper.CanonicalNameConstants.PRODUCE; +import static org.androidannotations.helper.CanonicalNameConstants.SUBSCRIBE; import static org.androidannotations.helper.ModelConstants.TRACE_OPTION; import java.io.IOException; @@ -164,6 +166,7 @@ import org.androidannotations.processing.OptionsMenuProcessor; import org.androidannotations.processing.OrmLiteDaoProcessor; import org.androidannotations.processing.PrefProcessor; +import org.androidannotations.processing.ProduceProcessor; import org.androidannotations.processing.ResProcessor; import org.androidannotations.processing.RestServiceProcessor; import org.androidannotations.processing.RoboGuiceProcessor; @@ -172,6 +175,7 @@ import org.androidannotations.processing.SeekBarTouchStartProcessor; import org.androidannotations.processing.SeekBarTouchStopProcessor; import org.androidannotations.processing.SharedPrefProcessor; +import org.androidannotations.processing.SubscribeProcessor; import org.androidannotations.processing.SystemServiceProcessor; import org.androidannotations.processing.TextChangeProcessor; import org.androidannotations.processing.TouchProcessor; @@ -229,6 +233,7 @@ import org.androidannotations.validation.OptionsMenuValidator; import org.androidannotations.validation.OrmLiteDaoValidator; import org.androidannotations.validation.PrefValidator; +import org.androidannotations.validation.ProduceValidator; import org.androidannotations.validation.ResValidator; import org.androidannotations.validation.RestServiceValidator; import org.androidannotations.validation.RoboGuiceValidator; @@ -238,6 +243,7 @@ import org.androidannotations.validation.SeekBarTouchStartValidator; import org.androidannotations.validation.SeekBarTouchStopValidator; import org.androidannotations.validation.SharedPrefValidator; +import org.androidannotations.validation.SubscribeValidator; import org.androidannotations.validation.SystemServiceValidator; import org.androidannotations.validation.TextChangeValidator; import org.androidannotations.validation.TouchValidator; @@ -429,6 +435,8 @@ private ModelValidator buildModelValidator(IRClass rClass, AndroidSystemServices */ modelValidator.register(new AfterViewsValidator(processingEnv)); modelValidator.register(new TraceValidator(processingEnv)); + modelValidator.register(new SubscribeValidator(processingEnv)); + modelValidator.register(new ProduceValidator(processingEnv)); modelValidator.register(new RunnableValidator(UiThread.class.getName(), processingEnv)); modelValidator.register(new RunnableValidator(Background.class.getName(), processingEnv)); modelValidator.register(new InstanceStateValidator(processingEnv)); @@ -436,6 +444,7 @@ private ModelValidator buildModelValidator(IRClass rClass, AndroidSystemServices modelValidator.register(new HttpsClientValidator(processingEnv, rClass)); modelValidator.register(new OnActivityResultValidator(processingEnv, rClass)); modelValidator.register(new HierarchyViewerSupportValidator(processingEnv, androidManifest)); + return modelValidator; } @@ -521,6 +530,8 @@ private ModelProcessor buildModelProcessor(IRClass rClass, AndroidSystemServices if (traceActivated()) { modelProcessor.register(new TraceProcessor()); } + modelProcessor.register(new SubscribeProcessor()); + modelProcessor.register(new ProduceProcessor()); modelProcessor.register(new UiThreadProcessor()); modelProcessor.register(new BackgroundProcessor()); modelProcessor.register(new AfterInjectProcessor()); @@ -652,6 +663,9 @@ public Set getSupportedAnnotationTypes() { set.add(annotationClass.getName()); } + set.add(SUBSCRIBE); + set.add(PRODUCE); + supportedAnnotationNames = Collections.unmodifiableSet(set); } return supportedAnnotationNames; 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 ef27ca5815..a579044f5f 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/AnnotationHelper.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/AnnotationHelper.java @@ -15,6 +15,8 @@ */ package org.androidannotations.helper; +import static org.androidannotations.helper.ModelConstants.GENERATION_SUFFIX; + import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -372,4 +374,12 @@ public DeclaredType extractAnnotationClassParameter(Element element, String anno return extractAnnotationClassParameter(element, annotationName, "value"); } + public boolean enclosingElementIsGenerated(Element element) { + /* + * TODO This isn't really safe, can we find a better way? + */ + Element enclosingElement = element.getEnclosingElement(); + return enclosingElement.getSimpleName().toString().endsWith(GENERATION_SUFFIX); + } + } 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 01c94ad946..d416f40be0 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/CanonicalNameConstants.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/CanonicalNameConstants.java @@ -162,6 +162,12 @@ public final class CanonicalNameConstants { public static final String SCHEME_REGISTRY = "org.apache.http.conn.scheme.SchemeRegistry"; public static final String SINGLE_CLIENT_CONN_MANAGER = "org.apache.http.impl.conn.SingleClientConnManager"; + /* + * Otto + */ + public static final String SUBSCRIBE = "com.squareup.otto.Subscribe"; + public static final String PRODUCE = "com.squareup.otto.Produce"; + private CanonicalNameConstants() { } 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 48a083475b..570e1833fe 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/ValidatorHelper.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/ValidatorHelper.java @@ -159,6 +159,13 @@ public void isNotPrivate(Element element, IsValid valid) { } } + public void isPublic(Element element, IsValid valid) { + if (!annotationHelper.isPublic(element)) { + valid.invalidate(); + annotationHelper.printAnnotationError(element, "%s cannot be used on a non public element"); + } + } + public void enclosingElementHasEBeanAnnotation(Element element, AnnotationElements validatedElements, IsValid valid) { Element enclosingElement = element.getEnclosingElement(); hasClassAnnotation(element, enclosingElement, validatedElements, EBean.class, valid); @@ -467,6 +474,15 @@ public void returnTypeIsVoid(ExecutableElement executableElement, IsValid valid) } } + public void returnTypeIsNotVoid(ExecutableElement executableElement, IsValid valid) { + TypeMirror returnType = executableElement.getReturnType(); + + if (returnType.getKind() == TypeKind.VOID) { + valid.invalidate(); + annotationHelper.printAnnotationError(executableElement, "%s can only be used on a method with a return type non void"); + } + } + public void zeroOrOneParameter(ExecutableElement executableElement, IsValid valid) { List parameters = executableElement.getParameters(); @@ -682,6 +698,14 @@ public void extendsType(Element element, String typeQualifiedName, IsValid valid } } + public void hasExactlyOneParameter(ExecutableElement executableElement, IsValid valid) { + List parameters = executableElement.getParameters(); + if (parameters.size() != 1) { + valid.invalidate(); + annotationHelper.printAnnotationError(executableElement, "%s can only be used on a method with exactly one parameter, instead of " + parameters.size()); + } + } + public void hasOneOrTwoParametersAndFirstIsBoolean(ExecutableElement executableElement, IsValid valid) { List parameters = executableElement.getParameters(); diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/ProduceProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/ProduceProcessor.java new file mode 100644 index 0000000000..be05b9dbd0 --- /dev/null +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/ProduceProcessor.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.processing; + +import static org.androidannotations.helper.CanonicalNameConstants.PRODUCE; + +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; + +import org.androidannotations.helper.APTCodeModelHelper; + +import com.sun.codemodel.JClassAlreadyExistsException; +import com.sun.codemodel.JCodeModel; +import com.sun.codemodel.JMethod; + +public class ProduceProcessor implements DecoratingElementProcessor { + + private final APTCodeModelHelper helper = new APTCodeModelHelper(); + + @Override + public String getTarget() { + return PRODUCE; + } + + @Override + public void process(Element element, JCodeModel codeModel, EBeanHolder holder) throws JClassAlreadyExistsException { + + ExecutableElement executableElement = (ExecutableElement) element; + + JMethod delegatingMethod = helper.overrideAnnotatedMethod(executableElement, holder); + + delegatingMethod.annotate(holder.refClass(PRODUCE)); + } + +} diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/SubscribeProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/SubscribeProcessor.java new file mode 100644 index 0000000000..e4b97e5cdf --- /dev/null +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/SubscribeProcessor.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.processing; + +import static org.androidannotations.helper.CanonicalNameConstants.SUBSCRIBE; + +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; + +import org.androidannotations.helper.APTCodeModelHelper; + +import com.sun.codemodel.JClassAlreadyExistsException; +import com.sun.codemodel.JCodeModel; +import com.sun.codemodel.JMethod; + +public class SubscribeProcessor implements DecoratingElementProcessor { + + private final APTCodeModelHelper helper = new APTCodeModelHelper(); + + @Override + public String getTarget() { + return SUBSCRIBE; + } + + @Override + public void process(Element element, JCodeModel codeModel, EBeanHolder holder) throws JClassAlreadyExistsException { + + ExecutableElement executableElement = (ExecutableElement) element; + + JMethod delegatingMethod = helper.overrideAnnotatedMethod(executableElement, holder); + + delegatingMethod.annotate(holder.refClass(SUBSCRIBE)); + } + +} diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/ProduceValidator.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/ProduceValidator.java new file mode 100644 index 0000000000..8945813e34 --- /dev/null +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/ProduceValidator.java @@ -0,0 +1,69 @@ +/** + * 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 static org.androidannotations.helper.CanonicalNameConstants.PRODUCE; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; + +import org.androidannotations.helper.TargetAnnotationHelper; +import org.androidannotations.helper.ValidatorHelper; +import org.androidannotations.model.AnnotationElements; + +public class ProduceValidator implements ElementValidator { + + private final ValidatorHelper validatorHelper; + private final TargetAnnotationHelper annotationHelper; + + public ProduceValidator(ProcessingEnvironment processingEnv) { + annotationHelper = new TargetAnnotationHelper(processingEnv, getTarget()); + validatorHelper = new ValidatorHelper(annotationHelper); + } + + @Override + public String getTarget() { + return PRODUCE; + } + + @Override + public boolean validate(Element element, AnnotationElements validatedElements) { + + if (annotationHelper.enclosingElementIsGenerated(element)) { + return false; + } + + IsValid valid = new IsValid(); + + validatorHelper.enclosingElementHasEnhancedComponentAnnotation(element, validatedElements, valid); + + ExecutableElement executableElement = (ExecutableElement) element; + + validatorHelper.returnTypeIsNotVoid(executableElement, valid); + + validatorHelper.isPublic(element, valid); + + validatorHelper.doesntThrowException(executableElement, valid); + + validatorHelper.isNotFinal(element, valid); + + validatorHelper.zeroParameter(executableElement, valid); + + return valid.isValid(); + } + +} diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/SubscribeValidator.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/SubscribeValidator.java new file mode 100644 index 0000000000..51e06d065d --- /dev/null +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/SubscribeValidator.java @@ -0,0 +1,69 @@ +/** + * 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 static org.androidannotations.helper.CanonicalNameConstants.SUBSCRIBE; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; + +import org.androidannotations.helper.TargetAnnotationHelper; +import org.androidannotations.helper.ValidatorHelper; +import org.androidannotations.model.AnnotationElements; + +public class SubscribeValidator implements ElementValidator { + + private final ValidatorHelper validatorHelper; + private final TargetAnnotationHelper annotationHelper; + + public SubscribeValidator(ProcessingEnvironment processingEnv) { + annotationHelper = new TargetAnnotationHelper(processingEnv, getTarget()); + validatorHelper = new ValidatorHelper(annotationHelper); + } + + @Override + public String getTarget() { + return SUBSCRIBE; + } + + @Override + public boolean validate(Element element, AnnotationElements validatedElements) { + + if (annotationHelper.enclosingElementIsGenerated(element)) { + return false; + } + + IsValid valid = new IsValid(); + + validatorHelper.enclosingElementHasEnhancedComponentAnnotation(element, validatedElements, valid); + + ExecutableElement executableElement = (ExecutableElement) element; + + validatorHelper.returnTypeIsVoid(executableElement, valid); + + validatorHelper.isPublic(element, valid); + + validatorHelper.doesntThrowException(executableElement, valid); + + validatorHelper.isNotFinal(element, valid); + + validatorHelper.hasExactlyOneParameter(executableElement, valid); + + return valid.isValid(); + } + +} diff --git a/AndroidAnnotations/functional-test-1-5/src/main/java/com/squareup/otto/Produce.java b/AndroidAnnotations/functional-test-1-5/src/main/java/com/squareup/otto/Produce.java new file mode 100644 index 0000000000..328d816998 --- /dev/null +++ b/AndroidAnnotations/functional-test-1-5/src/main/java/com/squareup/otto/Produce.java @@ -0,0 +1,12 @@ +package com.squareup.otto; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Produce { + +} diff --git a/AndroidAnnotations/functional-test-1-5/src/main/java/com/squareup/otto/Subscribe.java b/AndroidAnnotations/functional-test-1-5/src/main/java/com/squareup/otto/Subscribe.java new file mode 100644 index 0000000000..9e7bafe336 --- /dev/null +++ b/AndroidAnnotations/functional-test-1-5/src/main/java/com/squareup/otto/Subscribe.java @@ -0,0 +1,12 @@ +package com.squareup.otto; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Subscribe { + +} diff --git a/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/otto/Event.java b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/otto/Event.java new file mode 100644 index 0000000000..d37327956c --- /dev/null +++ b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/otto/Event.java @@ -0,0 +1,5 @@ +package org.androidannotations.test15.otto; + +public class Event { + +} diff --git a/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/otto/OttoBean.java b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/otto/OttoBean.java new file mode 100644 index 0000000000..e1e1b05987 --- /dev/null +++ b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/otto/OttoBean.java @@ -0,0 +1,25 @@ +package org.androidannotations.test15.otto; + +import org.androidannotations.annotations.Background; +import org.androidannotations.annotations.EBean; +import org.androidannotations.annotations.Trace; + +import com.squareup.otto.Produce; +import com.squareup.otto.Subscribe; + +@EBean +public class OttoBean { + + @Trace + @Background + @Subscribe + public void onEvent(Event event) { + + } + + @Produce + public Event produceEvent() { + return new Event(); + } + +} From 26199a5e7be88420d568b34d20ac8da2d0af0948 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Ricau Date: Tue, 5 Mar 2013 06:20:49 -0800 Subject: [PATCH 2/2] Ignoring Otto annotations when used separately from AA annotated classes --- .../helper/AnnotationHelper.java | 15 +++++++++++++ .../helper/ModelConstants.java | 21 +++++++++++++++++++ .../helper/ValidatorHelper.java | 14 ++----------- .../validation/ProduceValidator.java | 9 +++++--- .../validation/SubscribeValidator.java | 9 +++++--- 5 files changed, 50 insertions(+), 18 deletions(-) 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 a579044f5f..9530be82b6 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/AnnotationHelper.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/AnnotationHelper.java @@ -16,6 +16,7 @@ package org.androidannotations.helper; import static org.androidannotations.helper.ModelConstants.GENERATION_SUFFIX; +import static org.androidannotations.helper.ModelConstants.VALID_ENHANCED_COMPONENT_ANNOTATIONS; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; @@ -382,4 +383,18 @@ public boolean enclosingElementIsGenerated(Element element) { return enclosingElement.getSimpleName().toString().endsWith(GENERATION_SUFFIX); } + public boolean enclosingElementHasEnhancedComponentAnnotation(Element element) { + Element enclosingElement = element.getEnclosingElement(); + return hasOneOfClassAnnotations(enclosingElement, VALID_ENHANCED_COMPONENT_ANNOTATIONS); + } + + public boolean hasOneOfClassAnnotations(Element element, List> validAnnotations) { + for (Class validAnnotation : validAnnotations) { + if (element.getAnnotation(validAnnotation) != null) { + return true; + } + } + return false; + } + } 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 a5cfca3c95..8abc7ff15b 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/ModelConstants.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/ModelConstants.java @@ -15,12 +15,33 @@ */ package org.androidannotations.helper; +import static java.util.Arrays.asList; + +import java.lang.annotation.Annotation; +import java.util.List; + +import org.androidannotations.annotations.EActivity; +import org.androidannotations.annotations.EApplication; +import org.androidannotations.annotations.EBean; +import org.androidannotations.annotations.EFragment; +import org.androidannotations.annotations.EProvider; +import org.androidannotations.annotations.EReceiver; +import org.androidannotations.annotations.EService; +import org.androidannotations.annotations.EView; +import org.androidannotations.annotations.EViewGroup; + public abstract class ModelConstants { public static final String GENERATION_SUFFIX = "_"; public static final String TRACE_OPTION = "trace"; + @SuppressWarnings("unchecked") + 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); + 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 570e1833fe..63c317b05d 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/ValidatorHelper.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/ValidatorHelper.java @@ -25,6 +25,8 @@ import static org.androidannotations.helper.CanonicalNameConstants.HTTP_MESSAGE_CONVERTER; import static org.androidannotations.helper.CanonicalNameConstants.INTERNET_PERMISSION; import static org.androidannotations.helper.ModelConstants.GENERATION_SUFFIX; +import static org.androidannotations.helper.ModelConstants.VALID_ENHANCED_COMPONENT_ANNOTATIONS; +import static org.androidannotations.helper.ModelConstants.VALID_ENHANCED_VIEW_SUPPORT_ANNOTATIONS; import java.lang.annotation.Annotation; import java.util.ArrayList; @@ -49,14 +51,8 @@ import javax.lang.model.util.Elements; import org.androidannotations.annotations.EActivity; -import org.androidannotations.annotations.EApplication; import org.androidannotations.annotations.EBean; import org.androidannotations.annotations.EFragment; -import org.androidannotations.annotations.EProvider; -import org.androidannotations.annotations.EReceiver; -import org.androidannotations.annotations.EService; -import org.androidannotations.annotations.EView; -import org.androidannotations.annotations.EViewGroup; import org.androidannotations.annotations.Trace; import org.androidannotations.annotations.ViewById; import org.androidannotations.annotations.rest.Delete; @@ -91,12 +87,6 @@ public class ValidatorHelper { private static final Collection VALID_LOG_LEVELS = Arrays.asList(LOG_VERBOSE, LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR); - @SuppressWarnings("unchecked") - private static final List> VALID_ENHANCED_VIEW_SUPPORT_ANNOTATIONS = asList(EActivity.class, EViewGroup.class, EView.class, EBean.class, EFragment.class); - - @SuppressWarnings("unchecked") - private 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); - protected final TargetAnnotationHelper annotationHelper; public ValidatorHelper(TargetAnnotationHelper targetAnnotationHelper) { diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/ProduceValidator.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/ProduceValidator.java index 8945813e34..cd1b3cf3c0 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/ProduceValidator.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/ProduceValidator.java @@ -43,16 +43,19 @@ public String getTarget() { @Override public boolean validate(Element element, AnnotationElements validatedElements) { - if (annotationHelper.enclosingElementIsGenerated(element)) { + if (!annotationHelper.enclosingElementHasEnhancedComponentAnnotation(element)) { return false; } IsValid valid = new IsValid(); - validatorHelper.enclosingElementHasEnhancedComponentAnnotation(element, validatedElements, valid); - ExecutableElement executableElement = (ExecutableElement) element; + /* + * We check that twice to skip invalid annotated elements + */ + validatorHelper.enclosingElementHasEnhancedComponentAnnotation(executableElement, validatedElements, valid); + validatorHelper.returnTypeIsNotVoid(executableElement, valid); validatorHelper.isPublic(element, valid); diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/SubscribeValidator.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/SubscribeValidator.java index 51e06d065d..8cd0db7155 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/SubscribeValidator.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/validation/SubscribeValidator.java @@ -43,16 +43,19 @@ public String getTarget() { @Override public boolean validate(Element element, AnnotationElements validatedElements) { - if (annotationHelper.enclosingElementIsGenerated(element)) { + if (!annotationHelper.enclosingElementHasEnhancedComponentAnnotation(element)) { return false; } IsValid valid = new IsValid(); - validatorHelper.enclosingElementHasEnhancedComponentAnnotation(element, validatedElements, valid); - ExecutableElement executableElement = (ExecutableElement) element; + /* + * We check that twice to skip invalid annotated elements + */ + validatorHelper.enclosingElementHasEnhancedComponentAnnotation(executableElement, validatedElements, valid); + validatorHelper.returnTypeIsVoid(executableElement, valid); validatorHelper.isPublic(element, valid);