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

This commit is contained in:
Nelson R. Perez 2018-10-09 18:54:41 -05:00
parent b361cf5830
commit c773926ef7
2 changed files with 46 additions and 3 deletions

View file

@ -33,17 +33,51 @@ public class AccountOptions implements GrapheneSerializable {
private Vote[] votes; private Vote[] votes;
private Extensions extensions; private Extensions extensions;
/**
* Constructor used to instantiate only the following attributes:
* <ul>
* <li>voting_account</li>
* <li>votes</li>
* <li>extensions</li>
* </ul>
*/
public AccountOptions(){ public AccountOptions(){
voting_account = new UserAccount(UserAccount.PROXY_TO_SELF); voting_account = new UserAccount(UserAccount.PROXY_TO_SELF);
this.votes = new Vote[0]; this.votes = new Vote[0];
this.extensions = new Extensions(); this.extensions = new Extensions();
} }
/**
* Constructor used to instantiate only the following attributes:
* <ul>
* <li>voting_account</li>
* <li>votes</li>
* <li>memo_key</li>
* <li>extensions</li>
* </ul>
*/
public AccountOptions(PublicKey memoKey){ public AccountOptions(PublicKey memoKey){
this(); this();
this.memo_key = memoKey; 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. //TODO: Implement constructor that takes a Vote array.
public PublicKey getMemoKey() { public PublicKey getMemoKey() {
@ -149,13 +183,23 @@ public class AccountOptions implements GrapheneSerializable {
*/ */
public static class AccountOptionsDeserializer implements JsonDeserializer<AccountOptions> { public static class AccountOptionsDeserializer implements JsonDeserializer<AccountOptions> {
boolean mIncludeUserAccount;
public AccountOptionsDeserializer(){
this.mIncludeUserAccount = true;
}
public AccountOptionsDeserializer(boolean includeUserAccount){
this.mIncludeUserAccount = includeUserAccount;
}
@Override @Override
public AccountOptions deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { public AccountOptions deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject baseObject = json.getAsJsonObject(); JsonObject baseObject = json.getAsJsonObject();
AccountOptions options; AccountOptions options;
try { try {
Address address = new Address(baseObject.get(KEY_MEMO_KEY).getAsString()); Address address = new Address(baseObject.get(KEY_MEMO_KEY).getAsString());
options = new AccountOptions(address.getPublicKey()); options = new AccountOptions(address.getPublicKey(), mIncludeUserAccount);
} catch (MalformedAddressException e) { } catch (MalformedAddressException e) {
System.out.println("MalformedAddressException. Msg: "+e.getMessage()); System.out.println("MalformedAddressException. Msg: "+e.getMessage());
options = new AccountOptions(); options = new AccountOptions();

View file

@ -76,9 +76,8 @@ public class DeserializationMap {
// GetAccounts // GetAccounts
mClassMap.put(GetAccounts.class, List.class); mClassMap.put(GetAccounts.class, List.class);
Gson getAccountsGson = new GsonBuilder() Gson getAccountsGson = new GsonBuilder()
.setExclusionStrategies(new SkipAccountOptionsStrategy())
.registerTypeAdapter(Authority.class, new Authority.AuthorityDeserializer()) .registerTypeAdapter(Authority.class, new Authority.AuthorityDeserializer())
.registerTypeAdapter(AccountOptions.class, new AccountOptions.AccountOptionsDeserializer()) .registerTypeAdapter(AccountOptions.class, new AccountOptions.AccountOptionsDeserializer(false))
.create(); .create();
mGsonMap.put(GetAccounts.class, getAccountsGson); mGsonMap.put(GetAccounts.class, getAccountsGson);