/*
** Java currency library package.
** Copyright (c) 1999 by Bruno Antunes
**
** This program is free software.
**
** You may redistribute it and/or modify it under the terms of the GNU
** General Public License as published by the Free Software Foundation.
** Version 2 of the license should be included with this distribution in
** the file LICENSE, as well as License.html. If the license is not
** included with this distribution, you may find a copy at the FSF web
** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
**
** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
** REDISTRIBUTION OF THIS SOFTWARE.
**
*/
package org.gjt.currency;
import java.math.BigDecimal;
import java.io.Serializable;
/**
* A money representation using amounts as <code>BigDecimal</code>. The money is
* allways represented by an amount (the amount of money) and its currency.
*<br>
* BigMoneys are constant; their values cannot be changed after they are
* created.
*
* @see Currency
*
* @author Bruno Antunes
* @version 1.0 30/10/1999
*/
public class BigMoney implements Comparable, Cloneable, Serializable {
private BigDecimal amount;
private Currency currency;
/**
* A zero amount of money int the specified currency
*
* @param aCurrency the Currency for this amount of money
*/
public BigMoney(Currency aCurrency) {
this(0.0,aCurrency);
}
/**
* A specified amount of money in the specified currency
*
* @param anAmount the amount of money
* @param aCurrency the currency for this amount of money
*/
public BigMoney(String anAmount, Currency aCurrency) {
this(new BigDecimal(anAmount),aCurrency);
}
/**
* A specified amount of money int the specified currency
*
* @param anAmount the amount of money
* @param aCurrency the currency for this amount of money
*/
public BigMoney(double anAmount, Currency aCurrency) {
this(new BigDecimal(String.valueOf(anAmount)),aCurrency);
}
/**
* A specified amount of money int the specified currency
*
* @param anAmount the amount of money
* @param aCurrency the currency for this amount of money
*/
public BigMoney(BigDecimal anAmount, Currency aCurrency) {
if ((anAmount == null) || (aCurrency == null)) {
throw new IllegalArgumentException();
}
amount = anAmount;
currency = aCurrency;
}
/**
* Converts this money to the <code>Curency</code> specified.
*
* @param toCurrency the unit to convert the money
* @return a new BigMoney object in the specified unit. If the unit
* specified is the same of this <code>BigMoney</code>, the same
* <code>BigMoney</code> object is returned.
*
* @see Currency
*/
public BigMoney convertTo(Currency toCurrency) {
BigMoney result = null;
if (currency.equals(toCurrency)) {
return this;
} else {
// TOSEE: Is BigDecimal.ROUND_UP a good option?
// TOSEE: Is it necessary to make rounds?
// TOSEE: Is it ok for non Euro currencys?
BigDecimal newAmount = amount.divide(
new BigDecimal(String.valueOf(currency.getExchangeRate())),
BigDecimal.ROUND_UP);
newAmount = newAmount.multiply(
new BigDecimal(
String.valueOf(toCurrency.getExchangeRate())));
result = new BigMoney(newAmount, toCurrency);
}
return result;
}
/**
* Adds the money specified to this money
*
* @param money the money to be added
* @return (this + money)
*/
public BigMoney add(BigMoney money) {
BigMoney toAdd = money.convertTo(currency);
BigDecimal newAmount = amount.add(toAdd.amount);
return new BigMoney(newAmount,currency);
}
/**
* Subtracts the money specified to this money
*
* @param money the money to be subtracted
* @return (this - money)
*/
public BigMoney subtract(BigMoney money) {
BigMoney toSubtract = money.convertTo(currency);
BigDecimal newAmount = amount.subtract(toSubtract.amount);
return new BigMoney(newAmount,currency);
}
/**
* Multiplies this money with a specified factor
*
* @param factor the value os the multiplier
* @return (this * factor)
*/
public BigMoney multiply(double factor) {
BigDecimal newAmount = amount.multiply(
new BigDecimal(String.valueOf(factor)));
return new BigMoney(newAmount, currency);
}
/**
* Compares this money with the specified money.
*
* @param money Money to which this Money is to be compared.
* @return -1, 0 or 1 as this Money is numerically less than, equal
* to, or greater than money.
*/
public int compareTo(BigMoney money) {
money = money.convertTo(currency);
return amount.compareTo(money.amount);
}
/**
* Compares this money with the specified object. If the object is not a
* <code>BigMoney</code>, then a <code>ClassCastException</code> is thrown.
*
* @param obj Money to which this Money is to be compared.
* @return -1, 0 or 1 as this Money is numerically less than, equal
* to, or greater than money.
*
* @throws ClassCastException if obj is not a BigMoney.
* @see Comparable
*/
public int compareTo(Object obj) {
BigMoney money = (BigMoney) obj;
money = money.convertTo(currency);
return amount.compareTo(money.amount);
}
/**
* Compares the specified Object with this Money for equality.
*
* @param o the Object to be compared for equality with this Money
* @return true if the specified Object is equal to this Money
*/
public boolean equals(Object obj) {
if (obj instanceof BigMoney) {
BigMoney money = (BigMoney) obj;
return currency.equals(money.currency) &&
amount.equals(money.amount);
} else {
return false;
}
}
public BigDecimal getAmount() {
return amount;
}
public Currency getCurrency() {
return currency;
}
/**
* String representation of the amount of money formatted using the
* NumberFormatter registered in the <code>CurrenyFormatManager</code>
*
* @return the formatted money
*
* @see CurrenyFormatManager
*/
public String format() {
return CurrenyFormatManager.getCurrencyFormat(currency).format(amount);
}
/** @return a String representation of this money */
public String toString() {
return amount + ";" + currency.toString();
}
public Object clone() {
return this;
}
}