From 1ae49561a1397716e09c95e15bfc6cda10dafad2 Mon Sep 17 00:00:00 2001 From: Kay-Uwe Janssen Date: Thu, 4 Jun 2015 09:45:40 +0200 Subject: [PATCH 01/15] add isTypeOrSubclass() and castArgumentIfNecessary() helper to AbstractListenerHandler --- .../handler/AbstractListenerHandler.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/AbstractListenerHandler.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/AbstractListenerHandler.java index 58a814efbf..95a8ef3da3 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/AbstractListenerHandler.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/AbstractListenerHandler.java @@ -22,9 +22,11 @@ import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeMirror; +import org.androidannotations.helper.APTCodeModelHelper; import org.androidannotations.helper.AndroidManifest; import org.androidannotations.helper.IdAnnotationHelper; import org.androidannotations.helper.IdValidatorHelper; @@ -37,13 +39,16 @@ import com.sun.codemodel.JBlock; import com.sun.codemodel.JClass; import com.sun.codemodel.JDefinedClass; +import com.sun.codemodel.JExpr; import com.sun.codemodel.JExpression; import com.sun.codemodel.JFieldRef; import com.sun.codemodel.JInvocation; import com.sun.codemodel.JMethod; +import com.sun.codemodel.JVar; public abstract class AbstractListenerHandler extends BaseAnnotationHandler { + private final APTCodeModelHelper codeModelHelper = new APTCodeModelHelper(); private IdAnnotationHelper helper; private T holder; private String methodName; @@ -100,6 +105,22 @@ public void process(Element element, T holder) { assignListeners(holder, idsRefs, listenerAnonymousClass); } + protected final JExpression castArgumentIfNecessary(T holder, String baseType, JVar param, Element element) { + JExpression argument = param; + TypeMirror typeMirror = element.asType(); + if (!baseType.equals(typeMirror.toString())) { + JClass typeMirrorToJClass = codeModelHelper.typeMirrorToJClass(typeMirror, holder); + argument = JExpr.cast(typeMirrorToJClass, param); + } + return argument; + } + + protected final boolean isTypeOrSubclass(String baseType, Element element) { + TypeMirror typeMirror = element.asType(); + TypeElement typeElement = helper.typeElementFromQualifiedName(baseType); + return helper.isSubtype(typeMirror, typeElement.asType()); + } + protected abstract void assignListeners(T holder, List idsRefs, JDefinedClass listenerAnonymousClass); protected abstract void makeCall(JBlock listenerMethodBody, JInvocation call, TypeMirror returnType); From 9f6a66552318e384a846d7212c56f931d083883c Mon Sep 17 00:00:00 2001 From: Kay-Uwe Janssen Date: Thu, 4 Jun 2015 09:45:57 +0200 Subject: [PATCH 02/15] allow Preference subclasses as parameter for @PreferenceChange and @PreferenceClick --- .../androidannotations/annotations/PreferenceChange.java | 9 +++++++-- .../androidannotations/annotations/PreferenceClick.java | 9 +++++++-- .../handler/PreferenceChangeHandler.java | 7 +++---- .../handler/PreferenceClickHandler.java | 4 ++-- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/PreferenceChange.java b/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/PreferenceChange.java index 4a6c41679e..435fce96aa 100644 --- a/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/PreferenceChange.java +++ b/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/PreferenceChange.java @@ -39,8 +39,8 @@ * The method MAY have multiple parameter: *

*
    - *
  • A {@link android.preference.Preference Preference} parameter to know - * which preference was targeted by this event
  • + *
  • A {@link android.preference.Preference Preference} (or a sublcass) + * parameter to know which preference was targeted by this event
  • *
  • An {@link Object}, {@link String}, {@link java.util.Set Set of strings} * and also a {@link Boolean}, {@link Float}, {@link Integer}, {@link Long} or * their corresponding primitive types to obtain the new value of the @@ -65,6 +65,11 @@ * // Something Here * } * + * @PreferenceChange + * void myPrefPreferenceChanged(ListPreference preference) { + * // Something Here + * } + * * @PreferenceChange({R.string.myPref1, R.string.myPref2}) * void preferenceChangeOnMultiplePrefs(Preference preference, String newValue) { * // Something Here diff --git a/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/PreferenceClick.java b/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/PreferenceClick.java index e81e79a2d7..5c74e50e7a 100644 --- a/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/PreferenceClick.java +++ b/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/PreferenceClick.java @@ -37,8 +37,8 @@ * The method MAY have one parameter: *

    *
      - *
    • A {@link android.preference.Preference Preference} parameter to know - * which preference has been clicked
    • + *
    • A {@link android.preference.Preference Preference} (or a subclass) + * parameter to know which preference has been clicked
    • *
    *
    * @@ -54,6 +54,11 @@ * void myPrefPreferenceClicked(Preference preference) { * // Something Here * } + * + * @PreferenceClick + * void myPrefPreferenceClicked(ListPreference preference) { + * // Something Here + * } * * *
    diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/PreferenceChangeHandler.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/PreferenceChangeHandler.java index b37afab6eb..79ba096c78 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/PreferenceChangeHandler.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/PreferenceChangeHandler.java @@ -59,7 +59,7 @@ public void validate(Element element, AnnotationElements validatedElements, IsVa validatorHelper.returnTypeIsVoidOrBoolean(executableElement, valid); validatorHelper.param.anyOrder() // - .type(CanonicalNameConstants.PREFERENCE).optional() // + .extendsType(CanonicalNameConstants.PREFERENCE).optional() // .anyOfTypes(CanonicalNameConstants.OBJECT, CanonicalNameConstants.STRING_SET, CanonicalNameConstants.STRING, // CanonicalNameConstants.BOOLEAN, boolean.class.getName(), // CanonicalNameConstants.INTEGER, int.class.getName(), // @@ -86,9 +86,8 @@ protected void processParameters(HasPreferences holder, JMethod listenerMethod, for (VariableElement variableElement : userParameters) { String type = variableElement.asType().toString(); - - if (type.equals(CanonicalNameConstants.PREFERENCE)) { - call.arg(preferenceParam); + if (isTypeOrSubclass(CanonicalNameConstants.PREFERENCE, variableElement)) { + call.arg(castArgumentIfNecessary(holder, CanonicalNameConstants.PREFERENCE, preferenceParam, variableElement)); } else if (type.equals(CanonicalNameConstants.OBJECT)) { call.arg(newValueParam); } else if (type.equals(CanonicalNameConstants.INTEGER) || type.equals(int.class.getName()) || // diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/PreferenceClickHandler.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/PreferenceClickHandler.java index 61e0ec464e..4b2a0d3cc8 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/PreferenceClickHandler.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/PreferenceClickHandler.java @@ -55,7 +55,7 @@ public void validate(Element element, AnnotationElements validatedElements, IsVa validatorHelper.returnTypeIsVoidOrBoolean(executableElement, valid); validatorHelper.param // - .type(CanonicalNameConstants.PREFERENCE).optional() // + .extendsType(CanonicalNameConstants.PREFERENCE).optional() // .validate(executableElement, valid); } @@ -75,7 +75,7 @@ protected void processParameters(HasPreferences holder, JMethod listenerMethod, JVar preferenceParam = listenerMethod.param(classes().PREFERENCE, "preference"); if (userParameters.size() == 1) { - call.arg(preferenceParam); + call.arg(castArgumentIfNecessary(holder, CanonicalNameConstants.PREFERENCE, preferenceParam, userParameters.get(0))); } } From 26649abfb5dfa71e23d6a8709eb2c59b93cd4eb8 Mon Sep 17 00:00:00 2001 From: Kay-Uwe Janssen Date: Thu, 4 Jun 2015 09:46:22 +0200 Subject: [PATCH 03/15] add test for subclass parameters on @PreferenceClick and @PreferenceChange --- .../functional-test-1-5/res/values/values.xml | 3 ++- .../functional-test-1-5/res/xml/settings.xml | 2 ++ .../PreferenceEventsHandledActivity.java | 11 +++++++++++ .../PreferenceEventsHandledActivityTest.java | 16 ++++++++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/AndroidAnnotations/functional-test-1-5/res/values/values.xml b/AndroidAnnotations/functional-test-1-5/res/values/values.xml index cc332c0475..5cbc0a19d1 100644 --- a/AndroidAnnotations/functional-test-1-5/res/values/values.xml +++ b/AndroidAnnotations/functional-test-1-5/res/values/values.xml @@ -29,6 +29,7 @@ editTextPrefKey listPreferenceKey checkBoxPrefKey + checkBoxWithCastPrefKey switchPrefKey - \ No newline at end of file + diff --git a/AndroidAnnotations/functional-test-1-5/res/xml/settings.xml b/AndroidAnnotations/functional-test-1-5/res/xml/settings.xml index 0c52a89690..250a0e8322 100644 --- a/AndroidAnnotations/functional-test-1-5/res/xml/settings.xml +++ b/AndroidAnnotations/functional-test-1-5/res/xml/settings.xml @@ -30,6 +30,8 @@ + + diff --git a/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/preference/PreferenceEventsHandledActivity.java b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/preference/PreferenceEventsHandledActivity.java index 8b4ec7505f..831a829a48 100644 --- a/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/preference/PreferenceEventsHandledActivity.java +++ b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/preference/PreferenceEventsHandledActivity.java @@ -21,6 +21,7 @@ import org.androidannotations.test15.R; import android.os.Bundle; +import android.preference.CheckBoxPreference; import android.preference.Preference; import android.preference.PreferenceActivity; @@ -66,6 +67,11 @@ void checkBoxPreferenceChanged(Preference preference, Boolean newValue) { this.newValue = newValue; } + @PreferenceChange(R.string.checkBoxWithCastPrefKey) + void checkBoxWithCastPreferenceChanged(CheckBoxPreference preference) { + this.preference = preference; + } + @PreferenceChange(R.string.switchPrefKey) boolean switchPreferenceChanged() { return false; @@ -86,6 +92,11 @@ void checkBoxPreferenceClicked(Preference preference) { this.preference = preference; } + @PreferenceClick(R.string.checkBoxWithCastPrefKey) + void checkBoxWithCastPreferenceClicked(CheckBoxPreference preference) { + this.preference = preference; + } + @PreferenceClick(R.string.switchPrefKey) boolean switchPreferenceClicked() { return false; diff --git a/AndroidAnnotations/functional-test-1-5/src/test/java/org/androidannotations/test15/preference/PreferenceEventsHandledActivityTest.java b/AndroidAnnotations/functional-test-1-5/src/test/java/org/androidannotations/test15/preference/PreferenceEventsHandledActivityTest.java index f48f5b91a7..ef2d1e7d62 100644 --- a/AndroidAnnotations/functional-test-1-5/src/test/java/org/androidannotations/test15/preference/PreferenceEventsHandledActivityTest.java +++ b/AndroidAnnotations/functional-test-1-5/src/test/java/org/androidannotations/test15/preference/PreferenceEventsHandledActivityTest.java @@ -69,6 +69,14 @@ public void testPreferenceChangeParameterPassed() { assertThat(activity.newValue).isSameAs(newValue); } + @Test + public void testPreferenceChangeCastedParameterPassed() { + Preference preference = activity.findPreference(activity.getString(R.string.checkBoxWithCastPrefKey)); + preference.getOnPreferenceChangeListener().onPreferenceChange(preference, true); + + assertThat(activity.preference).isSameAs(preference); + } + @Test public void testPreferenceChangeParsedParameterPassed() { Preference preference = activity.findPreference(activity.getString(R.string.editTextPrefKey)); @@ -122,6 +130,14 @@ public void testPreferenceClickParameterPassed() { assertThat(activity.preference).isSameAs(preference); } + @Test + public void testPreferenceClickCastedParameterPassed() { + Preference preference = activity.findPreference(activity.getString(R.string.checkBoxWithCastPrefKey)); + preference.getOnPreferenceClickListener().onPreferenceClick(preference); + + assertThat(activity.preference).isSameAs(preference); + } + @Test public void testPreferenceClickDefaultReturnValue() { Preference preference = activity.findPreference(activity.getString(R.string.listPreferenceKey)); From e3047014e82bdbb3b6ac117cb1db47024797a658 Mon Sep 17 00:00:00 2001 From: Kay-Uwe Janssen Date: Thu, 4 Jun 2015 09:47:06 +0200 Subject: [PATCH 04/15] allow subclasses for @CheckedChange --- .../androidannotations/annotations/CheckedChange.java | 9 +++++++-- .../androidannotations/handler/CheckedChangeHandler.java | 6 +++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/CheckedChange.java b/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/CheckedChange.java index 7aa88dd79d..00c4716ca7 100644 --- a/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/CheckedChange.java +++ b/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/CheckedChange.java @@ -37,8 +37,8 @@ * The method MAY have multiple parameter: *

    *
      - *
    • A {@link android.widget.CompoundButton} parameter to know which view has - * targeted this event
    • + *
    • A {@link android.widget.CompoundButton} (or a subclass) parameter to know + * which view has targeted this event
    • *
    • An {@link boolean} to know the new state of the view.
    • *
    *
    @@ -56,6 +56,11 @@ * // Something Here * } * + * @CheckedChange + * void myButtonCheckedChanged(CheckBox button) { + * // Something Here + * } + * * @CheckedChange({R.id.myButton, R.id.myButton1}) * void checkedChangedOnSomeButtons(CompoundButton button, boolean isChecked) { * // Something Here diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/CheckedChangeHandler.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/CheckedChangeHandler.java index 45cfc652c6..66ea9dffe5 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/CheckedChangeHandler.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/CheckedChangeHandler.java @@ -52,7 +52,7 @@ public void validate(Element element, AnnotationElements validatedElements, IsVa validatorHelper.returnTypeIsVoid(executableElement, valid); validatorHelper.param.anyOrder() // - .type(CanonicalNameConstants.COMPOUND_BUTTON).optional() // + .extendsType(CanonicalNameConstants.COMPOUND_BUTTON).optional() // .primitiveOrWrapper(TypeKind.BOOLEAN).optional() // .validate(executableElement, valid); } @@ -69,8 +69,8 @@ protected void processParameters(EComponentWithViewSupportHolder holder, JMethod for (VariableElement parameter : parameters) { String parameterType = parameter.asType().toString(); - if (parameterType.equals(CanonicalNameConstants.COMPOUND_BUTTON)) { - call.arg(btnParam); + if (isTypeOrSubclass(CanonicalNameConstants.COMPOUND_BUTTON, parameter)) { + call.arg(castArgumentIfNecessary(holder, CanonicalNameConstants.COMPOUND_BUTTON, btnParam, parameter)); } else if (parameterType.equals(CanonicalNameConstants.BOOLEAN) || parameter.asType().getKind() == TypeKind.BOOLEAN) { call.arg(isCheckedParam); } From 993fd409fa2ca768c88b90e58d465de9a34e78fa Mon Sep 17 00:00:00 2001 From: Kay-Uwe Janssen Date: Thu, 4 Jun 2015 09:47:38 +0200 Subject: [PATCH 05/15] add test for subclasses in @CheckedChange --- .../res/layout/checkable_widgets.xml | 5 +++++ .../test15/CheckedChangeHandledActivity.java | 7 ++++++- .../test15/CheckedChangeHandledActivityTest.java | 12 +++++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/AndroidAnnotations/functional-test-1-5/res/layout/checkable_widgets.xml b/AndroidAnnotations/functional-test-1-5/res/layout/checkable_widgets.xml index 95586df4c7..ca742f8fdf 100644 --- a/AndroidAnnotations/functional-test-1-5/res/layout/checkable_widgets.xml +++ b/AndroidAnnotations/functional-test-1-5/res/layout/checkable_widgets.xml @@ -26,6 +26,11 @@ android:layout_width="fill_parent" android:layout_height="wrap_content" /> + + Date: Thu, 4 Jun 2015 09:48:02 +0200 Subject: [PATCH 06/15] allow subclasses for @Click --- .../java/org/androidannotations/annotations/Click.java | 9 +++++++-- .../org/androidannotations/handler/ClickHandler.java | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/Click.java b/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/Click.java index 4ab6c7e10a..bdf7efdfe5 100644 --- a/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/Click.java +++ b/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/Click.java @@ -34,8 +34,8 @@ * The method MAY have one parameter: *

    *
      - *
    • A {@link android.view.View} parameter to know which view has been clicked - *
    • + *
    • A {@link android.view.View} (or a subclass) parameter to know which view + * has been clicked
    • *
    *
    * @@ -51,6 +51,11 @@ * void myButtonClicked(View view) { * // Something Here * } + * + * @Click + * void myButtonClicked(Button view) { + * // Something Here + * } * * *
    diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/ClickHandler.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/ClickHandler.java index bd6f841455..1b5e9d0175 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/ClickHandler.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/ClickHandler.java @@ -66,7 +66,7 @@ protected void processParameters(EComponentWithViewSupportHolder holder, JMethod JVar viewParam = listenerMethod.param(classes().VIEW, "view"); if (hasItemParameter) { - call.arg(viewParam); + call.arg(castArgumentIfNecessary(holder, CanonicalNameConstants.VIEW, viewParam, parameters.get(0))); } } From 8d475a7ffaf18dd000cf494d3217ab143a9d0f99 Mon Sep 17 00:00:00 2001 From: Kay-Uwe Janssen Date: Thu, 4 Jun 2015 09:54:24 +0200 Subject: [PATCH 07/15] add test for subclasses in @Click --- .../res/layout/clickable_widgets.xml | 5 +++++ .../test15/ClicksHandledActivity.java | 6 ++++++ .../test15/ClicksHandledActivityTest.java | 12 +++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/AndroidAnnotations/functional-test-1-5/res/layout/clickable_widgets.xml b/AndroidAnnotations/functional-test-1-5/res/layout/clickable_widgets.xml index 8905815ad4..c8d49261f7 100644 --- a/AndroidAnnotations/functional-test-1-5/res/layout/clickable_widgets.xml +++ b/AndroidAnnotations/functional-test-1-5/res/layout/clickable_widgets.xml @@ -26,6 +26,11 @@ android:layout_width="fill_parent" android:layout_height="wrap_content" /> +