Skip to content

Commit 2e3d8f3

Browse files
committed
Merge branch 'i87_TraceLog' into develop. Fixes issue 87.
Conflicts: AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/AndroidAnnotationProcessor.java
2 parents e9d2ded + fe9a8b5 commit 2e3d8f3

12 files changed

Lines changed: 594 additions & 53 deletions

File tree

‎AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/AndroidAnnotationProcessor.java‎

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.io.IOException;
1919
import java.io.PrintWriter;
2020
import java.io.StringWriter;
21+
import java.util.Map;
2122
import java.util.Set;
2223

2324
import javax.annotation.processing.Messager;
@@ -51,6 +52,7 @@
5152
import com.googlecode.androidannotations.annotations.RoboGuice;
5253
import com.googlecode.androidannotations.annotations.SystemService;
5354
import com.googlecode.androidannotations.annotations.Touch;
55+
import com.googlecode.androidannotations.annotations.Trace;
5456
import com.googlecode.androidannotations.annotations.Transactional;
5557
import com.googlecode.androidannotations.annotations.UiThread;
5658
import com.googlecode.androidannotations.annotations.UiThreadDelayed;
@@ -118,6 +120,7 @@
118120
import com.googlecode.androidannotations.processing.SharedPrefProcessor;
119121
import com.googlecode.androidannotations.processing.SystemServiceProcessor;
120122
import com.googlecode.androidannotations.processing.TouchProcessor;
123+
import com.googlecode.androidannotations.processing.TraceProcessor;
121124
import com.googlecode.androidannotations.processing.TransactionalProcessor;
122125
import com.googlecode.androidannotations.processing.UiThreadDelayedProcessor;
123126
import com.googlecode.androidannotations.processing.UiThreadProcessor;
@@ -159,6 +162,7 @@
159162
import com.googlecode.androidannotations.validation.SharedPrefValidator;
160163
import com.googlecode.androidannotations.validation.SystemServiceValidator;
161164
import com.googlecode.androidannotations.validation.TouchValidator;
165+
import com.googlecode.androidannotations.validation.TraceValidator;
162166
import com.googlecode.androidannotations.validation.TransactionalValidator;
163167
import com.googlecode.androidannotations.validation.ViewByIdValidator;
164168
import com.googlecode.androidannotations.validation.rest.AcceptValidator;
@@ -222,7 +226,8 @@
222226
HtmlRes.class, //
223227
NoTitle.class, //
224228
Fullscreen.class, //
225-
RestService.class //
229+
RestService.class, //
230+
Trace.class //
226231
})
227232
@SupportedSourceVersion(SourceVersion.RELEASE_6)
228233
public class AndroidAnnotationProcessor extends AnnotatedAbstractProcessor {
@@ -348,9 +353,6 @@ private ModelValidator buildModelValidator(IRClass rClass, AndroidSystemServices
348353
for (AndroidRes androidRes : AndroidRes.values()) {
349354
modelValidator.register(new ResValidator(androidRes, processingEnv, rClass));
350355
}
351-
modelValidator.register(new RunnableValidator(UiThreadDelayed.class, processingEnv));
352-
modelValidator.register(new RunnableValidator(UiThread.class, processingEnv));
353-
modelValidator.register(new RunnableValidator(Background.class, processingEnv));
354356
modelValidator.register(new TransactionalValidator(processingEnv));
355357
modelValidator.register(new ExtraValidator(processingEnv));
356358
modelValidator.register(new SystemServiceValidator(processingEnv, androidSystemServices));
@@ -372,9 +374,25 @@ private ModelValidator buildModelValidator(IRClass rClass, AndroidSystemServices
372374
modelValidator.register(new NoTitleValidator(processingEnv));
373375
modelValidator.register(new FullscreenValidator(processingEnv));
374376
modelValidator.register(new RestServiceValidator(processingEnv));
377+
modelValidator.register(new RunnableValidator(UiThreadDelayed.class, processingEnv));
378+
modelValidator.register(new RunnableValidator(UiThread.class, processingEnv));
379+
modelValidator.register(new RunnableValidator(Background.class, processingEnv));
380+
if (traceActivated()) {
381+
modelValidator.register(new TraceValidator(processingEnv));
382+
}
375383
return modelValidator;
376384
}
377385

386+
private boolean traceActivated() {
387+
Map<String, String> options = processingEnv.getOptions();
388+
if (options.containsKey("trace")) {
389+
String trace = options.get("trace");
390+
return !"false".equals(trace);
391+
} else {
392+
return true;
393+
}
394+
}
395+
378396
private JCodeModel processAnnotations(AnnotationElements validatedModel, IRClass rClass, AndroidSystemServices androidSystemServices, AndroidManifest androidManifest) {
379397
timeStats.start("Process Annotations");
380398
ModelProcessor modelProcessor = buildModelProcessor(rClass, androidSystemServices, androidManifest);
@@ -401,9 +419,6 @@ private ModelProcessor buildModelProcessor(IRClass rClass, AndroidSystemServices
401419
for (AndroidRes androidRes : AndroidRes.values()) {
402420
modelProcessor.register(new ResProcessor(androidRes, rClass));
403421
}
404-
modelProcessor.register(new UiThreadProcessor());
405-
modelProcessor.register(new UiThreadDelayedProcessor());
406-
modelProcessor.register(new BackgroundProcessor());
407422
modelProcessor.register(new TransactionalProcessor());
408423
modelProcessor.register(new ExtraProcessor());
409424
modelProcessor.register(new SystemServiceProcessor(androidSystemServices));
@@ -423,6 +438,10 @@ private ModelProcessor buildModelProcessor(IRClass rClass, AndroidSystemServices
423438
modelProcessor.register(new NoTitleProcessor());
424439
modelProcessor.register(new FullscreenProcessor());
425440
modelProcessor.register(new RestServiceProcessor());
441+
modelProcessor.register(new TraceProcessor());
442+
modelProcessor.register(new UiThreadProcessor());
443+
modelProcessor.register(new UiThreadDelayedProcessor());
444+
modelProcessor.register(new BackgroundProcessor());
426445
return modelProcessor;
427446
}
428447

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* Copyright (C) 2010-2011 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 com.googlecode.androidannotations.annotations;
17+
18+
import java.lang.annotation.ElementType;
19+
import java.lang.annotation.Retention;
20+
import java.lang.annotation.RetentionPolicy;
21+
import java.lang.annotation.Target;
22+
23+
import android.util.Log;
24+
25+
/**
26+
* Use this annotation to log at runtime the execution time of the targeted
27+
* method.
28+
*
29+
* <i>tag</i> (optional) : the tag used for the log message. (default: enclosing
30+
* class name)
31+
*
32+
* <i>level</i> (optional) : the log level used for the log message. (default :
33+
* LOG.INFO).
34+
*
35+
* @author Mathieu Boniface
36+
*/
37+
@Retention(RetentionPolicy.SOURCE)
38+
@Target(ElementType.METHOD)
39+
public @interface Trace {
40+
41+
public static final String DEFAULT_TAG = "NO_TAG";
42+
43+
String tag() default DEFAULT_TAG;
44+
45+
int level() default Log.INFO;
46+
47+
}

‎AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/helper/APTCodeModelHelper.java‎

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,27 @@
1515
*/
1616
package com.googlecode.androidannotations.helper;
1717

18+
import java.lang.reflect.Field;
1819
import java.util.ArrayList;
1920
import java.util.List;
2021

22+
import javax.lang.model.element.ExecutableElement;
23+
import javax.lang.model.element.VariableElement;
2124
import javax.lang.model.type.DeclaredType;
2225
import javax.lang.model.type.TypeMirror;
2326

2427
import com.googlecode.androidannotations.processing.EBeanHolder;
28+
import com.sun.codemodel.JBlock;
2529
import com.sun.codemodel.JClass;
30+
import com.sun.codemodel.JDefinedClass;
31+
import com.sun.codemodel.JExpr;
32+
import com.sun.codemodel.JExpression;
33+
import com.sun.codemodel.JInvocation;
34+
import com.sun.codemodel.JMethod;
35+
import com.sun.codemodel.JMod;
36+
import com.sun.codemodel.JStatement;
37+
import com.sun.codemodel.JType;
38+
import com.sun.codemodel.JVar;
2639

2740
public class APTCodeModelHelper {
2841

@@ -51,4 +64,106 @@ public JClass typeMirrorToJClass(TypeMirror type, EBeanHolder holder) {
5164
}
5265
}
5366

67+
public static class Parameter {
68+
public final String name;
69+
public final JClass jClass;
70+
71+
public Parameter(String name, JClass jClass) {
72+
this.name = name;
73+
this.jClass = jClass;
74+
}
75+
}
76+
77+
public JMethod overrideAnnotatedMethod(ExecutableElement executableElement, EBeanHolder holder) {
78+
79+
String methodName = executableElement.getSimpleName().toString();
80+
81+
JClass returnType = typeMirrorToJClass(executableElement.getReturnType(), holder);
82+
83+
List<Parameter> parameters = new ArrayList<Parameter>();
84+
for (VariableElement parameter : executableElement.getParameters()) {
85+
String parameterName = parameter.getSimpleName().toString();
86+
JClass parameterClass = typeMirrorToJClass(parameter.asType(), holder);
87+
parameters.add(new Parameter(parameterName, parameterClass));
88+
}
89+
90+
JMethod existingMethod = findAlreadyGeneratedMethod(holder.eBean, methodName, parameters);
91+
92+
if (existingMethod != null) {
93+
return existingMethod;
94+
}
95+
96+
JMethod method = holder.eBean.method(JMod.PUBLIC, returnType, methodName);
97+
method.annotate(Override.class);
98+
99+
List<JVar> methodParameters = new ArrayList<JVar>();
100+
for (VariableElement parameter : executableElement.getParameters()) {
101+
String parameterName = parameter.getSimpleName().toString();
102+
JClass parameterClass = typeMirrorToJClass(parameter.asType(), holder);
103+
JVar param = method.param(JMod.FINAL, parameterClass, parameterName);
104+
methodParameters.add(param);
105+
}
106+
107+
for (TypeMirror superThrownType : executableElement.getThrownTypes()) {
108+
JClass thrownType = typeMirrorToJClass(superThrownType, holder);
109+
method._throws(thrownType);
110+
}
111+
112+
callSuperMethod(method, holder, method.body());
113+
114+
return method;
115+
}
116+
117+
private JMethod findAlreadyGeneratedMethod(JDefinedClass definedClass, String methodName, List<Parameter> parameters) {
118+
method: for (JMethod method : definedClass.methods()) {
119+
if (method.name().equals(methodName) && method.params().size() == parameters.size()) {
120+
int i = 0;
121+
for (JVar param : method.params()) {
122+
String searchedParamType = parameters.get(i).jClass.name();
123+
if (!param.type().name().equals(searchedParamType)) {
124+
continue method;
125+
}
126+
i++;
127+
}
128+
return method;
129+
}
130+
}
131+
return null;
132+
}
133+
134+
public void callSuperMethod(JMethod superMethod, EBeanHolder holder, JBlock callBlock) {
135+
JExpression activitySuper = holder.eBean.staticRef("super");
136+
JInvocation superCall = JExpr.invoke(activitySuper, superMethod);
137+
138+
for (JVar param : superMethod.params()) {
139+
superCall.arg(param);
140+
}
141+
142+
JType returnType = superMethod.type();
143+
if (returnType.fullName().equals("void")) {
144+
callBlock.add(superCall);
145+
} else {
146+
callBlock._return(superCall);
147+
}
148+
}
149+
150+
public JBlock removeBody(JMethod method) {
151+
JBlock body = method.body();
152+
try {
153+
Field bodyField = JMethod.class.getDeclaredField("body");
154+
bodyField.setAccessible(true);
155+
bodyField.set(method, null);
156+
} catch (Exception e) {
157+
throw new RuntimeException(e);
158+
}
159+
160+
JBlock clonedBody = new JBlock(false, false);
161+
162+
for(Object statement : body.getContents()) {
163+
clonedBody.add((JStatement) statement);
164+
}
165+
166+
return clonedBody;
167+
}
168+
54169
}

‎AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/helper/ValidatorHelper.java‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.lang.annotation.IncompleteAnnotationException;
2222
import java.util.ArrayList;
2323
import java.util.Arrays;
24+
import java.util.Collection;
2425
import java.util.List;
2526
import java.util.Set;
2627

@@ -36,9 +37,12 @@
3637
import javax.lang.model.type.TypeMirror;
3738
import javax.lang.model.util.Elements;
3839

40+
import android.util.Log;
41+
3942
import com.googlecode.androidannotations.annotations.EActivity;
4043
import com.googlecode.androidannotations.annotations.EViewGroup;
4144
import com.googlecode.androidannotations.annotations.Extra;
45+
import com.googlecode.androidannotations.annotations.Trace;
4246
import com.googlecode.androidannotations.annotations.ViewById;
4347
import com.googlecode.androidannotations.annotations.rest.Delete;
4448
import com.googlecode.androidannotations.annotations.rest.Get;
@@ -76,6 +80,8 @@ public class ValidatorHelper {
7680

7781
private static final List<String> INVALID_PREF_METHOD_NAMES = Arrays.asList("edit", "getSharedPreferences", "clear", "getEditor", "apply");
7882

83+
private static final Collection<Integer> VALID_LOG_LEVELS = Arrays.asList(Log.VERBOSE, Log.DEBUG, Log.INFO, Log.WARN, Log.ERROR);
84+
7985
@SuppressWarnings("unchecked")
8086
private static final List<Class<? extends Annotation>> VALID_EBEAN_ANNOTATIONS = Arrays.asList(EActivity.class, EViewGroup.class);
8187

@@ -787,4 +793,16 @@ public void hasOneConstructorWithContextAndAttributSet(Element element, IsValid
787793

788794
}
789795

796+
public void hasValidLogLevel(Element element, IsValid isValid) {
797+
798+
Trace annotation = element.getAnnotation(Trace.class);
799+
Integer level = annotation.level();
800+
801+
if (!VALID_LOG_LEVELS.contains(level)) {
802+
annotationHelper.printError(element, "Unrecognized log level.");
803+
isValid.invalidate();
804+
}
805+
806+
}
807+
790808
}

‎AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/processing/BackgroundProcessor.java‎

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,9 @@
1616
package com.googlecode.androidannotations.processing;
1717

1818
import java.lang.annotation.Annotation;
19-
import java.util.ArrayList;
20-
import java.util.List;
2119

2220
import javax.lang.model.element.Element;
2321
import javax.lang.model.element.ExecutableElement;
24-
import javax.lang.model.element.VariableElement;
2522

2623
import com.googlecode.androidannotations.annotations.Background;
2724
import com.googlecode.androidannotations.api.BackgroundExecutor;
@@ -33,7 +30,6 @@
3330
import com.sun.codemodel.JCodeModel;
3431
import com.sun.codemodel.JDefinedClass;
3532
import com.sun.codemodel.JExpr;
36-
import com.sun.codemodel.JExpression;
3733
import com.sun.codemodel.JInvocation;
3834
import com.sun.codemodel.JMethod;
3935
import com.sun.codemodel.JMod;
@@ -55,19 +51,10 @@ public void process(Element element, JCodeModel codeModel, EBeansHolder activiti
5551
EBeanHolder holder = activitiesHolder.getEnclosingActivityHolder(element);
5652

5753
// Method
58-
String backgroundMethodName = element.getSimpleName().toString();
59-
JMethod backgroundMethod = holder.eBean.method(JMod.PUBLIC, codeModel.VOID, backgroundMethodName);
60-
backgroundMethod.annotate(Override.class);
61-
62-
// Method parameters
63-
List<JVar> parameters = new ArrayList<JVar>();
6454
ExecutableElement executableElement = (ExecutableElement) element;
65-
for (VariableElement parameter : executableElement.getParameters()) {
66-
String parameterName = parameter.getSimpleName().toString();
67-
JClass parameterClass = helper.typeMirrorToJClass(parameter.asType(), holder);
68-
JVar param = backgroundMethod.param(JMod.FINAL, parameterClass, parameterName);
69-
parameters.add(param);
70-
}
55+
JMethod backgroundMethod = helper.overrideAnnotatedMethod(executableElement, holder);
56+
57+
JBlock previousMethodBody = helper.removeBody(backgroundMethod);
7158

7259
JDefinedClass anonymousRunnableClass = codeModel.anonymousClass(Runnable.class);
7360

@@ -76,13 +63,9 @@ public void process(Element element, JCodeModel codeModel, EBeansHolder activiti
7663

7764
JBlock runMethodBody = runMethod.body();
7865
JTryBlock runTry = runMethodBody._try();
66+
67+
runTry.body().add(previousMethodBody);
7968

80-
JExpression activitySuper = holder.eBean.staticRef("super");
81-
82-
JInvocation superCall = runTry.body().invoke(activitySuper, backgroundMethod);
83-
for (JVar param : parameters) {
84-
superCall.arg(param);
85-
}
8669
JCatchBlock runCatch = runTry._catch(holder.refClass(RuntimeException.class));
8770
JVar exceptionParam = runCatch.param("e");
8871

0 commit comments

Comments
 (0)