diff --git a/src/main/java/org/stellar/base/Memo.java b/src/main/java/org/stellar/base/Memo.java index 0436914..c82225e 100644 --- a/src/main/java/org/stellar/base/Memo.java +++ b/src/main/java/org/stellar/base/Memo.java @@ -1,18 +1,11 @@ package org.stellar.base; -import com.google.common.base.Strings; import org.apache.commons.codec.DecoderException; -import org.apache.commons.codec.binary.Hex; -import org.stellar.base.xdr.MemoType; -import org.stellar.base.xdr.Uint64; - -import java.nio.charset.StandardCharsets; - -import static com.google.common.base.Preconditions.checkNotNull; /** *
The memo contains optional extra information. It is the responsibility of the client to interpret this value. Memos can be one of the following types:
*MEMO_NONE
: Empty memo.MEMO_TEXT
: A string up to 28-bytes long.MEMO_ID
: A 64 bit unsigned integer.MEMO_HASH
: A 32 byte hash.Use static methods to generate any of above types.
* @see Transaction */ -public class Memo { - Memo() { - } - +public abstract class Memo { /** - * Creates MEMO_NONE type memo. + * Creates new MemoNone instance. */ - public static org.stellar.base.xdr.Memo none() { - org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo(); - memo.setDiscriminant(MemoType.MEMO_NONE); - return memo; + public static MemoNone none() { + return new MemoNone(); } /** - * Creates MEMO_TEXT type memo. + * Creates new {@link MemoText} instance. * @param text */ - public static org.stellar.base.xdr.Memo text(String text) { - checkNotNull(text, "text cannot be null"); - - int length = text.getBytes((StandardCharsets.UTF_8)).length; - if (length > 28) { - throw new MemoTooLongException("text must be <= 28 bytes. length=" + String.valueOf(length)); - } - - org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo(); - memo.setDiscriminant(MemoType.MEMO_TEXT); - memo.setText(text); - return memo; + public static MemoText text(String text) { + return new MemoText(text); } /** - * Creates MEMO_ID type memo. + * Creates new {@link MemoId} instance. * @param id */ - public static org.stellar.base.xdr.Memo id(long id) { - org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo(); - memo.setDiscriminant(MemoType.MEMO_ID); - Uint64 idXdr = new Uint64(); - idXdr.setUint64(id); - memo.setId(idXdr); - return memo; + public static MemoId id(long id) { + return new MemoId(id); } /** - * Creates MEMO_HASH type memo from byte array. + * Creates new {@link MemoHash} instance from byte array. * @param bytes */ - public static org.stellar.base.xdr.Memo hash(byte[] bytes) { - org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo(); - memo.setDiscriminant(MemoType.MEMO_HASH); - - if (bytes.length < 32) { - bytes = Util.paddedByteArray(bytes, 32); - } else if (bytes.length > 32) { - throw new MemoTooLongException("Memo.hash can contain 32 bytes at max."); - } - - org.stellar.base.xdr.Hash hash = new org.stellar.base.xdr.Hash(); - hash.setHash(bytes); - - memo.setHash(hash); - return memo; + public static MemoHash hash(byte[] bytes) { + return new MemoHash(bytes); } /** - * Creates MEMO_HASH type memo from hex-encoded string + * Creates new {@link MemoHash} instance from hex-encoded string * @param hexString * @throws DecoderException */ - public static org.stellar.base.xdr.Memo hash(String hexString) throws DecoderException { - checkNotNull(hexString, "hexString cannot be null"); - byte[] decoded = Hex.decodeHex(hexString.toCharArray()); - return Memo.hash(decoded); + public static MemoHash hash(String hexString) throws DecoderException { + return new MemoHash(hexString); } /** - * Creates MEMO_RETURN type memo from byte array. + * Creates new {@link MemoReturnHash} instance from byte array. * @param bytes */ - public static org.stellar.base.xdr.Memo returnHash(byte[] bytes) { - org.stellar.base.xdr.Memo memo = Memo.hash(bytes); - memo.setDiscriminant(MemoType.MEMO_RETURN); - return memo; + public static MemoReturnHash returnHash(byte[] bytes) { + return new MemoReturnHash(bytes); } /** - * Creates MEMO_RETURN type memo from hex-encoded string. + * Creates new {@link MemoReturnHash} instance from hex-encoded string. * @param hexString * @throws DecoderException */ - public static org.stellar.base.xdr.Memo returnHash(String hexString) throws DecoderException { - checkNotNull(hexString, "hexString cannot be null"); - org.stellar.base.xdr.Memo memo = Memo.hash(hexString); - memo.setDiscriminant(MemoType.MEMO_RETURN); - return memo; + public static MemoReturnHash returnHash(String hexString) throws DecoderException { + return new MemoReturnHash(hexString); } + + abstract org.stellar.base.xdr.Memo toXdr(); } diff --git a/src/main/java/org/stellar/base/MemoHash.java b/src/main/java/org/stellar/base/MemoHash.java new file mode 100644 index 0000000..0ea35da --- /dev/null +++ b/src/main/java/org/stellar/base/MemoHash.java @@ -0,0 +1,29 @@ +package org.stellar.base; + +import org.apache.commons.codec.DecoderException; +import org.stellar.base.xdr.MemoType; + +/** + * Represents MEMO_HASH. + */ +public class MemoHash extends MemoHashAbstract { + public MemoHash(byte[] bytes) { + super(bytes); + } + + public MemoHash(String hexString) throws DecoderException { + super(hexString); + } + + @Override + org.stellar.base.xdr.Memo toXdr() { + org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo(); + memo.setDiscriminant(MemoType.MEMO_HASH); + + org.stellar.base.xdr.Hash hash = new org.stellar.base.xdr.Hash(); + hash.setHash(bytes); + + memo.setHash(hash); + return memo; + } +} diff --git a/src/main/java/org/stellar/base/MemoHashAbstract.java b/src/main/java/org/stellar/base/MemoHashAbstract.java new file mode 100644 index 0000000..7c374d1 --- /dev/null +++ b/src/main/java/org/stellar/base/MemoHashAbstract.java @@ -0,0 +1,60 @@ +package org.stellar.base; + +import org.apache.commons.codec.DecoderException; +import org.apache.commons.codec.binary.Hex; + +abstract class MemoHashAbstract extends Memo { + protected byte[] bytes; + + public MemoHashAbstract(byte[] bytes) { + if (bytes.length < 32) { + bytes = Util.paddedByteArray(bytes, 32); + } else if (bytes.length > 32) { + throw new MemoTooLongException("MEMO_HASH can contain 32 bytes at max."); + } + + this.bytes = bytes; + } + + public MemoHashAbstract(String hexString) throws DecoderException { + this(Hex.decodeHex(hexString.toCharArray())); + } + + /** + * Returns 32 bytes long array contained in this memo. + */ + public byte[] getBytes() { + return bytes; + } + + /** + *Returns hex representation of bytes contained in this memo.
+ * + *Example:
+ *
+ * MemoHash memo = new MemoHash("4142434445");
+ * memo.getHexValue(); // 4142434445000000000000000000000000000000000000000000000000000000
+ * memo.getTrimmedHexValue(); // 4142434445
+ *
+ */
+ public String getHexValue() {
+ return new String(Hex.encodeHex(this.bytes));
+ }
+
+ /**
+ * Returns hex representation of bytes contained in this memo until null byte (0x00) is found.
+ * + *Example:
+ *
+ * MemoHash memo = new MemoHash("4142434445");
+ * memo.getHexValue(); // 4142434445000000000000000000000000000000000000000000000000000000
+ * memo.getTrimmedHexValue(); // 4142434445
+ *
+ */
+ public String getTrimmedHexValue() {
+ return this.getHexValue().split("00")[0];
+ }
+
+ @Override
+ abstract org.stellar.base.xdr.Memo toXdr();
+}
diff --git a/src/main/java/org/stellar/base/MemoId.java b/src/main/java/org/stellar/base/MemoId.java
new file mode 100644
index 0000000..508d170
--- /dev/null
+++ b/src/main/java/org/stellar/base/MemoId.java
@@ -0,0 +1,32 @@
+package org.stellar.base;
+
+import org.stellar.base.xdr.MemoType;
+import org.stellar.base.xdr.Uint64;
+
+/**
+ * Represents MEMO_ID.
+ */
+public class MemoId extends Memo {
+ private long id;
+
+ public MemoId(long id) {
+ if (id < 0) {
+ throw new IllegalArgumentException("id must be a positive number");
+ }
+ this.id = id;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ @Override
+ org.stellar.base.xdr.Memo toXdr() {
+ org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo();
+ memo.setDiscriminant(MemoType.MEMO_ID);
+ Uint64 idXdr = new Uint64();
+ idXdr.setUint64(id);
+ memo.setId(idXdr);
+ return memo;
+ }
+}
diff --git a/src/main/java/org/stellar/base/MemoNone.java b/src/main/java/org/stellar/base/MemoNone.java
new file mode 100644
index 0000000..21610eb
--- /dev/null
+++ b/src/main/java/org/stellar/base/MemoNone.java
@@ -0,0 +1,15 @@
+package org.stellar.base;
+
+import org.stellar.base.xdr.MemoType;
+
+/**
+ * Represents MEMO_NONE.
+ */
+public class MemoNone extends Memo {
+ @Override
+ org.stellar.base.xdr.Memo toXdr() {
+ org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo();
+ memo.setDiscriminant(MemoType.MEMO_NONE);
+ return memo;
+ }
+}
diff --git a/src/main/java/org/stellar/base/MemoReturnHash.java b/src/main/java/org/stellar/base/MemoReturnHash.java
new file mode 100644
index 0000000..55f5747
--- /dev/null
+++ b/src/main/java/org/stellar/base/MemoReturnHash.java
@@ -0,0 +1,30 @@
+package org.stellar.base;
+
+import org.apache.commons.codec.DecoderException;
+import org.stellar.base.xdr.Memo;
+import org.stellar.base.xdr.MemoType;
+
+/**
+ * Represents MEMO_RETURN.
+ */
+public class MemoReturnHash extends MemoHashAbstract {
+ public MemoReturnHash(byte[] bytes) {
+ super(bytes);
+ }
+
+ public MemoReturnHash(String hexString) throws DecoderException {
+ super(hexString);
+ }
+
+ @Override
+ Memo toXdr() {
+ org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo();
+ memo.setDiscriminant(MemoType.MEMO_RETURN);
+
+ org.stellar.base.xdr.Hash hash = new org.stellar.base.xdr.Hash();
+ hash.setHash(bytes);
+
+ memo.setHash(hash);
+ return memo;
+ }
+}
diff --git a/src/main/java/org/stellar/base/MemoText.java b/src/main/java/org/stellar/base/MemoText.java
new file mode 100644
index 0000000..0f64139
--- /dev/null
+++ b/src/main/java/org/stellar/base/MemoText.java
@@ -0,0 +1,35 @@
+package org.stellar.base;
+
+import org.stellar.base.xdr.MemoType;
+
+import java.nio.charset.StandardCharsets;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Represents MEMO_TEXT.
+ */
+public class MemoText extends Memo {
+ private String text;
+
+ public MemoText(String text) {
+ this.text = checkNotNull(text, "text cannot be null");
+
+ int length = text.getBytes((StandardCharsets.UTF_8)).length;
+ if (length > 28) {
+ throw new MemoTooLongException("text must be <= 28 bytes. length=" + String.valueOf(length));
+ }
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ @Override
+ org.stellar.base.xdr.Memo toXdr() {
+ org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo();
+ memo.setDiscriminant(MemoType.MEMO_TEXT);
+ memo.setText(text);
+ return memo;
+ }
+}
diff --git a/src/main/java/org/stellar/base/Operation.java b/src/main/java/org/stellar/base/Operation.java
index 0f1bdcf..78ecaed 100644
--- a/src/main/java/org/stellar/base/Operation.java
+++ b/src/main/java/org/stellar/base/Operation.java
@@ -10,6 +10,9 @@
import static com.google.common.base.Preconditions.checkNotNull;
+/**
+ * Abstract class for operations.
+ */
public abstract class Operation {
Operation() {}
diff --git a/src/main/java/org/stellar/base/Transaction.java b/src/main/java/org/stellar/base/Transaction.java
index f589fa7..b9a61e4 100644
--- a/src/main/java/org/stellar/base/Transaction.java
+++ b/src/main/java/org/stellar/base/Transaction.java
@@ -24,10 +24,10 @@ public class Transaction {
private final Keypair mSourceAccount;
private final long mSequenceNumber;
private final Operation[] mOperations;
- private final org.stellar.base.xdr.Memo mMemo;
+ private final Memo mMemo;
private List