graphenej/graphenej/src/main/java/cy/agorise/graphenej/operations/TransferOperation.java

206 lines
7.0 KiB
Java
Raw Normal View History

2017-10-02 19:34:50 +00:00
package cy.agorise.graphenej.operations;
2016-11-21 17:50:30 +00:00
import com.google.common.primitives.Bytes;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
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 java.lang.reflect.Type;
2017-10-02 19:34:50 +00:00
import cy.agorise.graphenej.AssetAmount;
import cy.agorise.graphenej.BaseOperation;
import cy.agorise.graphenej.OperationType;
import cy.agorise.graphenej.UserAccount;
2018-09-17 17:19:22 +00:00
import cy.agorise.graphenej.Memo;
2016-11-21 17:50:30 +00:00
/**
2016-12-02 21:24:42 +00:00
* Class used to encapsulate the TransferOperation operation related functionalities.
2016-11-21 17:50:30 +00:00
*/
2016-12-02 21:24:42 +00:00
public class TransferOperation extends BaseOperation {
public static final String KEY_AMOUNT = "amount";
public static final String KEY_FROM = "from";
public static final String KEY_TO = "to";
2016-12-09 02:27:20 +00:00
public static final String KEY_MEMO = "memo";
2016-11-21 17:50:30 +00:00
2016-12-02 21:24:42 +00:00
private AssetAmount fee;
private AssetAmount amount;
private UserAccount from;
private UserAccount to;
private Memo memo;
2016-11-21 17:50:30 +00:00
2016-12-02 21:24:42 +00:00
public TransferOperation(UserAccount from, UserAccount to, AssetAmount transferAmount, AssetAmount fee){
super(OperationType.TRANSFER_OPERATION);
2016-12-02 21:24:42 +00:00
this.from = from;
this.to = to;
this.amount = transferAmount;
this.fee = fee;
this.memo = new Memo();
2016-11-21 17:50:30 +00:00
}
2016-12-02 21:24:42 +00:00
public TransferOperation(UserAccount from, UserAccount to, AssetAmount transferAmount){
super(OperationType.TRANSFER_OPERATION);
2016-12-02 21:24:42 +00:00
this.from = from;
this.to = to;
this.amount = transferAmount;
this.memo = new Memo();
2016-11-21 17:50:30 +00:00
}
2016-12-02 21:24:42 +00:00
public UserAccount getFrom(){
return this.from;
}
2016-11-21 17:50:30 +00:00
2016-12-02 21:24:42 +00:00
public UserAccount getTo(){
return this.to;
}
2016-11-21 17:50:30 +00:00
public AssetAmount getAssetAmount(){
2016-12-02 21:24:42 +00:00
return this.amount;
}
2016-11-21 17:50:30 +00:00
2016-12-02 21:24:42 +00:00
public AssetAmount getFee(){
return this.fee;
}
2016-11-21 17:50:30 +00:00
2017-02-23 04:05:14 +00:00
public void setAssetAmount(AssetAmount assetAmount){
this.amount = assetAmount;
}
public void setFrom(UserAccount from) {
this.from = from;
}
public void setTo(UserAccount to) {
this.to = to;
}
public void setMemo(Memo memo) {
this.memo = memo;
}
public Memo getMemo() {
return this.memo;
}
2017-02-23 04:05:14 +00:00
@Override
public void setFee(AssetAmount newFee){
this.fee = newFee;
}
2016-12-02 21:24:42 +00:00
@Override
public byte[] toBytes() {
byte[] feeBytes = fee.toBytes();
byte[] fromBytes = from.toBytes();
byte[] toBytes = to.toBytes();
byte[] amountBytes = amount.toBytes();
byte[] memoBytes = memo.toBytes();
byte[] extensions = this.extensions.toBytes();
return Bytes.concat(feeBytes, fromBytes, toBytes, amountBytes, memoBytes, extensions);
2016-11-21 17:50:30 +00:00
}
@Override
public String toJsonString() {
//TODO: Evaluate using simple Gson class to return a simple string representation and drop the TransferSerializer class
2016-11-21 17:50:30 +00:00
GsonBuilder gsonBuilder = new GsonBuilder();
2016-12-02 21:24:42 +00:00
gsonBuilder.registerTypeAdapter(TransferOperation.class, new TransferSerializer());
2016-11-21 17:50:30 +00:00
return gsonBuilder.create().toJson(this);
}
@Override
2016-12-02 21:24:42 +00:00
public JsonElement toJsonObject() {
JsonArray array = new JsonArray();
array.add(this.getId());
JsonObject jsonObject = new JsonObject();
if(fee != null)
jsonObject.add(KEY_FEE, fee.toJsonObject());
jsonObject.addProperty(KEY_FROM, from.getObjectId());
jsonObject.addProperty(KEY_TO, to.getObjectId());
jsonObject.add(KEY_AMOUNT, amount.toJsonObject());
if(memo.getByteMessage() != null)
jsonObject.add(KEY_MEMO, memo.toJsonObject());
jsonObject.add(KEY_EXTENSIONS, new JsonArray());
2016-12-02 21:24:42 +00:00
array.add(jsonObject);
return array;
}
2016-11-21 17:50:30 +00:00
/**
* Serializer used to convert this object into a {@link JsonElement} instance
*/
2016-12-02 21:24:42 +00:00
public static class TransferSerializer implements JsonSerializer<TransferOperation> {
2016-11-21 17:50:30 +00:00
2016-12-02 21:24:42 +00:00
@Override
public JsonElement serialize(TransferOperation transfer, Type type, JsonSerializationContext jsonSerializationContext) {
return transfer.toJsonObject();
2016-11-21 17:50:30 +00:00
}
}
2016-12-02 21:24:42 +00:00
/**
* This deserializer will work on any transfer operation serialized in the 'array form' used a lot in
* the Graphene Blockchain API.
*
* An example of this serialized form is the following:
*
* [
* 0,
* {
* "fee": {
* "amount": 264174,
* "asset_id": "1.3.0"
* },
* "from": "1.2.138632",
* "to": "1.2.129848",
* "amount": {
* "amount": 100,
* "asset_id": "1.3.0"
* },
* "extensions": []
* }
* ]
*
* It will convert this data into a nice TransferOperation object.
*/
public static class TransferDeserializer implements JsonDeserializer<TransferOperation> {
2016-11-21 17:50:30 +00:00
@Override
2016-12-02 21:24:42 +00:00
public TransferOperation deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if(json.isJsonArray()){
// This block is used just to check if we are in the first step of the deserialization
// when we are dealing with an array.
JsonArray serializedTransfer = json.getAsJsonArray();
if(serializedTransfer.get(0).getAsInt() != OperationType.TRANSFER_OPERATION.ordinal()){
2016-12-02 21:24:42 +00:00
// If the operation type does not correspond to a transfer operation, we return null
return null;
}else{
// Calling itself recursively, this is only done once, so there will be no problems.
return context.deserialize(serializedTransfer.get(1), TransferOperation.class);
}
}else{
// This block is called in the second recursion and takes care of deserializing the
// transfer data itself.
JsonObject jsonObject = json.getAsJsonObject();
// Deserializing AssetAmount objects
AssetAmount amount = context.deserialize(jsonObject.get(KEY_AMOUNT), AssetAmount.class);
AssetAmount fee = context.deserialize(jsonObject.get(KEY_FEE), AssetAmount.class);
2016-12-02 21:24:42 +00:00
// Deserializing UserAccount objects
UserAccount from = new UserAccount(jsonObject.get(KEY_FROM).getAsString());
UserAccount to = new UserAccount(jsonObject.get(KEY_TO).getAsString());
2016-12-02 21:24:42 +00:00
TransferOperation transfer = new TransferOperation(from, to, amount, fee);
2017-09-26 03:53:30 +00:00
// If the transfer had a memo, deserialize it
if(jsonObject.has(KEY_MEMO)){
Memo memo = context.deserialize(jsonObject.get(KEY_MEMO), Memo.class);
transfer.setMemo(memo);
}
2016-12-02 21:24:42 +00:00
return transfer;
}
2016-11-21 17:50:30 +00:00
}
}
2016-12-02 21:24:42 +00:00
}