Skip to content
This repository was archived by the owner on Feb 26, 2023. It is now read-only.

Commit 3b66168

Browse files
committed
Re-add Otto annotation handlers
We copy all non-AA annotations when we override a method. This can help Otto, because it does not read annotations from parent classes. But if a method is only annotated with Otto annotation, so we do not override it, the annotation will not be read Otto and the methods will not be called. To help that case, we re-add Otto handlers, which override (and annotate) Otto annotated methods in the generated subclass.
1 parent 2465468 commit 3b66168

7 files changed

Lines changed: 254 additions & 15 deletions

File tree

‎AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/AnnotationHandlers.java‎

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,22 @@
1515
*/
1616
package org.androidannotations.handler;
1717

18-
import org.androidannotations.handler.rest.*;
18+
import java.util.ArrayList;
19+
import java.util.Collections;
20+
import java.util.HashSet;
21+
import java.util.List;
22+
import java.util.Set;
23+
24+
import javax.annotation.processing.ProcessingEnvironment;
25+
26+
import org.androidannotations.handler.rest.DeleteHandler;
27+
import org.androidannotations.handler.rest.GetHandler;
28+
import org.androidannotations.handler.rest.HeadHandler;
29+
import org.androidannotations.handler.rest.OptionsHandler;
30+
import org.androidannotations.handler.rest.PostHandler;
31+
import org.androidannotations.handler.rest.PutHandler;
32+
import org.androidannotations.handler.rest.RestHandler;
33+
import org.androidannotations.handler.rest.RestServiceHandler;
1934
import org.androidannotations.helper.AndroidManifest;
2035
import org.androidannotations.helper.OptionsHelper;
2136
import org.androidannotations.holder.GeneratedClassHolder;
@@ -25,9 +40,6 @@
2540
import org.androidannotations.process.ProcessHolder;
2641
import org.androidannotations.rclass.IRClass;
2742

28-
import javax.annotation.processing.ProcessingEnvironment;
29-
import java.util.*;
30-
3143
public class AnnotationHandlers {
3244

3345
private List<AnnotationHandler<? extends GeneratedClassHolder>> annotationHandlers = new ArrayList<AnnotationHandler<? extends GeneratedClassHolder>>();
@@ -99,6 +111,8 @@ public AnnotationHandlers(ProcessingEnvironment processingEnvironment) {
99111
add(new SeekBarTouchStartHandler(processingEnvironment));
100112
add(new SeekBarTouchStopHandler(processingEnvironment));
101113
add(new ServiceActionHandler(processingEnvironment));
114+
add(new ProduceHandler(processingEnvironment));
115+
add(new SubscribeHandler(processingEnvironment));
102116
add(new InstanceStateHandler(processingEnvironment));
103117
add(new HttpsClientHandler(processingEnvironment));
104118
add(new OnActivityResultHandler(processingEnvironment));
@@ -115,14 +129,19 @@ public AnnotationHandlers(ProcessingEnvironment processingEnvironment) {
115129
if (optionsHelper.shouldLogTrace()) {
116130
add(new TraceHandler(processingEnvironment));
117131
}
118-
/* UIThreadHandler and BackgroundHandler must be after TraceHandler and IgnoredWhenDetached */
132+
/*
133+
* UIThreadHandler and BackgroundHandler must be after TraceHandler and
134+
* IgnoredWhenDetached
135+
*/
119136
add(new UiThreadHandler(processingEnvironment));
120137
add(new BackgroundHandler(processingEnvironment));
121138

122-
/* SupposeUiThreadHandler and SupposeBackgroundHandler must be
123-
after all handlers that modifies generated method body */
124-
add(new SupposeUiThreadHandler(processingEnvironment));
125-
add(new SupposeBackgroundHandler(processingEnvironment));
139+
/*
140+
* SupposeUiThreadHandler and SupposeBackgroundHandler must be after all
141+
* handlers that modifies generated method body
142+
*/
143+
add(new SupposeUiThreadHandler(processingEnvironment));
144+
add(new SupposeBackgroundHandler(processingEnvironment));
126145
}
127146

128147
private void add(AnnotationHandler<? extends GeneratedClassHolder> annotationHandler) {
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* Copyright (C) 2010-2014 eBusiness Information, Excilys Group
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed To in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
package org.androidannotations.handler;
17+
18+
import javax.annotation.processing.ProcessingEnvironment;
19+
import javax.lang.model.element.Element;
20+
import javax.lang.model.element.ExecutableElement;
21+
22+
import org.androidannotations.helper.APTCodeModelHelper;
23+
import org.androidannotations.helper.CanonicalNameConstants;
24+
import org.androidannotations.helper.TargetAnnotationHelper;
25+
import org.androidannotations.holder.EComponentHolder;
26+
import org.androidannotations.model.AnnotationElements;
27+
import org.androidannotations.process.IsValid;
28+
29+
public class ProduceHandler extends BaseAnnotationHandler<EComponentHolder> {
30+
31+
private final TargetAnnotationHelper annotationHelper;
32+
private final APTCodeModelHelper codeModelHelper = new APTCodeModelHelper();
33+
34+
public ProduceHandler(ProcessingEnvironment processingEnvironment) {
35+
super(CanonicalNameConstants.PRODUCE, processingEnvironment);
36+
annotationHelper = new TargetAnnotationHelper(processingEnv, getTarget());
37+
}
38+
39+
@Override
40+
public void validate(Element element, AnnotationElements validatedElements, IsValid valid) {
41+
if (!annotationHelper.enclosingElementHasEnhancedComponentAnnotation(element)) {
42+
valid.invalidate();
43+
return;
44+
}
45+
46+
ExecutableElement executableElement = (ExecutableElement) element;
47+
48+
/*
49+
* We check that twice to skip invalid annotated elements
50+
*/
51+
validatorHelper.enclosingElementHasEnhancedComponentAnnotation(executableElement, validatedElements, valid);
52+
53+
validatorHelper.returnTypeIsNotVoid(executableElement, valid);
54+
55+
validatorHelper.isPublic(element, valid);
56+
57+
validatorHelper.doesntThrowException(executableElement, valid);
58+
59+
validatorHelper.isNotFinal(element, valid);
60+
61+
validatorHelper.param.zeroParameter(executableElement, valid);
62+
}
63+
64+
@Override
65+
public void process(Element element, EComponentHolder holder) throws Exception {
66+
ExecutableElement executableElement = (ExecutableElement) element;
67+
68+
codeModelHelper.overrideAnnotatedMethod(executableElement, holder);
69+
}
70+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* Copyright (C) 2010-2014 eBusiness Information, Excilys Group
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed To in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
package org.androidannotations.handler;
17+
18+
import javax.annotation.processing.ProcessingEnvironment;
19+
import javax.lang.model.element.Element;
20+
import javax.lang.model.element.ExecutableElement;
21+
22+
import org.androidannotations.helper.APTCodeModelHelper;
23+
import org.androidannotations.helper.CanonicalNameConstants;
24+
import org.androidannotations.helper.TargetAnnotationHelper;
25+
import org.androidannotations.holder.EComponentHolder;
26+
import org.androidannotations.model.AnnotationElements;
27+
import org.androidannotations.process.IsValid;
28+
29+
public class SubscribeHandler extends BaseAnnotationHandler<EComponentHolder> {
30+
31+
private final TargetAnnotationHelper annotationHelper;
32+
private final APTCodeModelHelper codeModelHelper = new APTCodeModelHelper();
33+
34+
public SubscribeHandler(ProcessingEnvironment processingEnvironment) {
35+
super(CanonicalNameConstants.SUBSCRIBE, processingEnvironment);
36+
annotationHelper = new TargetAnnotationHelper(processingEnv, getTarget());
37+
}
38+
39+
@Override
40+
public void validate(Element element, AnnotationElements validatedElements, IsValid valid) {
41+
if (!annotationHelper.enclosingElementHasEnhancedComponentAnnotation(element)) {
42+
valid.invalidate();
43+
return;
44+
}
45+
46+
ExecutableElement executableElement = (ExecutableElement) element;
47+
48+
/*
49+
* We check that twice to skip invalid annotated elements
50+
*/
51+
validatorHelper.enclosingElementHasEnhancedComponentAnnotation(executableElement, validatedElements, valid);
52+
53+
validatorHelper.returnTypeIsVoid(executableElement, valid);
54+
55+
validatorHelper.isPublic(element, valid);
56+
57+
validatorHelper.doesntThrowException(executableElement, valid);
58+
59+
validatorHelper.isNotFinal(element, valid);
60+
61+
validatorHelper.param.hasExactlyOneParameter(executableElement, valid);
62+
}
63+
64+
@Override
65+
public void process(Element element, EComponentHolder holder) throws Exception {
66+
ExecutableElement executableElement = (ExecutableElement) element;
67+
68+
codeModelHelper.overrideAnnotatedMethod(executableElement, holder);
69+
}
70+
}

‎AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/AnnotationHelper.java‎

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
*/
1616
package org.androidannotations.helper;
1717

18+
import static org.androidannotations.helper.ModelConstants.GENERATION_SUFFIX;
19+
import static org.androidannotations.helper.ModelConstants.VALID_ENHANCED_COMPONENT_ANNOTATIONS;
20+
1821
import java.lang.annotation.Annotation;
1922
import java.lang.reflect.InvocationTargetException;
2023
import java.lang.reflect.Method;
@@ -48,8 +51,6 @@
4851

4952
import com.sun.codemodel.JFieldRef;
5053

51-
import static org.androidannotations.helper.ModelConstants.GENERATION_SUFFIX;
52-
5354
public class AnnotationHelper {
5455

5556
public static final String DEFAULT_FIELD_NAME_VALUE = "value";
@@ -91,9 +92,9 @@ public String generatedClassQualifiedNameFromQualifiedName(String qualifiedName)
9192
TypeElement type = typeElementFromQualifiedName(qualifiedName);
9293
if (type.getNestingKind() == NestingKind.MEMBER) {
9394
String parentGeneratedClass = generatedClassQualifiedNameFromQualifiedName(type.getEnclosingElement().asType().toString());
94-
return parentGeneratedClass+"."+type.getSimpleName().toString()+GENERATION_SUFFIX;
95+
return parentGeneratedClass + "." + type.getSimpleName().toString() + GENERATION_SUFFIX;
9596
} else {
96-
return qualifiedName+GENERATION_SUFFIX;
97+
return qualifiedName + GENERATION_SUFFIX;
9798
}
9899
}
99100

@@ -173,7 +174,7 @@ public Types getTypeUtils() {
173174
/**
174175
* Returns a list of {@link JFieldRef} linking to the R class, based on the
175176
* given annotation
176-
*
177+
*
177178
* @see #extractAnnotationResources(Element, String, IRInnerClass, boolean)
178179
*/
179180
public List<JFieldRef> extractAnnotationFieldRefs(ProcessHolder holder, Element element, String annotationName, IRInnerClass rInnerClass, boolean useElementName) {
@@ -195,7 +196,7 @@ public List<JFieldRef> extractAnnotationFieldRefs(ProcessHolder holder, Element
195196
* set using the value() parameter of the annotation (as int or int[]), the
196197
* resName() parameter of the annotation (as String or String[]), the
197198
* element name.
198-
*
199+
*
199200
* @param element
200201
* the annotated element
201202
* @param annotationName
@@ -427,6 +428,11 @@ public boolean hasOneOfClassAnnotations(Element element, Class<? extends Annotat
427428
return hasOneOfClassAnnotations(element, annotations);
428429
}
429430

431+
public boolean enclosingElementHasEnhancedComponentAnnotation(Element element) {
432+
Element enclosingElement = element.getEnclosingElement();
433+
return hasOneOfClassAnnotations(enclosingElement, VALID_ENHANCED_COMPONENT_ANNOTATIONS);
434+
}
435+
430436
public boolean hasOneOfClassAnnotations(Element element, List<Class<? extends Annotation>> validAnnotations) {
431437
for (Class<? extends Annotation> validAnnotation : validAnnotations) {
432438
if (element.getAnnotation(validAnnotation) != null) {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.androidannotations.test15.otto;
2+
3+
import static org.fest.assertions.Assertions.assertThat;
4+
5+
import org.junit.Test;
6+
import org.junit.runner.RunWith;
7+
import org.robolectric.Robolectric;
8+
import org.robolectric.RobolectricTestRunner;
9+
10+
@RunWith(RobolectricTestRunner.class)
11+
public class OttoActivityTest {
12+
13+
@Test
14+
public void testOttoMethodsCalled() {
15+
OttoActivity activity = Robolectric.setupActivity(OttoActivity_.class);
16+
17+
assertThat(activity.lastEvent).isNotNull();
18+
}
19+
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Copyright (C) 2010-2014 eBusiness Information, Excilys Group
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed To in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
package org.androidannotations.test15.otto;
17+
18+
public class Event {
19+
20+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.androidannotations.test15.otto;
2+
3+
import org.androidannotations.annotations.EActivity;
4+
5+
import android.app.Activity;
6+
import android.os.Bundle;
7+
8+
import com.squareup.otto.Bus;
9+
import com.squareup.otto.Produce;
10+
import com.squareup.otto.Subscribe;
11+
12+
@EActivity
13+
public class OttoActivity extends Activity {
14+
15+
Event lastEvent;
16+
17+
@Override
18+
protected void onCreate(Bundle savedInstanceState) {
19+
super.onCreate(savedInstanceState);
20+
21+
Bus bus = new Bus();
22+
bus.register(this);
23+
}
24+
25+
@Subscribe
26+
public void onEvent(Event event) {
27+
lastEvent = event;
28+
}
29+
30+
@Produce
31+
public Event produceEvent() {
32+
return new Event();
33+
}
34+
}

0 commit comments

Comments
 (0)