Skip to content

Commit 5e38b20

Browse files
committed
Add a @OptionMenuItem annotation to inject MenuItem
1 parent b0ef7e8 commit 5e38b20

13 files changed

Lines changed: 334 additions & 83 deletions

File tree

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* Copyright (C) 2010-2013 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.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+
* Should be used on option items fields in activity classes.
25+
*
26+
* The field MUST be of type {@link link android.view.MenuItem} or
27+
* {@link com.actionbarsherlock.view.MenuItem}.
28+
* <p/>
29+
* The annotation value should be one of R.id.* fields. If not set, the method
30+
* name will be used as the R.id.* field name. *
31+
*/
32+
@Retention(RetentionPolicy.CLASS)
33+
@Target(ElementType.FIELD)
34+
public @interface OptionsMenuItem {
35+
36+
int[] value() default ResId.DEFAULT_VALUE;
37+
38+
String[] resName() default "";
39+
40+
}

‎AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/AndroidAnnotationProcessor.java‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
import org.androidannotations.annotations.OnActivityResult;
7676
import org.androidannotations.annotations.OptionsItem;
7777
import org.androidannotations.annotations.OptionsMenu;
78+
import org.androidannotations.annotations.OptionsMenuItem;
7879
import org.androidannotations.annotations.OrmLiteDao;
7980
import org.androidannotations.annotations.RoboGuice;
8081
import org.androidannotations.annotations.RootContext;
@@ -165,6 +166,7 @@
165166
import org.androidannotations.processing.NonConfigurationInstanceProcessor;
166167
import org.androidannotations.processing.OnActivityResultProcessor;
167168
import org.androidannotations.processing.OptionsItemProcessor;
169+
import org.androidannotations.processing.OptionsMenuItemProcessor;
168170
import org.androidannotations.processing.OptionsMenuProcessor;
169171
import org.androidannotations.processing.OrmLiteDaoProcessor;
170172
import org.androidannotations.processing.PrefProcessor;
@@ -234,6 +236,7 @@
234236
import org.androidannotations.validation.NonConfigurationInstanceValidator;
235237
import org.androidannotations.validation.OnActivityResultValidator;
236238
import org.androidannotations.validation.OptionsItemValidator;
239+
import org.androidannotations.validation.OptionsMenuItemValidator;
237240
import org.androidannotations.validation.OptionsMenuValidator;
238241
import org.androidannotations.validation.OrmLiteDaoValidator;
239242
import org.androidannotations.validation.PrefValidator;
@@ -420,6 +423,7 @@ private ModelValidator buildModelValidator(IRClass rClass, AndroidSystemServices
420423
modelValidator.register(new AcceptValidator(processingEnv));
421424
modelValidator.register(new AppValidator(processingEnv));
422425
modelValidator.register(new OptionsMenuValidator(processingEnv, rClass));
426+
modelValidator.register(new OptionsMenuItemValidator(processingEnv, rClass));
423427
modelValidator.register(new OptionsItemValidator(processingEnv, rClass));
424428
modelValidator.register(new NoTitleValidator(processingEnv));
425429
modelValidator.register(new CustomTitleValidator(processingEnv, rClass));
@@ -515,6 +519,7 @@ private ModelProcessor buildModelProcessor(IRClass rClass, AndroidSystemServices
515519
modelProcessor.register(new OptionsProcessor(processingEnv, restImplementationsHolder));
516520
modelProcessor.register(new AppProcessor());
517521
modelProcessor.register(new OptionsMenuProcessor(processingEnv, rClass));
522+
modelProcessor.register(new OptionsMenuItemProcessor(processingEnv, rClass));
518523
modelProcessor.register(new OptionsItemProcessor(processingEnv, rClass));
519524
modelProcessor.register(new NoTitleProcessor());
520525
modelProcessor.register(new CustomTitleProcessor(processingEnv, rClass));
@@ -633,6 +638,7 @@ public Set<String> getSupportedAnnotationTypes() {
633638
Accept.class, //
634639
FromHtml.class, //
635640
OptionsMenu.class, //
641+
OptionsMenuItem.class, //
636642
OptionsItem.class, //
637643
HtmlRes.class, //
638644
NoTitle.class, //

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ public class ValidatorHelper {
7878

7979
private static final List<String> ANDROID_FRAGMENT_QUALIFIED_NAMES = asList(CanonicalNameConstants.FRAGMENT, CanonicalNameConstants.SUPPORT_V4_FRAGMENT);
8080

81+
private static final List<String> ANDROID_MENU_ITEM_QUALIFIED_NAMES = asList(CanonicalNameConstants.MENU_ITEM, CanonicalNameConstants.SHERLOCK_MENU_ITEM);
82+
8183
private static final String METHOD_NAME_SET_ROOT_URL = "setRootUrl";
8284

8385
private static final List<String> VALID_PREF_RETURN_TYPES = Arrays.asList("int", "boolean", "float", "long", CanonicalNameConstants.STRING);
@@ -497,6 +499,10 @@ public void extendsContext(Element element, IsValid valid) {
497499
extendsType(element, CanonicalNameConstants.CONTEXT, valid);
498500
}
499501

502+
public void extendsMenuItem(Element element, IsValid valid) {
503+
extendsOneOfTypes(element, ANDROID_MENU_ITEM_QUALIFIED_NAMES, valid);
504+
}
505+
500506
public void extendsOrmLiteDaoWithValidModelParameter(Element element, IsValid valid) {
501507
TypeMirror elementType = element.asType();
502508

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/**
2+
* Copyright (C) 2010-2013 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.processing;
17+
18+
import static com.sun.codemodel.JExpr.invoke;
19+
import static com.sun.codemodel.JMod.PUBLIC;
20+
21+
import javax.annotation.processing.ProcessingEnvironment;
22+
import javax.lang.model.element.Element;
23+
24+
import org.androidannotations.annotations.EFragment;
25+
import org.androidannotations.helper.IdAnnotationHelper;
26+
import org.androidannotations.helper.ThirdPartyLibHelper;
27+
import org.androidannotations.processing.EBeansHolder.Classes;
28+
import org.androidannotations.rclass.IRClass;
29+
30+
import com.sun.codemodel.JBlock;
31+
import com.sun.codemodel.JClass;
32+
import com.sun.codemodel.JCodeModel;
33+
import com.sun.codemodel.JExpr;
34+
import com.sun.codemodel.JInvocation;
35+
import com.sun.codemodel.JMethod;
36+
import com.sun.codemodel.JType;
37+
import com.sun.codemodel.JVar;
38+
39+
public abstract class AbstractOptionsMenuProcessor implements DecoratingElementProcessor {
40+
41+
protected final ThirdPartyLibHelper libHelper;
42+
protected final IdAnnotationHelper annotationHelper;
43+
44+
public AbstractOptionsMenuProcessor(ProcessingEnvironment processingEnv, IRClass rClass) {
45+
annotationHelper = new IdAnnotationHelper(processingEnv, getTarget(), rClass);
46+
libHelper = new ThirdPartyLibHelper(annotationHelper);
47+
}
48+
49+
@Override
50+
public void process(Element element, JCodeModel codeModel, EBeanHolder holder) {
51+
if (holder.onCreateOptionMenuMethodBody == null) {
52+
Classes classes = holder.classes();
53+
54+
boolean isFragment = holder.eBeanAnnotation == EFragment.class;
55+
56+
JClass menuClass;
57+
JClass menuInflaterClass;
58+
String getMenuInflaterMethodName;
59+
if (libHelper.usesActionBarSherlock(holder)) {
60+
menuClass = classes.SHERLOCK_MENU;
61+
menuInflaterClass = classes.SHERLOCK_MENU_INFLATER;
62+
getMenuInflaterMethodName = "getSupportMenuInflater";
63+
} else {
64+
menuClass = classes.MENU;
65+
menuInflaterClass = classes.MENU_INFLATER;
66+
getMenuInflaterMethodName = "getMenuInflater";
67+
}
68+
69+
JType returnType;
70+
if (isFragment) {
71+
returnType = codeModel.VOID;
72+
} else {
73+
returnType = codeModel.BOOLEAN;
74+
}
75+
76+
JBlock body;
77+
JVar menuInflater;
78+
JVar menuParam;
79+
80+
JMethod method = holder.generatedClass.method(PUBLIC, returnType, "onCreateOptionsMenu");
81+
method.annotate(Override.class);
82+
83+
menuParam = method.param(menuClass, "menu");
84+
85+
JBlock methodBody = method.body();
86+
87+
if (isFragment) {
88+
menuInflater = method.param(menuInflaterClass, "inflater");
89+
} else {
90+
menuInflater = methodBody.decl(menuInflaterClass, "menuInflater", invoke(getMenuInflaterMethodName));
91+
}
92+
93+
body = methodBody.block();
94+
95+
JInvocation superCall = invoke(JExpr._super(), method);
96+
superCall.arg(menuParam);
97+
98+
if (isFragment) {
99+
superCall.arg(menuInflater);
100+
methodBody.add(superCall);
101+
} else {
102+
methodBody._return(superCall);
103+
}
104+
105+
if (isFragment) {
106+
holder.initBody.invoke("setHasOptionsMenu").arg(JExpr.TRUE);
107+
}
108+
109+
holder.onCreateOptionMenuMethodBody = body;
110+
holder.onCreateOptionMenuMenuInflaterVariable = menuInflater;
111+
holder.onCreateOptionMenuMenuParam = menuParam;
112+
}
113+
}
114+
115+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* Copyright (C) 2010-2013 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.processing;
17+
18+
import static com.sun.codemodel.JExpr.ref;
19+
20+
import javax.annotation.processing.ProcessingEnvironment;
21+
import javax.lang.model.element.Element;
22+
23+
import org.androidannotations.annotations.OptionsMenuItem;
24+
import org.androidannotations.rclass.IRClass;
25+
import org.androidannotations.rclass.IRClass.Res;
26+
27+
import com.sun.codemodel.JBlock;
28+
import com.sun.codemodel.JCodeModel;
29+
import com.sun.codemodel.JFieldRef;
30+
import com.sun.codemodel.JVar;
31+
32+
/**
33+
*/
34+
public class OptionsMenuItemProcessor extends AbstractOptionsMenuProcessor {
35+
36+
public OptionsMenuItemProcessor(ProcessingEnvironment processingEnv, IRClass rClass) {
37+
super(processingEnv, rClass);
38+
}
39+
40+
@Override
41+
public String getTarget() {
42+
return OptionsMenuItem.class.getName();
43+
}
44+
45+
@Override
46+
public void process(Element element, JCodeModel codeModel, EBeanHolder holder) {
47+
super.process(element, codeModel, holder);
48+
49+
String fieldName = element.getSimpleName().toString();
50+
JBlock body = holder.onCreateOptionMenuMethodBody;
51+
JVar menuParam = holder.onCreateOptionMenuMenuParam;
52+
53+
JFieldRef idsRef = annotationHelper.extractOneAnnotationFieldRef(holder, element, Res.ID, true);
54+
55+
body.assign(ref(fieldName), menuParam.invoke("findItem").arg(idsRef));
56+
57+
}
58+
}

0 commit comments

Comments
 (0)