Adding support for optional decimal or hex representations of the memo's nonce value in the newly introduced toJson method. Also introducing a Serializer

This commit is contained in:
Nelson R. Perez 2017-11-09 23:52:50 -05:00
parent c2287f5410
commit 394ed4b3b0
2 changed files with 61 additions and 11 deletions

View file

@ -1,11 +1,14 @@
package cy.agorise.graphenej.objects;
import com.google.common.primitives.Bytes;
import com.google.gson.Gson;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import org.bitcoinj.core.ECKey;
import org.spongycastle.math.ec.ECPoint;
@ -259,21 +262,36 @@ public class Memo implements ByteSerializable, JsonSerializable {
}
}
/**
* Converts a memo instance to a String.
*
* The nonce is always encoded as a decimal number in a string field.
* @return
*/
@Override
public String toJsonString() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
Gson gson = new Gson();
return gson.toJson(toJson(true));
}
/**
* Converts a memo instance into a JsonElement.
*
* This method differs from the {@link #toJson(boolean)} in that here the nonce is encoded as an
* hexadecimal number, while in that one we offer the user to choose either the decimal or hexadecimal
* representations.
*
* @return JsonObject instance representing this memo
*/
@Override
public JsonElement toJsonObject() {
JsonObject memoObject = new JsonObject();
if ((this.from == null) && (this.to == null)) {
// Public memo
// TODO: Add public memo support
// memoObject.addProperty(KEY_FROM, "");
// memoObject.addProperty(KEY_TO, "");
// memoObject.addProperty(KEY_NONCE, "");
// memoObject.addProperty(KEY_MESSAGE, Util.bytesToHex(this.message));
// TODO: Check if this public memo serialization is accepted
memoObject.addProperty(KEY_FROM, "");
memoObject.addProperty(KEY_TO, "");
memoObject.addProperty(KEY_NONCE, "");
memoObject.addProperty(KEY_MESSAGE, Util.bytesToHex(this.message));
return null;
}else{
memoObject.addProperty(KEY_FROM, this.from.toString());
@ -284,6 +302,22 @@ public class Memo implements ByteSerializable, JsonSerializable {
return memoObject;
}
/**
* Method that converts the memo into a JsonObject.
*
* @param decimal If true, the nonce is saved as string containing a decimal number representation.
* @return JsonObject instance representing this memo
*/
public JsonElement toJson(boolean decimal){
JsonElement jsonElement = toJsonObject();
if(decimal){
JsonObject jsonObject = (JsonObject) jsonElement;
BigInteger nonce = new BigInteger(jsonObject.get(KEY_NONCE).getAsString(), 16);
jsonObject.addProperty(KEY_NONCE, nonce.toString());
}
return jsonElement;
}
/**
* Class used to deserialize a memo
*/
@ -314,4 +348,15 @@ public class Memo implements ByteSerializable, JsonSerializable {
return memo;
}
}
/**
* Class used to serialize a memo
*/
public static class MemoSerializer implements JsonSerializer<Memo> {
@Override
public JsonElement serialize(Memo memo, Type typeOfSrc, JsonSerializationContext context) {
return memo.toJson(true);
}
}
}

View file

@ -13,8 +13,8 @@ import org.junit.Test;
import java.math.BigInteger;
import cy.agorise.graphenej.Address;
import cy.agorise.graphenej.TestAccounts;
import cy.agorise.graphenej.PublicKey;
import cy.agorise.graphenej.TestAccounts;
import cy.agorise.graphenej.Util;
import cy.agorise.graphenej.errors.ChecksumException;
@ -149,11 +149,16 @@ public class MemoTest {
@Test
public void shouldDeserializeFromString(){
String jsonMemo = "{\"from\":\"BTS6nB7gw1EawYXRofLvuivLsboVmh2inXroQgSQqYfAc5Bamk4Vq\",\"to\":\"BTS4xAQGg2ePLeDGZvQFpsh9CjMhQvRnVkPp6jPoE6neVPotRfZX9\",\"nonce\":\"8000000000000000\",\"message\":\"b9aeb7632f1f4281eedcf28a684828a42d02de71254fb88e13ddcb9a79adf51d9770c58d7e7efcdbb1515f1136c3be3e\"}";
GsonBuilder gsonBuilder = new GsonBuilder().registerTypeAdapter(Memo.class, new Memo.MemoDeserializer());
GsonBuilder gsonBuilder = new GsonBuilder()
.registerTypeAdapter(Memo.class, new Memo.MemoSerializer())
.registerTypeAdapter(Memo.class, new Memo.MemoDeserializer());
Memo memo = gsonBuilder.create().fromJson(jsonMemo, Memo.class);
Assert.assertEquals("Source address should match the serialized one", "BTS6nB7gw1EawYXRofLvuivLsboVmh2inXroQgSQqYfAc5Bamk4Vq", memo.getSource().toString());
Assert.assertEquals("Destination address should match the serialized one", "BTS4xAQGg2ePLeDGZvQFpsh9CjMhQvRnVkPp6jPoE6neVPotRfZX9", memo.getDestination().toString());
Assert.assertEquals("Nonce should match serialized one", new BigInteger("8000000000000000", 10), memo.getNonce());
Assert.assertArrayEquals(Util.hexToBytes("b9aeb7632f1f4281eedcf28a684828a42d02de71254fb88e13ddcb9a79adf51d9770c58d7e7efcdbb1515f1136c3be3e"), memo.getByteMessage());
String json = gsonBuilder.create().toJson(memo);
Assert.assertEquals("Serialized memo matches the original one", jsonMemo, json);
}
}