/*
* JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
* Copyright (C) 2006 - JScience (http://jscience.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package org.jscience.economics.money;
import javolution.context.LocalContext;
import javolution.util.LocalMap;
import javax.measure.converter.ConversionException;
import javax.measure.converter.UnitConverter;
import javax.measure.unit.DerivedUnit;
import javax.measure.unit.Unit;
import javax.measure.unit.UnitFormat;
/**
* This class represents a currency {@link javax.measure.unit.Unit Unit}.
* Currencies are a special form of {@link DerivedUnit}, conversions
* between currencies is possible if their respective exchange rates
* have been set and the conversion factor can be changed dynamically.
*
* Quantities stated in {@link Currency} are usually instances of
* {@link Money}.
*
* By default, the label associated to a currency is its ISO-4217 code
* (see the ISO 4217
* maintenance agency for a table of currency codes). An application may
* change this default using the {@link javax.measure.unit.UnitFormat#label
* UnitFormat.label(String)} method.
* For example:[code]
* UnitFormat.getStandardInstance().label(Currency.EUR, "€");
* UnitFormat.getStandardInstance().label(Currency.GBP, "£");
* UnitFormat.getStandardInstance().label(Currency.JPY, "¥");
* UnitFormat.getStandardInstance().label(Currency.USD, "$");
* [/code]
*
* @author Jean-Marie Dautelle
* @version 3.0, February 13, 2006
* @see #setExchangeRate
*/
public class Currency extends DerivedUnit {
/**
* The Australian Dollar currency unit.
*/
public static final Currency AUD = new Currency("AUD");
/**
* The Canadian Dollar currency unit.
*/
public static final Currency CAD = new Currency("CAD");
/**
* The China Yan currency.
*/
public static final Currency CNY = new Currency("CNY");
/**
* The Euro currency.
*/
public static final Currency EUR = new Currency("EUR");
/**
* The British Pound currency.
*/
public static final Currency GBP = new Currency("GBP");
/**
* The Japanese Yen currency.
*/
public static final Currency JPY = new Currency("JPY");
/**
* The Korean Republic Won currency.
*/
public static final Currency KRW = new Currency("KRW");
/**
* The Taiwanese dollar currency.
*/
public static final Currency TWD = new Currency("TWD");
/**
* The United State dollar currency.
*/
public static final Currency USD = new Currency("USD");
/**
* Holds the reference currency.
*/
private static final LocalContext.Reference
REFERENCE = new LocalContext.Reference();
/**
* Holds the exchanges rate to the reference currency.
*/
private static final LocalMap TO_REFERENCE =
new LocalMap();
/**
* Holds the converter to the {@link Money#BASE_UNIT money base unit}.
*/
private final Converter _toBaseUnit;
/**
* Creates the currency unit for the given currency code.
* See the ISO 4217
* maintenance agency for more information, including a table of
* currency codes.
*
* @param code the ISO-4217 code of the currency (e.g.
* "EUR", "USD", "JPY").
* @throws IllegalArgumentException if the specified code is not an ISO-4217
* code.
*/
public Currency(String code) {
_toBaseUnit = new Converter(code, false);
UnitFormat.getInstance().label(this, code);
}
/**
* Returns the currency code for this currency.
*
* @return the ISO-4217 code of the currency
* (e.g. "EUR", "USD", "JPY").
*/
public String getCode() {
return _toBaseUnit._code;
}
/**
* Returns the default number of fraction digits used with this currency
* unit. For example, the default number of fraction digits for
* the {@link Currency#EUR} is 2, while for the {@link Currency#JPY} (Yen)
* it's 0. This method can be overriden for custom currencies returning
* values different from 2.
*
* @return the default number of fraction digits for this currency.
*/
public int getDefaultFractionDigits() {
return (this.equals(JPY) || (this.equals(KRW))) ?
0 : 2;
}
/**
* Sets the reference currency (context-local). Changing the
* reference currency clears all the exchange rates previously set.
*
* @param currency the new reference currency.
* @see javolution.context.LocalContext
*/
public static void setReferenceCurrency(Currency currency) {
REFERENCE.set(currency);
TO_REFERENCE.clear();
TO_REFERENCE.put(currency.getCode(), 1.0);
}
/**
* Returns the currency used as reference when setting the exchange rate.
* By default, the reference currency is the currency for the default
* country locale.
*
* @return the reference currency.
* @see #setExchangeRate
*/
public static Currency getReferenceCurrency() {
return REFERENCE.get();
}
/**
* Sets the exchange rate of this {@link Currency} relatively to
* the reference currency. Setting the exchange rate allows
* for conversion between {@link Money} stated in different currencies.
* For example:
* Currency.setReferenceCurrency(Currency.USD);
* Currency.EUR.setExchangeRate(1.17); // 1.0 € = 1.17 $
*
*
* @param refAmount the amount stated in the {@link #getReferenceCurrency}
* equals to one unit of this {@link Currency}.
* @see #getReferenceCurrency
*/
public void setExchangeRate(double refAmount) {
TO_REFERENCE.put(this.getCode(), refAmount);
}
/**
* Returns the exchange rate for this {@link Currency}.
*
* @return the amount stated in the {@link #getReferenceCurrency}
* equals to one unit of this {@link Currency}.
* @throws ConversionException if the exchange rate has not be set for
* this {@link Currency}.
*/
public double getExchangeRate() {
Double refAmount = TO_REFERENCE.get(this.getCode());
if (refAmount == null)
throw new ConversionException("Exchange rate not set for " + this.getCode());
return refAmount.doubleValue();
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Currency))
return false;
Currency that = (Currency) obj;
return this._toBaseUnit.equals(that._toBaseUnit);
}
@Override
public int hashCode() {
return _toBaseUnit.hashCode();
}
@Override
public Unit super Money> getStandardUnit() {
return Money.BASE_UNIT;
}
@Override
public UnitConverter toStandardUnit() {
return _toBaseUnit;
}
/**
* This class represents the currency converters.
*/
private static class Converter extends UnitConverter {
String _code;
boolean _invert;
private Converter(String code, boolean invert) {
_code = code;
_invert = invert;
}
@Override
public UnitConverter inverse() {
return new Converter(_code, !_invert);
}
@Override
public double convert(double x) throws ConversionException {
Double refAmount = TO_REFERENCE.get(_code);
if (refAmount == null)
throw new ConversionException("Exchange rate not set for " + _code);
return _invert ? x / refAmount.doubleValue() : x * refAmount.doubleValue();
}
@Override
public boolean isLinear() {
return true;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Converter))
return false;
Converter that = (Converter) obj;
return this._code.equals(that._code) && (this._invert == that._invert);
}
@Override
public int hashCode() {
return _invert ? _code.hashCode() : - _code.hashCode();
}
private static final long serialVersionUID = 1L;
}
private static final long serialVersionUID = 1L;
}
Ads help maintain this website.