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

Commit

Permalink
Fix for getParcelableArray ClassCastException
Browse files Browse the repository at this point in the history
  • Loading branch information
WonderCsabo committed Mar 22, 2015
1 parent e608029 commit c2136c8
Show file tree
Hide file tree
Showing 18 changed files with 199 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ private void injectExtraInComponent(Element element, HasExtras hasExtras, JField
JExpression intent = invoke("getIntent");
JBlock ifContainsKey = injectExtrasBlock._if(JExpr.invoke(extras, "containsKey").arg(extraKeyStaticField))._then();

JExpression restoreMethodCall = bundleHelper.getExpressionToRestoreFromIntentOrBundle(elementClass, intent, extras, extraKeyStaticField, injectExtrasMethod);
JExpression restoreMethodCall = bundleHelper.getExpressionToRestoreFromIntentOrBundle(elementClass, intent, extras, extraKeyStaticField, injectExtrasMethod, hasExtras);
ifContainsKey.assign(extraField, restoreMethodCall);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.androidannotations.helper.BundleHelper;
import org.androidannotations.helper.CaseHelper;
import org.androidannotations.holder.GeneratedClassHolder;
import org.androidannotations.holder.HasBundleExtraction;
import org.androidannotations.model.AnnotationElements;
import org.androidannotations.process.IsValid;

Expand Down Expand Up @@ -80,7 +81,7 @@ public JExpression getExtraValue(VariableElement parameter, JVar intent, JVar ex
}

BundleHelper bundleHelper = new BundleHelper(annotationHelper, parameter.asType());
JExpression restoreMethodCall = bundleHelper.getExpressionToRestoreFromIntentOrBundle(parameterClass, intent, extras, getStaticExtraField(generatedClass, extraKey, holder), annotatedMethod);
JExpression restoreMethodCall = bundleHelper.getExpressionToRestoreFromIntentOrBundle(parameterClass, intent, extras, getStaticExtraField(generatedClass, extraKey, holder), annotatedMethod, (HasBundleExtraction) holder);

return block.decl(parameterClass, parameterName, restoreMethodCall);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ private void injectArgInComponent(Element element, EFragmentHolder holder, Bundl
JFieldRef extraField = JExpr.ref(fieldName);

JBlock ifContainsKey = injectExtrasBlock._if(JExpr.invoke(bundle, "containsKey").arg(extraKeyStaticField))._then();
JExpression restoreMethodCall = bundleHelper.getExpressionToRestoreFromBundle(elementClass, bundle, extraKeyStaticField, injectExtrasMethod);
JExpression restoreMethodCall = bundleHelper.getExpressionToRestoreFromBundle(elementClass, bundle, extraKeyStaticField, injectExtrasMethod, holder);
ifContainsKey.assign(extraField, restoreMethodCall);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public void process(Element element, HasInstanceState holder) {
JFieldRef ref = ref(fieldName);
saveStateBody.invoke(saveStateBundleParam, bundleHelper.getMethodNameToSave()).arg(fieldName).arg(ref);

JExpression restoreMethodCall = bundleHelper.getExpressionToRestoreFromBundle(elementClass, restoreStateBundleParam, JExpr.lit(fieldName), restoreStateMethod);
JExpression restoreMethodCall = bundleHelper.getExpressionToRestoreFromBundle(elementClass, restoreStateBundleParam, JExpr.lit(fieldName), restoreStateMethod, holder);
restoreStateBody.assign(ref, restoreMethodCall);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ private void addActionInOnHandleIntent(EIntentServiceHolder holder, ExecutableEl
JClass extraParamClass = codeModelHelper.typeMirrorToJClass(param.asType(), holder);

BundleHelper bundleHelper = new BundleHelper(annotationHelper, param.asType());
JExpression getExtraExpression = bundleHelper.getExpressionToRestoreFromIntentOrBundle(extraParamClass, intent, extras, paramVar, onHandleIntentMethod);
JExpression getExtraExpression = bundleHelper.getExpressionToRestoreFromIntentOrBundle(extraParamClass, intent, extras, paramVar, onHandleIntentMethod, holder);

JVar extraField = callActionBlock.decl(extraParamClass, extraParamName, getExtraExpression);
callActionInvocation.arg(extraField);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;

import org.androidannotations.holder.HasBundleExtraction;

import com.sun.codemodel.JClass;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JExpression;
Expand Down Expand Up @@ -207,16 +209,23 @@ private boolean isTypeParcelable(TypeElement elementType) {
return elementType != null && annotationHelper.isSubtype(elementType, parcelableType);
}

public JExpression getExpressionToRestoreFromIntentOrBundle(JClass variableClass, JExpression intent, JExpression extras, JExpression extraKey, JMethod method) {
public JExpression getExpressionToRestoreFromIntentOrBundle(JClass variableClass, JExpression intent, JExpression extras, JExpression extraKey, JMethod method, HasBundleExtraction bundleExtractionHolder) {
if ("byte[]".equals(element.toString())) {
return intent.invoke("getByteArrayExtra").arg(extraKey);
} else {
return getExpressionToRestoreFromBundle(variableClass, extras, extraKey, method);
return getExpressionToRestoreFromBundle(variableClass, extras, extraKey, method, bundleExtractionHolder);
}
}

public JExpression getExpressionToRestoreFromBundle(JClass variableClass, JExpression bundle, JExpression extraKey, JMethod method) {
JExpression expressionToRestore = JExpr.invoke(bundle, methodNameToRestore).arg(extraKey);
public JExpression getExpressionToRestoreFromBundle(JClass variableClass, JExpression bundle, JExpression extraKey, JMethod method, HasBundleExtraction bundleExtractionHolder) {
JExpression expressionToRestore;
if (methodNameToRestore.equals("getParcelableArray")) {
JClass erasure = variableClass.elementType().erasure().array();
expressionToRestore = JExpr.invoke(bundleExtractionHolder.getGetParcelableArrayMethod()).arg(bundle).arg(extraKey).arg(erasure.dotclass());
} else {
expressionToRestore = JExpr.invoke(bundle, methodNameToRestore).arg(extraKey);
}

if (restoreCallNeedCastStatement()) {
expressionToRestore = JExpr.cast(variableClass, expressionToRestore);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/**
* Copyright (C) 2010-2014 eBusiness Information, Excilys Group
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed To in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.androidannotations.holder;

import static com.sun.codemodel.JExpr._null;
import static com.sun.codemodel.JExpr.cast;
import static com.sun.codemodel.JExpr.invoke;
import static com.sun.codemodel.JExpr.lit;
import static com.sun.codemodel.JMod.PRIVATE;

import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.TypeElement;

import org.androidannotations.process.ProcessHolder.Classes;

import com.sun.codemodel.JBlock;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JVar;

public class BundleExtractionHolder implements HasBundleExtraction {

protected EComponentHolder holder;

public BundleExtractionHolder(EComponentHolder holder) {
this.holder = holder;
}

@Override
public JMethod getGetParcelableArrayMethod() {
JMethod method = getGeneratedClass().method(PRIVATE, classes().PARCELABLE.array(), "getParcelableArray");
JVar bundleParam = method.param(classes().BUNDLE, "bundle");
JVar keyParam = method.param(classes().STRING, "key");
JVar typeParam = method.param(classes().CLASS.narrow(classes().PARCELABLE.array().wildcard()), "type");

JBlock methodBody = method.body();

JVar valueVar = methodBody.decl(classes().PARCELABLE.array(), "value", invoke(bundleParam, "getParcelableArray").arg(keyParam));
methodBody._if(valueVar.eq(_null()))._then()._return(_null());
JVar copyVar = methodBody.decl(classes().OBJECT, "copy", classes().ARRAY.staticInvoke("newInstance").arg(typeParam.invoke("getComponentType")).arg(valueVar.ref("length")));
methodBody.staticInvoke(classes().SYSTEM, "arraycopy").arg(valueVar).arg(lit(0)).arg(copyVar).arg(lit(0)).arg(valueVar.ref("length"));
methodBody._return(cast(classes().PARCELABLE.array(), copyVar));

return method;
}

@Override
public JDefinedClass getGeneratedClass() {
return holder.getGeneratedClass();
}

@Override
public TypeElement getAnnotatedElement() {
return holder.getAnnotatedElement();
}

@Override
public ProcessingEnvironment processingEnvironment() {
return holder.processingEnvironment();
}

@Override
public Classes classes() {
return holder.classes();
}

@Override
public JCodeModel codeModel() {
return holder.codeModel();
}

@Override
public JClass refClass(String fullyQualifiedClassName) {
return holder.refClass(fullyQualifiedClassName);
}

@Override
public JClass refClass(Class<?> clazz) {
return holder.refClass(clazz);
}

@Override
public JDefinedClass definedClass(String fullyQualifiedClassName) {
return holder.definedClass(fullyQualifiedClassName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public class EActivityHolder extends EComponentWithViewSupportHolder implements
private JBlock onStartAfterSuperBlock;
private JBlock onStopBeforeSuperBlock;
private JBlock onPauseBeforeSuperBlock;
private JMethod getParcelableArray;

public EActivityHolder(ProcessHolder processHolder, TypeElement annotatedElement, AndroidManifest androidManifest) throws Exception {
super(processHolder, annotatedElement);
Expand Down Expand Up @@ -775,4 +776,12 @@ protected JFieldVar setDatabaseHelperRef(TypeMirror databaseHelperTypeMirror) {

return databaseHelperRef;
}

@Override
public JMethod getGetParcelableArrayMethod() {
if (getParcelableArray == null) {
getParcelableArray = instanceStateHolder.getGetParcelableArrayMethod();
}
return getParcelableArray;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
import com.sun.codemodel.JTypeVar;
import com.sun.codemodel.JVar;

public class EFragmentHolder extends EComponentWithViewSupportHolder implements HasInstanceState, HasOptionsMenu, HasOnActivityResult, HasReceiverRegistration {
public class EFragmentHolder extends EComponentWithViewSupportHolder implements HasInstanceState, HasOptionsMenu, HasOnActivityResult, HasReceiverRegistration, HasBundleExtraction {

private JFieldVar contentView;
private JBlock setContentViewBlock;
Expand Down Expand Up @@ -82,6 +82,7 @@ public class EFragmentHolder extends EComponentWithViewSupportHolder implements
private JBlock onPauseBeforeSuperBlock;
private JBlock onAttachAfterSuperBlock;
private JBlock onDetachBeforeSuperBlock;
private JMethod getParcelableArray;

public EFragmentHolder(ProcessHolder processHolder, TypeElement annotatedElement) throws Exception {
super(processHolder, annotatedElement);
Expand Down Expand Up @@ -563,4 +564,12 @@ protected JFieldVar setDatabaseHelperRef(TypeMirror databaseHelperTypeMirror) {

return databaseHelperRef;
}

@Override
public JMethod getGetParcelableArrayMethod() {
if (getParcelableArray == null) {
getParcelableArray = instanceStateHolder.getGetParcelableArrayMethod();
}
return getParcelableArray;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,19 @@
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JVar;

public class EIntentServiceHolder extends EServiceHolder {
public class EIntentServiceHolder extends EServiceHolder implements HasBundleExtraction {

private JVar onHandleIntentIntent;
private JMethod onHandleIntentMethod;
private JBlock onHandleIntentBody;
private JVar onHandleIntentIntentAction;
private JMethod getParcelableArray;

private BundleExtractionHolder bundleExtractionHolder;

public EIntentServiceHolder(ProcessHolder processHolder, TypeElement annotatedElement, AndroidManifest androidManifest) throws Exception {
super(processHolder, annotatedElement, androidManifest);
bundleExtractionHolder = new BundleExtractionHolder(this);
}

public JVar getOnHandleIntentIntent() {
Expand Down Expand Up @@ -76,4 +80,12 @@ private void createOnHandleIntent() {
JInvocation getActionInvocation = JExpr.invoke(onHandleIntentIntent, "getAction");
onHandleIntentIntentAction = onHandleIntentBody.decl(classes().STRING, "action", getActionInvocation);
}

@Override
public JMethod getGetParcelableArrayMethod() {
if (getParcelableArray == null) {
getParcelableArray = bundleExtractionHolder.getGetParcelableArrayMethod();
}
return getParcelableArray;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,22 @@
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JVar;

public class EReceiverHolder extends EComponentHolder {
public class EReceiverHolder extends EComponentHolder implements HasBundleExtraction {

private JBlock onReceiveBody;
private JVar onReceiveIntentAction;
private JVar onReceiveIntentDataScheme;
private JVar onReceiveIntent;
private JVar onReceiveContext;
private JMethod onReceiveMethod;
private JMethod getParcelableArray;

private BundleExtractionHolder bundleExtractionHolder;

public EReceiverHolder(ProcessHolder processHolder, TypeElement annotatedElement) throws Exception {
super(processHolder, annotatedElement);

bundleExtractionHolder = new BundleExtractionHolder(this);
}

@Override
Expand Down Expand Up @@ -118,4 +123,12 @@ public JVar getOnReceiveIntentDataScheme() {
}
return onReceiveIntentDataScheme;
}

@Override
public JMethod getGetParcelableArrayMethod() {
if (getParcelableArray == null) {
getParcelableArray = bundleExtractionHolder.getGetParcelableArrayMethod();
}
return getParcelableArray;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Copyright (C) 2010-2014 eBusiness Information, Excilys Group
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed To in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.androidannotations.holder;

import com.sun.codemodel.JMethod;

public interface HasBundleExtraction extends GeneratedClassHolder {

JMethod getGetParcelableArrayMethod();
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JVar;

public interface HasExtras extends GeneratedClassHolder {
public interface HasExtras extends HasBundleExtraction {
JMethod getInjectExtrasMethod();

JBlock getInjectExtrasBlock();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JVar;

public interface HasInstanceState extends GeneratedClassHolder {
public interface HasInstanceState extends HasBundleExtraction {
JBlock getSaveStateMethodBody();

JVar getSaveStateBundleParam();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JVar;

public interface HasOnActivityResult extends GeneratedClassHolder {
public interface HasOnActivityResult extends HasBundleExtraction {
JBlock getOnActivityResultCaseBlock(int requestCode);

JVar getOnActivityResultDataParam();
Expand Down

0 comments on commit c2136c8

Please sign in to comment.