package org.ripple.power; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; import org.json.JSONObject; import org.ripple.power.RippleSchemas.BinaryFormatField; import org.ripple.power.RippleSchemas.PrimitiveTypes; import org.ripple.power.RippleSchemas.TransactionTypes; public class RippleObject { HashMap<BinaryFormatField, Object> fields = new HashMap<BinaryFormatField, Object>(); private static RippleSerializer binSer = new RippleSerializer(); public RippleObject() { } public RippleObject(RippleObject serObjToSign) { this.fields.putAll(serObjToSign.fields); } public RippleObject getUnsignedCopy() { RippleObject copy = new RippleObject(this); copy.removeField(BinaryFormatField.TxnSignature); return copy; } public byte[] generateHashFromBinaryObject() { byte[] bytesToSign = binSer.writeBinaryObject(this).array(); byte[] prefixedBytesToHash = new byte[bytesToSign.length + 4]; prefixedBytesToHash[0] = (byte) 'S'; prefixedBytesToHash[1] = (byte) 'T'; prefixedBytesToHash[2] = (byte) 'X'; prefixedBytesToHash[3] = (byte) 0; System.arraycopy(bytesToSign, 0, prefixedBytesToHash, 4, bytesToSign.length); byte[] hashOfBytes = Helper.halfSHA512(prefixedBytesToHash); return hashOfBytes; } public byte[] getTransactionHash() { byte[] signedBytes = binSer.writeBinaryObject(this).array(); byte[] prefixedSignedBytes = new byte[signedBytes.length + 4]; prefixedSignedBytes[0] = (byte) 'T'; prefixedSignedBytes[1] = (byte) 'X'; prefixedSignedBytes[2] = (byte) 'N'; prefixedSignedBytes[3] = (byte) 0; System.arraycopy(signedBytes, 0, prefixedSignedBytes, 4, signedBytes.length); byte[] hashOfTransaction = Helper.halfSHA512(prefixedSignedBytes); return hashOfTransaction; } public Object getField(BinaryFormatField transactiontype) { Object obj = fields.get(transactiontype); if (obj == null) { return null; } return obj; } public void putField(BinaryFormatField field, Object value) { fields.put(field, value); } public TransactionTypes getTransactionType() { Object txTypeObj = getField(BinaryFormatField.TransactionType); if (txTypeObj == null) { throw new NullPointerException("No transaction type field found"); } return TransactionTypes.fromType((int) txTypeObj); } public String toJSONString() { JSONObject root = new JSONObject(); for (Entry<BinaryFormatField, Object> field : fields.entrySet()) { PrimitiveTypes primitive = field.getKey().primitive; if (primitive == PrimitiveTypes.UINT8 || primitive == PrimitiveTypes.UINT16 || primitive == PrimitiveTypes.UINT32 || primitive == PrimitiveTypes.UINT64) { root.put(field.getKey().toString(), field.getValue()); } else { root.put(field.getKey().toString(), field.getValue().toString()); } } return root.toString(); } public List<BinaryFormatField> getSortedField() { ArrayList<BinaryFormatField> sortedFields = new ArrayList<BinaryFormatField>( fields.keySet()); Collections.sort(sortedFields); return sortedFields; } public Object removeField(BinaryFormatField fieldToBeRemoved) { return fields.remove(fieldToBeRemoved); } @Override public String toString() { return "RippleBinaryObject [fields=" + fields + "]"; } }