Skip to content

Commit 0ebd5cb

Browse files
committed
Creating @BeforeCreate annotation
fixes issue 13
1 parent 4d86a10 commit 0ebd5cb

9 files changed

Lines changed: 260 additions & 23 deletions

File tree

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

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import javax.tools.Diagnostic;
2727

2828
import com.googlecode.androidannotations.annotations.Background;
29+
import com.googlecode.androidannotations.annotations.BeforeCreate;
2930
import com.googlecode.androidannotations.annotations.Click;
3031
import com.googlecode.androidannotations.annotations.Extra;
3132
import com.googlecode.androidannotations.annotations.ItemClick;
@@ -65,6 +66,7 @@
6566
import com.googlecode.androidannotations.model.MetaModel;
6667
import com.googlecode.androidannotations.model.ModelExtractor;
6768
import com.googlecode.androidannotations.processing.BackgroundProcessor;
69+
import com.googlecode.androidannotations.processing.BeforeCreateProcessor;
6870
import com.googlecode.androidannotations.processing.ClickProcessor;
6971
import com.googlecode.androidannotations.processing.ExtraProcessor;
7072
import com.googlecode.androidannotations.processing.ItemClickProcessor;
@@ -87,6 +89,7 @@
8789
import com.googlecode.androidannotations.rclass.CoumpoundRClass;
8890
import com.googlecode.androidannotations.rclass.IRClass;
8991
import com.googlecode.androidannotations.rclass.RClassFinder;
92+
import com.googlecode.androidannotations.validation.BeforeCreateValidator;
9093
import com.googlecode.androidannotations.validation.ClickValidator;
9194
import com.googlecode.androidannotations.validation.ExtraValidator;
9295
import com.googlecode.androidannotations.validation.ItemClickValidator;
@@ -104,6 +107,7 @@
104107
import com.googlecode.androidannotations.validation.ViewValidator;
105108

106109
@SupportedAnnotationClasses({ Layout.class, //
110+
BeforeCreate.class, //
107111
RoboGuice.class, //
108112
ViewById.class, //
109113
Click.class, //
@@ -127,7 +131,7 @@
127131
DimensionPixelOffsetRes.class, //
128132
DimensionPixelSizeRes.class, //
129133
DrawableRes.class, //
130-
IntArrayRes.class, // ;
134+
IntArrayRes.class, //
131135
IntegerRes.class, //
132136
LayoutRes.class, //
133137
MovieRes.class, //
@@ -217,6 +221,7 @@ private ModelValidator buildModelValidator(IRClass rClass, AndroidSystemServices
217221
modelValidator.register(new RoboGuiceValidator(processingEnv));
218222
modelValidator.register(new ViewValidator(processingEnv, rClass));
219223
modelValidator.register(new ClickValidator(processingEnv, rClass));
224+
modelValidator.register(new BeforeCreateValidator(processingEnv));
220225
modelValidator.register(new LongClickValidator(processingEnv, rClass));
221226
modelValidator.register(new TouchValidator(processingEnv, rClass));
222227
modelValidator.register(new ItemClickValidator(processingEnv, rClass));
@@ -247,6 +252,7 @@ private ModelProcessor buildModelProcessor(IRClass rClass, AndroidSystemServices
247252
modelProcessor.register(new RoboGuiceProcessor());
248253
modelProcessor.register(new ViewProcessor(rClass));
249254
modelProcessor.register(new ClickProcessor(rClass));
255+
modelProcessor.register(new BeforeCreateProcessor());
250256
modelProcessor.register(new LongClickProcessor(rClass));
251257
modelProcessor.register(new TouchProcessor(rClass));
252258
modelProcessor.register(new ItemClickProcessor(rClass));
@@ -268,25 +274,4 @@ private void generateSources(MetaModel model) throws IOException {
268274
ModelGenerator modelGenerator = new ModelGenerator(processingEnv.getFiler());
269275
modelGenerator.generate(model);
270276
}
271-
272-
/*
273-
* This code should be moved elsewhere. It is kept here as a pastebin code :
274-
* we may want to extract class informations from annotations, which can
275-
* easily be done with the following code.
276-
*/
277-
// private TypeElement extractRClassElement(Element rLocationElement) {
278-
// RClass rLocationAnnotation =
279-
// rLocationElement.getAnnotation(RClass.class);
280-
// try {
281-
// rLocationAnnotation.value();
282-
// } catch (MirroredTypeException mte) {
283-
// DeclaredType typeMirror = (DeclaredType) mte.getTypeMirror();
284-
// return (TypeElement) typeMirror.asElement();
285-
// }
286-
// processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
287-
// "Annotation processing error : could not extract MirrorType from class value",
288-
// rLocationElement);
289-
// throw new IllegalArgumentException();
290-
// }
291-
292277
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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;
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+
/**
24+
* Use on methods that should be called before onCreate() is called. Can be
25+
* useful if you want to execute some code before setContentView() is called or
26+
* before the injection is done.
27+
*
28+
* The method may have zero or one parameter, that MUST be of type
29+
* android.os.Bundle .
30+
*
31+
* There may be several methods annotated with @BeforeCreate in the same activity
32+
*
33+
* Warning : the injection (views, extras, etc) is not done yet when an @BeforeCreate
34+
* annotated method is called
35+
*/
36+
@Retention(RetentionPolicy.SOURCE)
37+
@Target(ElementType.METHOD)
38+
public @interface BeforeCreate {
39+
}

AndroidAnnotations/src/main/java/com/googlecode/androidannotations/generation/ActivityGenerator.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ public class ActivityGenerator {
3333
" @Override\n" + //
3434
" public void onCreate(android.os.Bundle savedInstanceState) {\n" + //
3535
"\n" + //
36+
"%s" + //
37+
"\n" + //
3638
" setContentView(%s);\n" + //
3739
"\n" + //
3840
"%s" + //
@@ -47,6 +49,11 @@ public void generate(MetaActivity activity, Writer writer) throws IOException {
4749
for (Instruction instruction : activity.getOnCreateInstructions()) {
4850
onCreateInstructionsBuilder.append(instruction.generate());
4951
}
52+
53+
StringBuilder beforeCreateInstructionsBuilder = new StringBuilder();
54+
for (Instruction instruction : activity.getBeforeCreateInstructions()) {
55+
beforeCreateInstructionsBuilder.append(instruction.generate());
56+
}
5057

5158
StringBuilder memberInstructionsBuilder = new StringBuilder();
5259
for (Instruction instruction : activity.getMemberInstructions()) {
@@ -70,6 +77,7 @@ public void generate(MetaActivity activity, Writer writer) throws IOException {
7077
activity.getClassSimpleName(), //
7178
activity.getSuperClassName(), //
7279
implementsBuilder.toString(), //
80+
beforeCreateInstructionsBuilder.toString(), //
7381
activity.getLayoutQualifiedName(), //
7482
onCreateInstructionsBuilder.toString(), //
7583
memberInstructionsBuilder.toString());
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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.generation;
17+
18+
import com.googlecode.androidannotations.model.Instruction;
19+
20+
public class BeforeCreateInstruction implements Instruction {
21+
22+
private static final String FORMAT = //
23+
"" + //
24+
" %s(%s);\n" + //
25+
"\n";
26+
27+
private final String methodName;
28+
29+
private final boolean bundleParameter;
30+
31+
public BeforeCreateInstruction(String methodName, boolean bundleParameter) {
32+
this.methodName = methodName;
33+
this.bundleParameter = bundleParameter;
34+
}
35+
36+
@Override
37+
public String generate() {
38+
String viewParameterValue = bundleParameter ? "savedInstanceState" : "";
39+
return String.format(FORMAT, methodName, viewParameterValue);
40+
}
41+
42+
}

AndroidAnnotations/src/main/java/com/googlecode/androidannotations/model/MetaActivity.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public class MetaActivity {
3030

3131
private final List<Instruction> onCreateInstructions = new ArrayList<Instruction>();
3232

33+
private final List<Instruction> beforeCreateInstructions = new ArrayList<Instruction>();
34+
3335
private final List<Instruction> memberInstructions = new ArrayList<Instruction>();
3436

3537
private final List<String> implementedInterfaces = new ArrayList<String>();
@@ -52,6 +54,10 @@ public List<Instruction> getOnCreateInstructions() {
5254
return onCreateInstructions;
5355
}
5456

57+
public List<Instruction> getBeforeCreateInstructions() {
58+
return beforeCreateInstructions;
59+
}
60+
5561
public List<Instruction> getMemberInstructions() {
5662
return memberInstructions;
5763
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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+
import java.util.List;
20+
21+
import javax.lang.model.element.Element;
22+
import javax.lang.model.element.ExecutableElement;
23+
import javax.lang.model.element.VariableElement;
24+
25+
import com.googlecode.androidannotations.annotations.BeforeCreate;
26+
import com.googlecode.androidannotations.generation.BeforeCreateInstruction;
27+
import com.googlecode.androidannotations.model.Instruction;
28+
import com.googlecode.androidannotations.model.MetaActivity;
29+
import com.googlecode.androidannotations.model.MetaModel;
30+
31+
public class BeforeCreateProcessor implements ElementProcessor {
32+
33+
@Override
34+
public Class<? extends Annotation> getTarget() {
35+
return BeforeCreate.class;
36+
}
37+
38+
@Override
39+
public void process(Element element, MetaModel metaModel) {
40+
41+
String methodName = element.getSimpleName().toString();
42+
43+
44+
Element enclosingElement = element.getEnclosingElement();
45+
MetaActivity metaActivity = metaModel.getMetaActivities().get(enclosingElement);
46+
List<Instruction> beforeCreateInstructions = metaActivity.getBeforeCreateInstructions();
47+
48+
ExecutableElement executableElement = (ExecutableElement) element;
49+
List<? extends VariableElement> parameters = executableElement.getParameters();
50+
51+
boolean bundleParameter = parameters.size() == 1;
52+
53+
Instruction instruction = new BeforeCreateInstruction(methodName, bundleParameter);
54+
beforeCreateInstructions.add(instruction);
55+
56+
}
57+
58+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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.validation;
17+
18+
import java.lang.annotation.Annotation;
19+
import java.util.List;
20+
21+
import javax.annotation.processing.ProcessingEnvironment;
22+
import javax.lang.model.element.Element;
23+
import javax.lang.model.element.ExecutableElement;
24+
import javax.lang.model.element.VariableElement;
25+
import javax.lang.model.type.TypeKind;
26+
import javax.lang.model.type.TypeMirror;
27+
28+
import com.googlecode.androidannotations.annotations.BeforeCreate;
29+
import com.googlecode.androidannotations.helper.ValidatorHelper;
30+
import com.googlecode.androidannotations.model.AnnotationElements;
31+
32+
public class BeforeCreateValidator extends ValidatorHelper implements ElementValidator {
33+
34+
private static final String ANDROID_BUNDLE_QUALIFIED_NAME = "android.os.Bundle";
35+
36+
public BeforeCreateValidator(ProcessingEnvironment processingEnv) {
37+
super(processingEnv);
38+
}
39+
40+
@Override
41+
public Class<? extends Annotation> getTarget() {
42+
return BeforeCreate.class;
43+
}
44+
45+
@Override
46+
public boolean validate(Element element, AnnotationElements validatedElements) {
47+
48+
IsValid valid = new IsValid();
49+
50+
validateEnclosingElementHasLayout(element, validatedElements, valid);
51+
52+
ExecutableElement executableElement = (ExecutableElement) element;
53+
54+
warnNotVoidReturnType(element, executableElement);
55+
56+
validateParameters(element, valid, executableElement);
57+
58+
validateIsNotPrivate(element, valid);
59+
60+
validateDoesntThrowException(element, valid);
61+
62+
return valid.isValid();
63+
}
64+
65+
private void validateParameters(Element element, IsValid valid, ExecutableElement executableElement) {
66+
List<? extends VariableElement> parameters = executableElement.getParameters();
67+
68+
if (parameters.size() != 0 && parameters.size() != 1) {
69+
valid.invalidate();
70+
printAnnotationError(element, annotationName() + " should only be used on a method with zero or one parameter, instead of " + parameters.size());
71+
}
72+
73+
if (parameters.size() == 1) {
74+
VariableElement parameter = parameters.get(0);
75+
TypeMirror parameterType = parameter.asType();
76+
if (!parameterType.toString().equals(ANDROID_BUNDLE_QUALIFIED_NAME)) {
77+
valid.invalidate();
78+
printAnnotationError(element, annotationName() + " should only be used on a method with no parameter or a parameter of type " + ANDROID_BUNDLE_QUALIFIED_NAME + ", not " + parameterType);
79+
}
80+
}
81+
}
82+
83+
private void warnNotVoidReturnType(Element element, ExecutableElement executableElement) {
84+
TypeMirror returnType = executableElement.getReturnType();
85+
86+
if (returnType.getKind() != TypeKind.VOID) {
87+
printAnnotationWarning(element, annotationName() + " should only be used on a method with a void return type");
88+
}
89+
}
90+
}

AndroidAnnotations/src/main/java/com/googlecode/androidannotations/validation/ClickValidator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ private void warnNotVoidReturnType(Element element, ExecutableElement executable
114114
TypeMirror returnType = executableElement.getReturnType();
115115

116116
if (returnType.getKind() != TypeKind.VOID) {
117-
printAnnotationWarning(element, annotationName() + " should only be used on a method with a void return type ");
117+
printAnnotationWarning(element, annotationName() + " should only be used on a method with a void return type");
118118
}
119119
}
120120
}

0 commit comments

Comments
 (0)