Adding support to invoice generation

master
Nelson R. Perez 2016-11-29 12:23:18 -05:00
parent 7a904a435e
commit c2b46e4b0a
4 changed files with 162 additions and 2 deletions

View File

@ -0,0 +1,64 @@
package com.luminiasoft.bitshares;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.luminiasoft.bitshares.interfaces.JsonSerializable;
import org.bitcoinj.core.Base58;
/**
* Class used to handle invoice generation, compression and QR-Code data derivation,
* as detailed in <a href="http://docs.bitshares.eu/integration/merchants/merchant-protocol.html">this</> link.
* @author Nelson R. Pérez
*/
public class Invoice implements JsonSerializable {
public static class LineItem {
private String label;
private int quantity;
private String price;
public LineItem(String label, int quantity, String price){
this.label = label;
this.quantity = quantity;
this.price = price;
}
}
private String to;
private String to_label;
private String memo;
private String currency;
private LineItem[] line_items;
private String note;
private String callback;
public Invoice(String to, String to_label, String memo, String currency, LineItem[] items, String note, String callback){
this.to = to;
this.to_label = to_label;
this.memo = memo;
this.currency = currency;
this.line_items = items;
this.note = note;
this.callback = callback;
}
@Override
public String toJsonString() {
Gson gson = new Gson();
return gson.toJson(this);
}
@Override
public JsonElement toJsonObject() {
return null;
}
public static String toQrCode(Invoice invoice){
String json = invoice.toJsonString();
return Base58.encode(Util.compress(json.getBytes()));
}
public static Invoice fromQrCode(String encoded){
String json = new String(Util.decompress(Base58.decode(encoded)));
Gson gson = new Gson();
return gson.fromJson(json, Invoice.class);
}
}

View File

@ -72,10 +72,14 @@ public class Main {
// test.testBip39Opertion();
test.testAccountNamebyAddress();
// test.testAccountNamebyAddress();
// test.testAccountNameById();
// test.testRelativeAccountHistory();
test.testingInvoiceGeneration();
// test.testCompression();
}
}

View File

@ -705,4 +705,23 @@ public class Test {
System.out.println("NoSuchAlgorithmException. Msg: " + e.getMessage());
}
}
public void testingInvoiceGeneration(){
Invoice.LineItem[] lineItem = new Invoice.LineItem[] { new Invoice.LineItem("Apples", 2, "20 CSD")};
Invoice invoice = new Invoice("bilthon-83", "Bilthon's store", "Invoice #12", "BTS", lineItem, "Thank you", "");
String qrCodeData = Invoice.toQrCode(invoice);
System.out.println("qrCodeData");
System.out.println(qrCodeData);
Invoice recovered = Invoice.fromQrCode(qrCodeData);
System.out.println("recovered invoice: "+recovered.toJsonString());
}
public void testCompression(){
String test = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
System.out.println("to compress");
System.out.println(Util.bytesToHex(test.getBytes()));
byte[] compressed = Util.compress(test.getBytes());
System.out.println("compressed");
System.out.println(Util.bytesToHex(compressed));
}
}

View File

@ -1,7 +1,17 @@
package com.luminiasoft.bitshares;
import org.tukaani.xz.LZMA2Options;
import org.tukaani.xz.LZMAInputStream;
import org.tukaani.xz.LZMAOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Created by nelson on 11/8/16.
* Class used to encapsulate common utility methods
*/
public class Util {
final private static char[] hexArray = "0123456789abcdef".toCharArray();
@ -25,4 +35,67 @@ public class Util {
}
return new String(hexChars);
}
/**
* Utility function that compresses data using the LZMA algorithm.
* @param inputBytes Input bytes of the data to be compressed.
* @return Compressed data
* @author Henry Varona
*/
public static byte[] compress(byte[] inputBytes) {
LZMAOutputStream out = null;
try {
ByteArrayInputStream input = new ByteArrayInputStream(inputBytes);
ByteArrayOutputStream output = new ByteArrayOutputStream(2048);
LZMA2Options options = new LZMA2Options();
out = new LZMAOutputStream(output, options,-1);
byte[] buf = new byte[inputBytes.length];
int size;
while ((size = input.read(buf)) != -1) {
out.write(buf, 0, size);
}
out.finish();
return output.toByteArray();
} catch (IOException ex) {
Logger.getLogger(FileBin.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
out.close();
} catch (IOException ex) {
Logger.getLogger(FileBin.class.getName()).log(Level.SEVERE, null, ex);
}
}
return null;
}
/**
* Utility function that decompresses data that has been compressed using the LZMA algorithm
* by the {@link Util#compress(byte[])} method.
* @param inputBytes Compressed data
* @return Uncompressed data
* @author Henry Varona
*/
public static byte[] decompress(byte[] inputBytes) {
LZMAInputStream in = null;
try {
ByteArrayInputStream input = new ByteArrayInputStream(inputBytes);
ByteArrayOutputStream output = new ByteArrayOutputStream(2048);
in = new LZMAInputStream(input);
int size;
while ((size = in.read()) != -1) {
output.write(size);
}
in.close();
return output.toByteArray();
} catch (IOException ex) {
Logger.getLogger(FileBin.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
in.close();
} catch (IOException ex) {
Logger.getLogger(FileBin.class.getName()).log(Level.SEVERE, null, ex);
}
}
return null;
}
}