Skip to content

Commit 6db5485

Browse files
committed
Done with implementing shared prefs and corresponding tests. Fixes issue 47.
1 parent 4c6a63b commit 6db5485

17 files changed

Lines changed: 494 additions & 100 deletions

File tree

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
import com.googlecode.androidannotations.annotations.rest.Post;
7171
import com.googlecode.androidannotations.annotations.rest.Put;
7272
import com.googlecode.androidannotations.annotations.rest.Rest;
73+
import com.googlecode.androidannotations.annotations.sharedpreferences.Pref;
7374
import com.googlecode.androidannotations.annotations.sharedpreferences.SharedPref;
7475
import com.googlecode.androidannotations.generation.CodeModelGenerator;
7576
import com.googlecode.androidannotations.helper.AndroidManifest;
@@ -91,6 +92,7 @@
9192
import com.googlecode.androidannotations.processing.ItemSelectedProcessor;
9293
import com.googlecode.androidannotations.processing.LongClickProcessor;
9394
import com.googlecode.androidannotations.processing.ModelProcessor;
95+
import com.googlecode.androidannotations.processing.PrefProcessor;
9496
import com.googlecode.androidannotations.processing.ResProcessor;
9597
import com.googlecode.androidannotations.processing.RoboGuiceProcessor;
9698
import com.googlecode.androidannotations.processing.SharedPrefProcessor;
@@ -117,6 +119,7 @@
117119
import com.googlecode.androidannotations.validation.ItemSelectedValidator;
118120
import com.googlecode.androidannotations.validation.LongClickValidator;
119121
import com.googlecode.androidannotations.validation.ModelValidator;
122+
import com.googlecode.androidannotations.validation.PrefValidator;
120123
import com.googlecode.androidannotations.validation.ResValidator;
121124
import com.googlecode.androidannotations.validation.RoboGuiceValidator;
122125
import com.googlecode.androidannotations.validation.RunnableValidator;
@@ -152,6 +155,7 @@
152155
Extra.class, //
153156
SystemService.class, //
154157
SharedPref.class, //
158+
Pref.class, //
155159
StringRes.class, //
156160
ColorRes.class, //
157161
AnimationRes.class, //
@@ -277,6 +281,7 @@ private ModelValidator buildModelValidator(IRClass rClass, AndroidSystemServices
277281
modelValidator.register(new SystemServiceValidator(processingEnv, androidSystemServices));
278282
modelValidator.register(new BeforeCreateValidator(processingEnv));
279283
modelValidator.register(new SharedPrefValidator(processingEnv));
284+
modelValidator.register(new PrefValidator(processingEnv));
280285
modelValidator.register(new RestValidator(processingEnv));
281286
modelValidator.register(new DeleteValidator(processingEnv));
282287
modelValidator.register(new GetValidator(processingEnv));
@@ -295,8 +300,9 @@ private JCodeModel processAnnotations(AnnotationElements validatedModel, IRClass
295300

296301
private ModelProcessor buildModelProcessor(IRClass rClass, AndroidSystemServices androidSystemServices, AndroidManifest androidManifest) {
297302
ModelProcessor modelProcessor = new ModelProcessor();
298-
modelProcessor.register(new SharedPrefProcessor(processingEnv));
299303
modelProcessor.register(new EActivityProcessor(processingEnv, rClass));
304+
modelProcessor.register(new SharedPrefProcessor(processingEnv));
305+
modelProcessor.register(new PrefProcessor());
300306
modelProcessor.register(new RoboGuiceProcessor());
301307
modelProcessor.register(new ViewByIdProcessor(rClass));
302308
modelProcessor.register(new ClickProcessor(rClass));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2010-2011 Pierre-Yves Ricau (py.ricau at gmail.com)
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.sharedpreferences;
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 com.googlecode.androidannotations.api.sharedpreferences.SharedPreferencesHelper;
24+
25+
/**
26+
* Injects a {@link SharedPref}
27+
*
28+
* The field MUST be of a type that is generated using {@link SharedPref} and therefore extends {@link SharedPreferencesHelper}.
29+
*
30+
*/
31+
@Retention(RetentionPolicy.SOURCE)
32+
@Target(ElementType.FIELD)
33+
public @interface Pref {
34+
}

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

Lines changed: 95 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -30,96 +30,100 @@
3030

3131
public class AnnotationHelper {
3232

33-
protected final ProcessingEnvironment processingEnv;
34-
35-
public AnnotationHelper(ProcessingEnvironment processingEnv) {
36-
this.processingEnv = processingEnv;
37-
}
38-
39-
/**
40-
* Tests whether one type is a subtype of another. Any type is considered to
41-
* be a subtype of itself.
42-
*
43-
* @param t1
44-
* the first type
45-
* @param t2
46-
* the second type
47-
* @return true if and only if the first type is a subtype of the second
48-
* @throws IllegalArgumentException
49-
* if given an executable or package type
50-
* @see Types#isSubtype(TypeMirror, TypeMirror)
51-
*/
52-
public boolean isSubtype(TypeMirror t1, TypeMirror t2) {
53-
return processingEnv.getTypeUtils().isSubtype(t1, t2);
54-
}
55-
56-
public boolean isSubtype(TypeElement t1, TypeElement t2) {
57-
return isSubtype(t1.asType(), t2.asType());
58-
}
59-
60-
public TypeElement typeElementFromQualifiedName(String qualifiedName) {
61-
return processingEnv.getElementUtils().getTypeElement(qualifiedName);
62-
}
63-
64-
public AnnotationMirror findAnnotationMirror(Element annotatedElement, Class<? extends Annotation> annotationClass) {
65-
List<? extends AnnotationMirror> annotationMirrors = annotatedElement.getAnnotationMirrors();
66-
67-
for (AnnotationMirror annotationMirror : annotationMirrors) {
68-
TypeElement annotationElement = (TypeElement) annotationMirror.getAnnotationType().asElement();
69-
if (isAnnotation(annotationElement, annotationClass)) {
70-
return annotationMirror;
71-
}
72-
}
73-
return null;
74-
}
75-
76-
public boolean isAnnotation(TypeElement annotation, Class<? extends Annotation> annotationClass) {
77-
return annotation.getQualifiedName().toString().equals(annotationClass.getName());
78-
}
79-
80-
public void printAnnotationError(Element annotatedElement, Class<? extends Annotation> annotationClass, String message) {
81-
printAnnotationMessage(Diagnostic.Kind.ERROR, annotatedElement, annotationClass, message);
82-
}
83-
84-
public void printAnnotationWarning(Element annotatedElement, Class<? extends Annotation> annotationClass, String message) {
85-
printAnnotationMessage(Diagnostic.Kind.WARNING, annotatedElement, annotationClass, message);
86-
}
87-
88-
public void printAnnotationMessage(Diagnostic.Kind diagnosticKind, Element annotatedElement, Class<? extends Annotation> annotationClass, String message) {
89-
AnnotationMirror annotationMirror = findAnnotationMirror(annotatedElement, annotationClass);
90-
if (annotationMirror != null) {
91-
processingEnv.getMessager().printMessage(diagnosticKind, message, annotatedElement, annotationMirror);
92-
} else {
93-
printError(annotatedElement, message);
94-
}
95-
}
96-
97-
public void printError(Element element, String message) {
98-
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, element);
99-
}
100-
101-
public boolean isPrivate(Element element) {
102-
return element.getModifiers().contains(Modifier.PRIVATE);
103-
}
104-
105-
public boolean isAbstract(Element element) {
106-
return element.getModifiers().contains(Modifier.ABSTRACT);
107-
}
108-
109-
public boolean isInterface(TypeElement element) {
110-
return element.getKind().isInterface();
111-
}
112-
113-
public boolean isFinal(Element element) {
114-
return element.getModifiers().contains(Modifier.FINAL);
115-
}
116-
117-
public boolean isSynchronized(Element element) {
118-
return element.getModifiers().contains(Modifier.SYNCHRONIZED);
119-
}
120-
121-
public Elements getElementUtils() {
122-
return processingEnv.getElementUtils();
123-
}
33+
protected final ProcessingEnvironment processingEnv;
34+
35+
public AnnotationHelper(ProcessingEnvironment processingEnv) {
36+
this.processingEnv = processingEnv;
37+
}
38+
39+
/**
40+
* Tests whether one type is a subtype of another. Any type is considered to
41+
* be a subtype of itself.
42+
*
43+
* @param t1
44+
* the first type
45+
* @param t2
46+
* the second type
47+
* @return true if and only if the first type is a subtype of the second
48+
* @throws IllegalArgumentException
49+
* if given an executable or package type
50+
* @see Types#isSubtype(TypeMirror, TypeMirror)
51+
*/
52+
public boolean isSubtype(TypeMirror t1, TypeMirror t2) {
53+
return processingEnv.getTypeUtils().isSubtype(t1, t2);
54+
}
55+
56+
public boolean isSubtype(TypeElement t1, TypeElement t2) {
57+
return isSubtype(t1.asType(), t2.asType());
58+
}
59+
60+
public TypeElement typeElementFromQualifiedName(String qualifiedName) {
61+
return processingEnv.getElementUtils().getTypeElement(qualifiedName);
62+
}
63+
64+
public AnnotationMirror findAnnotationMirror(Element annotatedElement, Class<? extends Annotation> annotationClass) {
65+
List<? extends AnnotationMirror> annotationMirrors = annotatedElement.getAnnotationMirrors();
66+
67+
for (AnnotationMirror annotationMirror : annotationMirrors) {
68+
TypeElement annotationElement = (TypeElement) annotationMirror.getAnnotationType().asElement();
69+
if (isAnnotation(annotationElement, annotationClass)) {
70+
return annotationMirror;
71+
}
72+
}
73+
return null;
74+
}
75+
76+
public boolean isAnnotation(TypeElement annotation, Class<? extends Annotation> annotationClass) {
77+
return annotation.getQualifiedName().toString().equals(annotationClass.getName());
78+
}
79+
80+
public void printAnnotationError(Element annotatedElement, Class<? extends Annotation> annotationClass, String message) {
81+
printAnnotationMessage(Diagnostic.Kind.ERROR, annotatedElement, annotationClass, message);
82+
}
83+
84+
public void printAnnotationWarning(Element annotatedElement, Class<? extends Annotation> annotationClass, String message) {
85+
printAnnotationMessage(Diagnostic.Kind.WARNING, annotatedElement, annotationClass, message);
86+
}
87+
88+
public void printAnnotationMessage(Diagnostic.Kind diagnosticKind, Element annotatedElement, Class<? extends Annotation> annotationClass, String message) {
89+
AnnotationMirror annotationMirror = findAnnotationMirror(annotatedElement, annotationClass);
90+
if (annotationMirror != null) {
91+
processingEnv.getMessager().printMessage(diagnosticKind, message, annotatedElement, annotationMirror);
92+
} else {
93+
printError(annotatedElement, message);
94+
}
95+
}
96+
97+
public void printError(Element element, String message) {
98+
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, element);
99+
}
100+
101+
public boolean isPrivate(Element element) {
102+
return element.getModifiers().contains(Modifier.PRIVATE);
103+
}
104+
105+
public boolean isAbstract(Element element) {
106+
return element.getModifiers().contains(Modifier.ABSTRACT);
107+
}
108+
109+
public boolean isInterface(TypeElement element) {
110+
return element.getKind().isInterface();
111+
}
112+
113+
public boolean isFinal(Element element) {
114+
return element.getModifiers().contains(Modifier.FINAL);
115+
}
116+
117+
public boolean isSynchronized(Element element) {
118+
return element.getModifiers().contains(Modifier.SYNCHRONIZED);
119+
}
120+
121+
public Elements getElementUtils() {
122+
return processingEnv.getElementUtils();
123+
}
124+
125+
public Types getTypeUtils() {
126+
return processingEnv.getTypeUtils();
127+
}
124128

125129
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,18 @@ public void zeroOrOneSpecificParameter(ExecutableElement executableElement, Stri
339339
valid.invalidate();
340340
annotationHelper.printAnnotationError(executableElement, "%s can only be used on a method with no parameter or a parameter of type " + parameterTypeQualifiedName + ", not " + parameterType);
341341
}
342+
// Tests for StackOverflow question.
343+
// Types typeUtils = annotationHelper.getTypeUtils();
344+
// TypeElement typeElement = (TypeElement) typeUtils.asElement(parameterType);
345+
// Elements elementUtils = annotationHelper.getElementUtils();
346+
// List<? extends Element> elementMembers = elementUtils.getAllMembers(typeElement);
347+
// List<ExecutableElement> elementMethods = ElementFilter.methodsIn(elementMembers);
348+
// for(ExecutableElement methodElement : elementMethods) {
349+
// if (methodElement.getParameters().size()==0 && methodElement.getSimpleName().toString().startsWith("get")) {
350+
// annotationHelper.printAnnotationWarning(executableElement, "Method name: "+methodElement.getSimpleName());
351+
// }
352+
// }
353+
342354
}
343355
}
344356

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2010-2011 Pierre-Yves Ricau (py.ricau at gmail.com)
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.processing;
17+
18+
import java.lang.annotation.Annotation;
19+
20+
import javax.lang.model.element.Element;
21+
import javax.lang.model.type.TypeMirror;
22+
23+
import com.googlecode.androidannotations.annotations.sharedpreferences.Pref;
24+
import com.sun.codemodel.JBlock;
25+
import com.sun.codemodel.JCodeModel;
26+
import com.sun.codemodel.JExpr;
27+
import com.sun.codemodel.JFieldRef;
28+
29+
public class PrefProcessor implements ElementProcessor {
30+
31+
@Override
32+
public Class<? extends Annotation> getTarget() {
33+
return Pref.class;
34+
}
35+
36+
37+
@Override
38+
public void process(Element element, JCodeModel codeModel, ActivitiesHolder activitiesHolder) {
39+
ActivityHolder holder = activitiesHolder.getEnclosingActivityHolder(element);
40+
41+
String fieldName = element.getSimpleName().toString();
42+
43+
TypeMirror fieldTypeMirror = element.asType();
44+
String fieldType = fieldTypeMirror.toString();
45+
46+
JBlock methodBody = holder.beforeSetContentView.body();
47+
48+
JFieldRef field = JExpr.ref(fieldName);
49+
50+
methodBody.assign(field, JExpr._new(holder.refClass(fieldType)).arg(JExpr._this()));
51+
}
52+
53+
}

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

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,11 @@ public void process(Element element, JCodeModel codeModel, ActivitiesHolder acti
103103
helperClass._extends(SharedPreferencesHelper.class);
104104

105105
// Extracting valid methods
106-
Elements elements = processingEnv.getElementUtils();
107-
List<? extends Element> inheritedMembers = elements.getAllMembers(typeElement);
108-
List<ExecutableElement> inheritedMethods = ElementFilter.methodsIn(inheritedMembers);
106+
List<? extends Element> members = typeElement.getEnclosedElements();
107+
List<ExecutableElement> methods = ElementFilter.methodsIn(members);
109108
List<ExecutableElement> validMethods = new ArrayList<ExecutableElement>();
110-
for (ExecutableElement method : inheritedMethods) {
111-
if (!method.getEnclosingElement().asType().toString().equals("java.lang.Object")) {
112-
validMethods.add(method);
113-
}
109+
for (ExecutableElement method : methods) {
110+
validMethods.add(method);
114111
}
115112

116113
// Static editor class

0 commit comments

Comments
 (0)