From c773926ef7d54d6f0f21cfe17e8bb3ba98bd616e Mon Sep 17 00:00:00 2001 From: "Nelson R. Perez" Date: Tue, 9 Oct 2018 18:54:41 -0500 Subject: [PATCH] Givingh the AccountOptionsDeserializer class more control over when it should de-serialize its UserAccount attribute and when it should skip it in order to prevent infinite recursion loops --- .../cy/agorise/graphenej/AccountOptions.java | 46 ++++++++++++++++++- .../api/android/DeserializationMap.java | 3 +- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/graphenej/src/main/java/cy/agorise/graphenej/AccountOptions.java b/graphenej/src/main/java/cy/agorise/graphenej/AccountOptions.java index 3a58cab..f32f800 100644 --- a/graphenej/src/main/java/cy/agorise/graphenej/AccountOptions.java +++ b/graphenej/src/main/java/cy/agorise/graphenej/AccountOptions.java @@ -33,17 +33,51 @@ public class AccountOptions implements GrapheneSerializable { private Vote[] votes; private Extensions extensions; + /** + * Constructor used to instantiate only the following attributes: + * + */ public AccountOptions(){ voting_account = new UserAccount(UserAccount.PROXY_TO_SELF); this.votes = new Vote[0]; this.extensions = new Extensions(); } + /** + * Constructor used to instantiate only the following attributes: + * + */ public AccountOptions(PublicKey memoKey){ this(); this.memo_key = memoKey; } + /** + * Constructor that can be used to instantiate a version of the AccountOptions object + * with a null reference in the 'voting_account' attribute. This can be used to prevent + * a circular dependency situation when de-serializing the UserAccount instance. + * + * @param memoKey Memo public key used by this account + * @param includeAccount Whether or not to instantiate an UserAccount + */ + public AccountOptions(PublicKey memoKey, boolean includeAccount){ + if(includeAccount){ + voting_account = new UserAccount(UserAccount.PROXY_TO_SELF); + } + this.memo_key = memoKey; + this.votes = new Vote[0]; + this.extensions = new Extensions(); + } + //TODO: Implement constructor that takes a Vote array. public PublicKey getMemoKey() { @@ -149,13 +183,23 @@ public class AccountOptions implements GrapheneSerializable { */ public static class AccountOptionsDeserializer implements JsonDeserializer { + boolean mIncludeUserAccount; + + public AccountOptionsDeserializer(){ + this.mIncludeUserAccount = true; + } + + public AccountOptionsDeserializer(boolean includeUserAccount){ + this.mIncludeUserAccount = includeUserAccount; + } + @Override public AccountOptions deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject baseObject = json.getAsJsonObject(); AccountOptions options; try { Address address = new Address(baseObject.get(KEY_MEMO_KEY).getAsString()); - options = new AccountOptions(address.getPublicKey()); + options = new AccountOptions(address.getPublicKey(), mIncludeUserAccount); } catch (MalformedAddressException e) { System.out.println("MalformedAddressException. Msg: "+e.getMessage()); options = new AccountOptions(); diff --git a/graphenej/src/main/java/cy/agorise/graphenej/api/android/DeserializationMap.java b/graphenej/src/main/java/cy/agorise/graphenej/api/android/DeserializationMap.java index c1bf4d6..1c36f8a 100644 --- a/graphenej/src/main/java/cy/agorise/graphenej/api/android/DeserializationMap.java +++ b/graphenej/src/main/java/cy/agorise/graphenej/api/android/DeserializationMap.java @@ -76,9 +76,8 @@ public class DeserializationMap { // GetAccounts mClassMap.put(GetAccounts.class, List.class); Gson getAccountsGson = new GsonBuilder() - .setExclusionStrategies(new SkipAccountOptionsStrategy()) .registerTypeAdapter(Authority.class, new Authority.AuthorityDeserializer()) - .registerTypeAdapter(AccountOptions.class, new AccountOptions.AccountOptionsDeserializer()) + .registerTypeAdapter(AccountOptions.class, new AccountOptions.AccountOptionsDeserializer(false)) .create(); mGsonMap.put(GetAccounts.class, getAccountsGson);