Introducing the SkipAssetOptionsStrategy class, used to avoid falling into an infinite loop while deserializing/serializing results from the get_relative_account_history API call

develop
Nelson R. Perez 2018-06-11 23:48:35 -05:00
parent 7582fefd0e
commit 4f6b628891
3 changed files with 88 additions and 51 deletions

View File

@ -10,6 +10,7 @@ import java.util.List;
import cy.agorise.graphenej.AccountOptions;
import cy.agorise.graphenej.AssetAmount;
import cy.agorise.graphenej.AssetOptions;
import cy.agorise.graphenej.Authority;
import cy.agorise.graphenej.Transaction;
import cy.agorise.graphenej.api.calls.GetAccounts;
@ -51,7 +52,7 @@ public class DeserializationMap {
// GetAccounts
mClassMap.put(GetAccounts.class, List.class);
Gson getAccountsGson = new GsonBuilder()
.setExclusionStrategies(new GetAccountsExclusionStrategy())
.setExclusionStrategies(new SkipAccountOptionsStrategy())
.registerTypeAdapter(Authority.class, new Authority.AuthorityDeserializer())
.registerTypeAdapter(AccountOptions.class, new AccountOptions.AccountOptionsDeserializer())
.create();
@ -64,9 +65,10 @@ public class DeserializationMap {
.create();
mGsonMap.put(GetRequiredFees.class, getRequiredFeesGson);
// GetRelativeAccounthistory
// GetRelativeAccountHistory
mClassMap.put(GetRelativeAccountHistory.class, List.class);
Gson getRelativeAcountHistoryGson = new GsonBuilder()
.setExclusionStrategies(new SkipAccountOptionsStrategy(), new SkipAssetOptionsStrategy())
.registerTypeAdapter(OperationHistory.class, new OperationHistory.OperationHistoryDeserializer())
.registerTypeAdapter(TransferOperation.class, new TransferOperation.TransferDeserializer())
.registerTypeAdapter(AssetAmount.class, new AssetAmount.AssetAmountDeserializer())
@ -88,7 +90,7 @@ public class DeserializationMap {
* This class is required in order to break a recursion loop when de-serializing the
* AccountProperties class instance.
*/
private class GetAccountsExclusionStrategy implements ExclusionStrategy {
public static class SkipAccountOptionsStrategy implements ExclusionStrategy {
@Override
public boolean shouldSkipField(FieldAttributes f) {
@ -100,4 +102,21 @@ public class DeserializationMap {
return clazz == AccountOptions.class;
}
}
/**
* This class is required in order to break a recursion loop when de-serializing the
* AssetAmount instance.
*/
public static class SkipAssetOptionsStrategy implements ExclusionStrategy {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return false;
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return clazz == AssetOptions.class;
}
}
}

View File

@ -32,7 +32,6 @@ import cy.agorise.graphenej.interfaces.JsonSerializable;
* {@url https://bitshares.org/doxygen/structgraphene_1_1chain_1_1memo__data.html}
*/
public class Memo implements ByteSerializable, JsonSerializable {
public final static String TAG = "Memo";
public static final String KEY_FROM = "from";
public static final String KEY_TO = "to";
public static final String KEY_NONCE = "nonce";
@ -291,13 +290,15 @@ public class Memo implements ByteSerializable, JsonSerializable {
memoObject.addProperty(KEY_FROM, "");
memoObject.addProperty(KEY_TO, "");
memoObject.addProperty(KEY_NONCE, "");
memoObject.addProperty(KEY_MESSAGE, Util.bytesToHex(this.message));
if(this.message != null)
memoObject.addProperty(KEY_MESSAGE, Util.bytesToHex(this.message));
return null;
}else{
memoObject.addProperty(KEY_FROM, this.from.toString());
memoObject.addProperty(KEY_TO, this.to.toString());
memoObject.addProperty(KEY_NONCE, String.format("%x", this.nonce));
memoObject.addProperty(KEY_MESSAGE, Util.bytesToHex(this.message));
if(this.message != null)
memoObject.addProperty(KEY_MESSAGE, Util.bytesToHex(this.message));
}
return memoObject;
}
@ -310,8 +311,9 @@ public class Memo implements ByteSerializable, JsonSerializable {
*/
public JsonElement toJson(boolean decimal){
JsonElement jsonElement = toJsonObject();
if(decimal){
if(decimal && jsonElement != null){
JsonObject jsonObject = (JsonObject) jsonElement;
// The nonce is interpreted in base 16, but it is going to be written in base 10
BigInteger nonce = new BigInteger(jsonObject.get(KEY_NONCE).getAsString(), 16);
jsonObject.addProperty(KEY_NONCE, nonce.toString());
}

View File

@ -9,7 +9,7 @@
android:id="@+id/output_text_container"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/container_get_accounts_call"
app:layout_constraintBottom_toTopOf="@+id/container_controls"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
@ -18,52 +18,68 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ScrollView>
<LinearLayout
android:id="@+id/container_get_accounts_call"
<ScrollView
android:id="@+id/container_controls"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
app:layout_constraintBottom_toTopOf="@+id/container_get_block_call"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/output_text_container">
<Button
android:id="@+id/call_get_accounts"
android:layout_width="wrap_content"
app:layout_constraintTop_toBottomOf="@id/output_text_container"
app:layout_constraintBottom_toTopOf="@+id/next_activity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Get accounts"
app:layout_constraintBottom_toTopOf="@+id/next_activity"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/container_get_block_call" />
<EditText
android:id="@+id/argument_get_accounts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1.2.139205"/>
</LinearLayout>
<LinearLayout
android:id="@+id/container_get_block_call"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
app:layout_constraintBottom_toTopOf="@+id/next_activity"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/container_get_accounts_call">
<Button
android:id="@+id/call_get_block"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get block"/>
<EditText
android:id="@+id/argument_get_block"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="100000"/>
</LinearLayout>
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
<Button
android:id="@+id/call_get_accounts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get accounts" />
<EditText
android:id="@+id/argument_get_accounts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1.2.139205"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
<Button
android:id="@+id/call_get_block"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get block"/>
<EditText
android:id="@+id/argument_get_block"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="100000"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
<Button
android:id="@+id/call_get_relative_account_history"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get relative account history"/>
<EditText
android:id="@+id/argument_get_relative_account_history"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1.2.138632"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
<Button
android:id="@+id/next_activity"
android:layout_width="wrap_content"
@ -72,7 +88,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/container_get_block_call" />
app:layout_constraintTop_toBottomOf="@id/container_controls" />
<TextView
android:id="@+id/connection_status"
android:layout_width="match_parent"