package org.ripple.power.txns;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import org.json.JSONObject;
import org.ripple.power.CoinUtils;
import org.ripple.power.RippleAddress;
import org.ripple.power.config.LSystem;
import org.ripple.power.txns.data.Take;
import org.ripple.power.utils.BigNumber;
import org.ripple.power.utils.StringUtils;
import com.ripple.core.coretypes.AccountID;
import com.ripple.core.coretypes.Amount;
import com.ripple.core.coretypes.Currency;
import com.ripple.core.coretypes.Issue;
public class IssuedCurrency extends RippleDefault {
boolean isHighNodeIssuer(BigNumber finalBalance, BigNumber previousBalance,
BigNumber highLimit, BigNumber lowLimit) {
if (finalBalance.isPositive()) {
return true;
} else if (finalBalance.isNegative()) {
return false;
} else if (previousBalance.isPositive()) {
return true;
} else if (previousBalance.isNegative()) {
return false;
} else if (lowLimit.isZero() && highLimit.isPositive()) {
return false;
} else if (highLimit.isZero() && lowLimit.isPositive()) {
return true;
} else {
return false;
}
}
// enter an account with a trust line containing XAU (-0.5%pa) -> hex:
private final static String XAU_05PA = "0158415500000000C1F76FF6ECB0BAC600000000";
public BigDecimal amount;
public RippleAddress issuer;
public String currency = LSystem.nativeCurrency.toUpperCase();
public static final int MIN_SCALE = -96;
public static final int MAX_SCALE = 80;
public Object tag;
public IssuedCurrency() {
}
public IssuedCurrency(String amountStr) {
this(amountStr, false);
}
public IssuedCurrency(String amountStr, boolean update) {
if (amountStr.toLowerCase().indexOf(LSystem.nativeCurrency) != -1) {
amountStr = StringUtils.replaceIgnoreCase(amountStr,
LSystem.nativeCurrency, "").trim();
int idx = amountStr.indexOf('/');
if (idx != -1) {
amountStr = amountStr.substring(0, idx);
}
if (update) {
amountStr = CurrencyUtils.getValueToRipple(amountStr);
}
}
if (amountStr.indexOf('/') == -1) {
amount = new BigDecimal(amountStr).stripTrailingZeros();
} else {
String[] split = org.ripple.power.utils.StringUtils.split(
amountStr, "/");
amount = new BigDecimal(split[0]).stripTrailingZeros();
currency = split[1];
if ("XAU (-0.5%pa)".equals(currency)
|| "XAU(-0.5%pa)".equals(currency)) {
this.currency = XAU_05PA;
} else if (currency.length() > 3 && AccountFind.is256hash(currency)) {
byte[] buffer = CoinUtils.fromHex(currency);
this.currency = CoinUtils.toHex(buffer);
}
issuer = new RippleAddress(split[2]);
int oldScale = amount.scale();
if (oldScale < MIN_SCALE || oldScale > MAX_SCALE) {
int newScale = MAX_SCALE
- (amount.precision() - amount.scale());
if (newScale < MIN_SCALE || newScale > MAX_SCALE) {
throw new RuntimeException("newScale " + newScale
+ " is out of range");
}
amount = amount.setScale(newScale);
}
}
}
public IssuedCurrency(String issuerStr, String currencyStr) {
this("0", new RippleAddress(issuerStr), currencyStr);
}
public IssuedCurrency(String amountStr, String issuerStr, String currencyStr) {
this(amountStr, new RippleAddress(issuerStr), currencyStr);
}
public IssuedCurrency(String amountStr, RippleAddress issuer,
String currencyStr) {
this(new BigDecimal(amountStr).stripTrailingZeros(), issuer,
currencyStr);
}
public IssuedCurrency(IssuedCurrency cur) {
this(cur.toString());
}
public IssuedCurrency(BigDecimal amount, RippleAddress issuer,
String currencyStr) {
int oldScale = amount.scale();
if (oldScale < MIN_SCALE || oldScale > MAX_SCALE) {
int newScale = MAX_SCALE - (amount.precision() - amount.scale());
if (newScale < MIN_SCALE || newScale > MAX_SCALE) {
throw new RuntimeException("newScale " + newScale
+ " is out of range");
}
amount = amount.setScale(newScale);
}
this.amount = amount;
this.issuer = issuer;
if ("XAU (-0.5%pa)".equals(currencyStr)
|| "XAU(-0.5%pa)".equals(currencyStr)) {
this.currency = XAU_05PA;
} else if (currencyStr.length() > 3
&& AccountFind.is256hash(currencyStr)) {
byte[] buffer = CoinUtils.fromHex(currencyStr);
this.currency = CoinUtils.toHex(buffer);
} else {
this.currency = currencyStr;
}
}
public IssuedCurrency(BigDecimal xrpAmount) {
this.amount = xrpAmount;
}
public IssuedCurrency(int xrpAmount) {
this(BigDecimal.valueOf(xrpAmount));
}
public boolean isNative() {
return issuer == null
|| LSystem.nativeCurrency.equalsIgnoreCase(currency);
}
public boolean isNegative() {
return amount.signum() == -1;
}
public String toGatewayString() {
if (issuer == null || currency == null) {
return amount.movePointLeft(6).stripTrailingZeros().toPlainString()
+ " XRP";
}
Gateway gateway = Gateway.getGateway(issuer.toString());
if (gateway == null) {
return amount.stripTrailingZeros().toPlainString() + "/" + currency
+ "/" + issuer.toString();
} else {
return amount.stripTrailingZeros().toPlainString() + "/" + currency
+ "/" + gateway.name;
}
}
@Override
public String toString() {
if (issuer == null || currency == null) {
return amount.movePointLeft(6).stripTrailingZeros().toPlainString()
+ " XRP";
}
return amount.stripTrailingZeros().toPlainString() + "/" + currency
+ "/" + issuer;
}
public BigDecimal scale(float s) {
if (amount == null) {
return null;
}
return amount = new BigDecimal(LSystem.getNumber(
amount.multiply(BigDecimal.valueOf(s)), false));
}
public void copyFrom(JSONObject jsonDenomination) {
if (jsonDenomination == null) {
return;
}
String issuerStr = jsonDenomination.optString("issuer");
if (!StringUtils.isEmpty(issuerStr)) {
issuer = new RippleAddress(issuerStr);
}
String currencyStr = jsonDenomination.optString("currency");
if (XAU_05PA.equals(currencyStr)) {
currency = "XAU (-0.5%pa)";
} else if (currencyStr.length() > 3
&& AccountFind.is256hash(currencyStr)) {
byte[] buffer = CoinUtils.fromHex(currencyStr);
try {
currency = new String(buffer, LSystem.encoding);
} catch (UnsupportedEncodingException e) {
currency = new String(buffer);
}
} else {
currency = currencyStr;
}
String amountStr = LSystem.getNumberShort(jsonDenomination.optString(
"value", "0"));
amount = new BigDecimal(amountStr);
}
public void copyFrom(Object jsonObject) {
if (jsonObject instanceof String) {
amount = new BigDecimal((String) jsonObject);
} else {
copyFrom((JSONObject) jsonObject);
}
}
public Object toJSON() {
if (currency == null) {
return amount.toString();
} else {
JSONObject jsonThis = new JSONObject();
jsonThis.put("value", amount.toString());
jsonThis.put("issuer", issuer.toString());
jsonThis.put("currency", currency);
return jsonThis;
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((amount == null) ? 0 : amount.hashCode());
result = prime * result
+ ((currency == null) ? 0 : currency.hashCode());
result = prime * result + ((issuer == null) ? 0 : issuer.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
IssuedCurrency other = (IssuedCurrency) obj;
if (amount == null) {
if (other.amount != null)
return false;
} else if (amount.compareTo(other.amount) != 0)
return false;
if (currency == null) {
if (other.currency != null)
return false;
} else if (!currency.equals(other.currency))
return false;
if (issuer == null) {
if (other.issuer != null)
return false;
} else if (!issuer.equals(other.issuer))
return false;
return true;
}
public Amount getAmount() {
if (issuer != null && currency != null) {
return new Amount(amount, Currency.fromString(currency),
AccountID.fromAddress(issuer.toString()));
}
return new Amount(amount);
}
public Issue getIssue() {
if (issuer != null && currency != null) {
return new Issue(Currency.fromString(currency),
AccountID.fromAddress(issuer.toString()));
}
return null;
}
public JSONObject getJSON() {
if (currency == null) {
currency = LSystem.nativeCurrency.toUpperCase();
}
JSONObject obj = new JSONObject();
if (LSystem.nativeCurrency.equalsIgnoreCase(currency)) {
obj.put("currency", currency.toUpperCase());
} else {
obj.put("currency", currency.toUpperCase());
obj.put("issuer", issuer.toString());
}
return obj;
}
public Take getTake() {
if (currency == null) {
currency = LSystem.nativeCurrency.toUpperCase();
}
Take take = null;
if (LSystem.nativeCurrency.equalsIgnoreCase(currency)) {
take = new Take(amount.toString());
} else {
take = new Take(amount.toString(), currency, issuer.toString());
}
return take;
}
}