Skip to content
This repository was archived by the owner on Feb 26, 2023. It is now read-only.

Commit 3dba0f3

Browse files
committed
Added parceler @Extra and @InstanceState support
1 parent 76b374d commit 3dba0f3

13 files changed

Lines changed: 215 additions & 12 deletions

File tree

‎AndroidAnnotations/androidannotations-core/androidannotations-test/pom.xml‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,17 @@
8282
<version>140</version>
8383
<scope>test</scope>
8484
</dependency>
85+
<dependency>
86+
<groupId>org.parceler</groupId>
87+
<artifactId>parceler</artifactId>
88+
<version>1.0.3</version>
89+
<scope>provided</scope>
90+
</dependency>
91+
<dependency>
92+
<groupId>org.parceler</groupId>
93+
<artifactId>parceler-api</artifactId>
94+
<version>1.0.3</version>
95+
</dependency>
8596
</dependencies>
8697
<build>
8798
<plugins>

‎AndroidAnnotations/androidannotations-core/androidannotations-test/src/main/java/org/androidannotations/test/ExtraInjectedActivity.java‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
package org.androidannotations.test;
1717

1818
import java.util.ArrayList;
19+
import java.util.List;
1920

2021
import org.androidannotations.annotations.EActivity;
2122
import org.androidannotations.annotations.Extra;
23+
import org.androidannotations.test.parceler.ParcelerBean;
2224

2325
import android.app.Activity;
2426
import android.content.Intent;
@@ -41,6 +43,12 @@ public class ExtraInjectedActivity extends Activity {
4143
@Extra("byteArrayExtra")
4244
byte[] byteArrayExtra;
4345

46+
@Extra("parcelerExtra")
47+
ParcelerBean parcelerExample;
48+
49+
@Extra("parcelerExtraCollection")
50+
List<ParcelerBean> parcelerExampleCollection;
51+
4452
@Extra
4553
String extraWithoutValue;
4654

@@ -57,6 +65,12 @@ void intentWithExtras() {
5765
ExtraInjectedActivity_.intent(this).intExtra(42).get();
5866
ExtraInjectedActivity_.intent(this).stringExtra("hello")
5967
.startForResult(42);
68+
ExtraInjectedActivity_.intent(this)
69+
.parcelerExample(new ParcelerBean("Andy", 42));
70+
List<ParcelerBean> parcelerBeans = new ArrayList<ParcelerBean>();
71+
parcelerBeans.add(new ParcelerBean("Duke", 1337));
72+
ExtraInjectedActivity_.intent(this)
73+
.parcelerExampleCollection(parcelerBeans);
6074
ExtraInjectedActivity_.intent(this)
6175
.parcelableSerializableData(new ParcelableSerializableData())
6276
.get();

‎AndroidAnnotations/androidannotations-core/androidannotations-test/src/main/java/org/androidannotations/test/instancestate/SaveInstanceStateActivity.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.androidannotations.annotations.EActivity;
2121
import org.androidannotations.annotations.InstanceState;
2222
import org.androidannotations.test.R;
23+
import org.androidannotations.test.parceler.ParcelerBean;
2324

2425
import android.app.Activity;
2526
import android.os.Bundle;
@@ -180,4 +181,6 @@ public class SaveInstanceStateActivity extends Activity {
180181
@InstanceState
181182
Bundle bundle;
182183

184+
@InstanceState
185+
ParcelerBean parcelerBean;
183186
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* Copyright (C) 2010-2015 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.test.parceler;
17+
18+
import org.parceler.Parcel;
19+
import org.parceler.ParcelConstructor;
20+
21+
22+
@Parcel
23+
public class ParcelerBean {
24+
25+
String name;
26+
int age;
27+
28+
public ParcelerBean() {
29+
}
30+
31+
@ParcelConstructor
32+
public ParcelerBean(String name, int age) {
33+
this.name = name;
34+
this.age = age;
35+
}
36+
37+
public String getName() {
38+
return name;
39+
}
40+
41+
public int getAge() {
42+
return age;
43+
}
44+
}

‎AndroidAnnotations/androidannotations-core/androidannotations-test/src/test/java/org/androidannotations/test/InjectExtraTest.java‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
import static org.fest.assertions.api.Assertions.assertThat;
1919

2020
import java.util.ArrayList;
21+
import java.util.List;
2122

23+
import org.androidannotations.test.parceler.ParcelerBean;
2224
import org.junit.Before;
2325
import org.junit.Test;
2426
import org.junit.runner.RunWith;
@@ -93,4 +95,22 @@ public void extraWithoutValueInjected() {
9395
assertThat(activity.extraWithoutValue).isEqualTo("Hello!");
9496
}
9597

98+
@Test
99+
public void parcelerExtraInjected() {
100+
controller.withIntent(ExtraInjectedActivity_.intent(context).parcelerExample(new ParcelerBean("Andy", 42)).get()).create();
101+
assertThat(activity.parcelerExample.getName()).isEqualTo("Andy");
102+
assertThat(activity.parcelerExample.getAge()).isEqualTo(42);
103+
}
104+
105+
@Test
106+
public void parcelerExtraCollectionInjected() {
107+
List<ParcelerBean> parcelerBeans = new ArrayList<ParcelerBean>();
108+
parcelerBeans.add(new ParcelerBean("Duke", 1337));
109+
controller.withIntent(ExtraInjectedActivity_.intent(context).parcelerExampleCollection(parcelerBeans).get()).create();
110+
assertThat(activity.parcelerExampleCollection.size()).isEqualTo(1);
111+
ParcelerBean bean = activity.parcelerExampleCollection.iterator().next();
112+
assertThat(bean.getName()).isEqualTo("Duke");
113+
assertThat(bean.getAge()).isEqualTo(1337);
114+
}
115+
96116
}

‎AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/helper/AnnotationHelper.java‎

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,19 @@
2222
import java.lang.reflect.InvocationTargetException;
2323
import java.lang.reflect.Method;
2424
import java.util.ArrayList;
25+
import java.util.Collection;
26+
import java.util.HashMap;
27+
import java.util.HashSet;
28+
import java.util.LinkedHashMap;
29+
import java.util.LinkedHashSet;
30+
import java.util.LinkedList;
2531
import java.util.List;
2632
import java.util.Map;
33+
import java.util.Set;
34+
import java.util.SortedMap;
35+
import java.util.SortedSet;
36+
import java.util.TreeMap;
37+
import java.util.TreeSet;
2738

2839
import javax.annotation.processing.ProcessingEnvironment;
2940
import javax.lang.model.element.AnnotationMirror;
@@ -55,6 +66,40 @@ public class AnnotationHelper {
5566

5667
public static final String DEFAULT_FIELD_NAME_VALUE = "value";
5768
public static final String DEFAULT_FIELD_NAME_RESNAME = "resName";
69+
private static final String PARCEL_ANNOTATION = "org.parceler.Parcel";
70+
private static final Map<String, Integer> SUPPORTED_PARCEL_TYPES = new HashMap<>();
71+
72+
static {
73+
SUPPORTED_PARCEL_TYPES.put(Collection.class.getName(), 1);
74+
SUPPORTED_PARCEL_TYPES.put(List.class.getName(), 1);
75+
SUPPORTED_PARCEL_TYPES.put(ArrayList.class.getName(), 1);
76+
SUPPORTED_PARCEL_TYPES.put(Set.class.getName(), 1);
77+
SUPPORTED_PARCEL_TYPES.put(HashSet.class.getName(), 2);
78+
SUPPORTED_PARCEL_TYPES.put(TreeSet.class.getName(), 2);
79+
SUPPORTED_PARCEL_TYPES.put(CanonicalNameConstants.SPARSE_ARRAY, 1);
80+
SUPPORTED_PARCEL_TYPES.put(Map.class.getName(), 2);
81+
SUPPORTED_PARCEL_TYPES.put(HashMap.class.getName(), 2);
82+
SUPPORTED_PARCEL_TYPES.put(TreeMap.class.getName(), 2);
83+
SUPPORTED_PARCEL_TYPES.put(Integer.class.getName(), 0);
84+
SUPPORTED_PARCEL_TYPES.put(Long.class.getName(), 0);
85+
SUPPORTED_PARCEL_TYPES.put(Double.class.getName(), 0);
86+
SUPPORTED_PARCEL_TYPES.put(Float.class.getName(), 0);
87+
SUPPORTED_PARCEL_TYPES.put(Byte.class.getName(), 0);
88+
SUPPORTED_PARCEL_TYPES.put(String.class.getName(), 0);
89+
SUPPORTED_PARCEL_TYPES.put(Character.class.getName(), 0);
90+
SUPPORTED_PARCEL_TYPES.put(Boolean.class.getName(), 0);
91+
SUPPORTED_PARCEL_TYPES.put(byte[].class.getName(), 0);
92+
SUPPORTED_PARCEL_TYPES.put(char[].class.getName(), 0);
93+
SUPPORTED_PARCEL_TYPES.put(boolean[].class.getName(), 0);
94+
SUPPORTED_PARCEL_TYPES.put(CanonicalNameConstants.IBINDER, 0);
95+
SUPPORTED_PARCEL_TYPES.put(CanonicalNameConstants.BUNDLE, 0);
96+
SUPPORTED_PARCEL_TYPES.put(CanonicalNameConstants.SPARSE_BOOLEAN_ARRAY, 0);
97+
SUPPORTED_PARCEL_TYPES.put(LinkedList.class.getName(), 1);
98+
SUPPORTED_PARCEL_TYPES.put(LinkedHashMap.class.getName(), 2);
99+
SUPPORTED_PARCEL_TYPES.put(SortedMap.class.getName(), 2);
100+
SUPPORTED_PARCEL_TYPES.put(SortedSet.class.getName(), 1);
101+
SUPPORTED_PARCEL_TYPES.put(LinkedHashSet.class.getName(), 1);
102+
};
58103

59104
private static final Logger LOGGER = LoggerFactory.getLogger(AnnotationHelper.class);
60105

@@ -95,6 +140,47 @@ public TypeElement typeElementFromQualifiedName(String qualifiedName) {
95140
return getElementUtils().getTypeElement(qualifiedName);
96141
}
97142

143+
public boolean isParcelType(TypeMirror typeMirror) {
144+
return isParcelType(typeMirror, true);
145+
}
146+
147+
public boolean isParcelType(TypeMirror typeMirror, boolean root) {
148+
if (typeMirror instanceof DeclaredType && getElementUtils().getTypeElement(PARCEL_ANNOTATION) != null) {
149+
DeclaredType declaredType = (DeclaredType) typeMirror;
150+
TypeElement element = (TypeElement) declaredType.asElement();
151+
152+
String name = element.getQualifiedName().toString();
153+
154+
if (isAnnotatedWith(element, PARCEL_ANNOTATION)) {
155+
return true;
156+
}
157+
158+
if (SUPPORTED_PARCEL_TYPES.containsKey(name)) {
159+
boolean genericsMatch = true;
160+
161+
Integer genericsSize = SUPPORTED_PARCEL_TYPES.get(name);
162+
if (genericsSize == declaredType.getTypeArguments().size()
163+
&& (!root || genericsSize > 0)) {
164+
for (int i = 0; i < genericsSize; i++) {
165+
genericsMatch &= isParcelType(declaredType.getTypeArguments().get(i), false);
166+
}
167+
168+
return genericsMatch;
169+
}
170+
}
171+
}
172+
return false;
173+
}
174+
175+
private boolean isAnnotatedWith(Element element, String qualifiedName) {
176+
for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) {
177+
if (annotationMirror.getAnnotationType().toString().equals(qualifiedName)) {
178+
return true;
179+
}
180+
}
181+
return false;
182+
}
183+
98184
public String generatedClassQualifiedNameFromQualifiedName(String qualifiedName) {
99185
TypeElement type = typeElementFromQualifiedName(qualifiedName);
100186
if (type.getNestingKind() == NestingKind.MEMBER) {
@@ -443,5 +529,4 @@ public boolean hasOneOfClassAnnotations(Element element, List<Class<? extends An
443529
}
444530
return false;
445531
}
446-
447532
}

‎AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/helper/BundleHelper.java‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import com.sun.codemodel.JExpr;
3636
import com.sun.codemodel.JExpression;
3737
import com.sun.codemodel.JMethod;
38+
import com.sun.codemodel.JStatement;
3839

3940
public class BundleHelper {
4041
public static final Map<String, String> METHOD_SUFFIX_BY_TYPE_NAME = new HashMap<>();
@@ -83,6 +84,7 @@ public class BundleHelper {
8384

8485
private boolean restoreCallNeedCastStatement = false;
8586
private boolean restoreCallNeedsSuppressWarning = false;
87+
private boolean parcelerBean = false;
8688

8789
private String methodNameToSave;
8890
private String methodNameToRestore;
@@ -172,6 +174,10 @@ public BundleHelper(AndroidAnnotationsEnvironment environment, TypeMirror elemen
172174
if (isTypeParcelable(type)) {
173175
methodNameToSave = "put" + "Parcelable";
174176
methodNameToRestore = "get" + "Parcelable";
177+
} else if (annotationHelper.isParcelType(type)) {
178+
methodNameToSave = "put" + "Parcelable";
179+
methodNameToRestore = "get" + "Parcelable";
180+
parcelerBean = true;
175181
} else {
176182
methodNameToSave = "put" + "Serializable";
177183
methodNameToRestore = "get" + "Serializable";
@@ -225,6 +231,10 @@ public JExpression getExpressionToRestoreFromBundle(JClass variableClass, JExpre
225231
expressionToRestore = JExpr.invoke(bundle, methodNameToRestore).arg(extraKey);
226232
}
227233

234+
if (parcelerBean) {
235+
expressionToRestore = environment.getCodeModel().ref("org.parceler.Parcels").staticInvoke("unwrap").arg(expressionToRestore);
236+
}
237+
228238
if (restoreCallNeedCastStatement) {
229239
expressionToRestore = JExpr.cast(variableClass, expressionToRestore);
230240

@@ -234,4 +244,12 @@ public JExpression getExpressionToRestoreFromBundle(JClass variableClass, JExpre
234244
}
235245
return expressionToRestore;
236246
}
247+
248+
public JStatement getExpressionToSaveFromField(JExpression saveStateBundleParam, JExpression fieldName, JExpression variableRef) {
249+
JExpression refExpression = variableRef;
250+
if (parcelerBean) {
251+
refExpression = environment.getCodeModel().ref("org.parceler.Parcels").staticInvoke("wrap").arg(refExpression);
252+
}
253+
return JExpr.invoke(saveStateBundleParam, methodNameToSave).arg(fieldName).arg(refExpression);
254+
}
237255
}

‎AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/helper/CanonicalNameConstants.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ public final class CanonicalNameConstants {
5858
public static final String INTENT_FILTER = "android.content.IntentFilter";
5959
public static final String COMPONENT_NAME = "android.content.ComponentName";
6060
public static final String BUNDLE = "android.os.Bundle";
61+
public static final String IBINDER = "android.os.IBinder";
62+
public static final String SPARSE_ARRAY = "android.util.SparseArray";
63+
public static final String SPARSE_BOOLEAN_ARRAY = "android.util.SparseBooleanArray";
6164
public static final String APPLICATION = "android.app.Application";
6265
public static final String ACTIVITY = "android.app.Activity";
6366
public static final String EDITABLE = "android.text.Editable";

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -546,8 +546,10 @@ public void canBePutInABundle(Element element, ElementValidation valid) {
546546
if (typeMirror.getKind() != TypeKind.NONE) {
547547
TypeMirror parcelableType = annotationHelper.typeElementFromQualifiedName(CanonicalNameConstants.PARCELABLE).asType();
548548
TypeMirror serializableType = annotationHelper.typeElementFromQualifiedName("java.io.Serializable").asType();
549-
if (!annotationHelper.isSubtype(typeMirror, parcelableType) && !annotationHelper.isSubtype(typeMirror, serializableType)) {
550-
valid.addError("Unrecognized type. Please let your attribute be primitive or implement Serializable or Parcelable");
549+
if (!annotationHelper.isSubtype(typeMirror, parcelableType)
550+
&& !annotationHelper.isSubtype(typeMirror, serializableType)
551+
&& !annotationHelper.isParcelType(typeMirror)) {
552+
valid.addError("Unrecognized type. Please let your attribute be primitive or implement Serializable or Parcelable or an annotated Parceler bean.");
551553
}
552554
}
553555
}

‎AndroidAnnotations/androidannotations-core/androidannotations/src/main/java/org/androidannotations/internal/core/handler/FragmentArgHandler.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ private void createBuilderInjectionMethod(Element element, EFragmentHolder holde
107107

108108
JMethod method = builderClass.method(PUBLIC, holder.narrow(builderClass), fieldName);
109109
JVar arg = method.param(paramClass, fieldName);
110-
method.body().invoke(builderArgsField, bundleHelper.getMethodNameToSave()).arg(argKeyStaticField).arg(arg);
110+
method.body().add(bundleHelper.getExpressionToSaveFromField(builderArgsField, argKeyStaticField, arg));
111111
method.body()._return(_this());
112112

113113
String docComment = getProcessingEnvironment().getElementUtils().getDocComment(element);

0 commit comments

Comments
 (0)