/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.util.money;
import java.io.Serializable;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.joda.convert.FromString;
import org.joda.convert.ToString;
import com.google.common.collect.ImmutableSet;
import com.opengamma.id.ObjectId;
import com.opengamma.id.ObjectIdentifiable;
import com.opengamma.id.UniqueId;
import com.opengamma.id.UniqueIdentifiable;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.PublicAPI;
/**
* A unit of currency.
* <p>
* This class represents a unit of currency such as the British Pound, Euro or US Dollar.
* <p>
* This class is immutable and thread-safe.
*/
@PublicAPI
public final class Currency implements ObjectIdentifiable, UniqueIdentifiable, Comparable<Currency>, Serializable {
/** Serialization version. */
private static final long serialVersionUID = 1L;
/**
* A cache of instances.
*/
private static final ConcurrentMap<String, Currency> s_instanceMap = new ConcurrentHashMap<String, Currency>();
/**
* The scheme to use in object identifiers.
*/
public static final String OBJECT_SCHEME = "CurrencyISO";
// a selection of commonly traded, stable currencies
/**
* The currency 'USD' - United States Dollar.
*/
public static final Currency USD = of("USD");
/**
* The currency 'EUR' - Euro.
*/
public static final Currency EUR = of("EUR");
/**
* The currency 'JPY' - Japanese Yen.
*/
public static final Currency JPY = of("JPY");
/**
* The currency 'GBP' - British pound.
*/
public static final Currency GBP = of("GBP");
/**
* The currency 'EUR' - Swiss Franc.
*/
public static final Currency CHF = of("CHF");
/**
* The currency 'AUD' - Australian Dollar.
*/
public static final Currency AUD = of("AUD");
/**
* The currency 'CAD' - Canadian Dollar.
*/
public static final Currency CAD = of("CAD");
// a selection of other currencies
/**
* The currency 'NZD' - New Zealand Dollar.
*/
public static final Currency NZD = of("NZD");
/**
* The currency 'DKK' - Danish Krone
*/
public static final Currency DKK = of("DKK");
/**
* The currency 'DEM' - Deutsche Mark
*/
public static final Currency DEM = of("DEM");
/**
* The currency 'CZK' - Czeck Krona
*/
public static final Currency CZK = of("CZK");
/**
* The currency 'SEK' - Swedish Krona
*/
public static final Currency SEK = of("SEK");
/**
* The currency 'SKK' - Slovak Korona
*/
public static final Currency SKK = of("SKK");
/**
* The currency 'ITL' - Italian Lira
*/
public static final Currency ITL = of("ITL");
/**
* The currency 'HUF' = Hugarian Forint
*/
public static final Currency HUF = of("HUF");
/**
* The currency 'FRF' - French Franc
*/
public static final Currency FRF = of("FRF");
/**
* The currency 'NOK' - Norwegian Krone
*/
public static final Currency NOK = of("NOK");
/**
* The currency 'HKD' - Hong Kong Dollar
*/
public static final Currency HKD = of("HKD");
/**
* The currency 'BRL' - Brazil Dollar
*/
public static final Currency BRL = of("BRL");
/**
* The currency 'ZAR' - South African Rand
*/
public static final Currency ZAR = of("ZAR");
/**
* The currency 'PLN' - Polish Zloty
*/
public static final Currency PLN = of("PLN");
/**
* The currency 'SGD' - Singapore Dollar
*/
public static final Currency SGD = of("SGD");
/**
* The currency 'MXN' - Mexican Peso
*/
public static final Currency MXN = of("MXN");
/**
* The currency code, not null.
*/
private final String _code;
//-----------------------------------------------------------------------
/**
* Lists the available currencies.
*
* @return an immutable set containing all registered currencies, not null
*/
public static Set<Currency> getAvailableCurrencies() {
return ImmutableSet.copyOf(s_instanceMap.values());
}
//-----------------------------------------------------------------------
/**
* Obtains an instance of {@code Currency} matching the specified JDK currency.
* <p>
* This converts the JDK currency instance to a currency unit using the code.
*
* @param currency the currency, not null
* @return the singleton instance, not null
*/
public static Currency of(java.util.Currency currency) {
ArgumentChecker.notNull(currency, "currency");
return of(currency.getCurrencyCode());
}
/**
* Obtains an instance of {@code Currency} for the specified ISO-4217
* three letter currency code dynamically creating a currency if necessary.
* <p>
* A currency is uniquely identified by ISO-4217 three letter code.
* This method creates the currency if it is not known.
*
* @param currencyCode the three letter currency code, ASCII and upper case, not null
* @return the singleton instance, not null
* @throws IllegalArgumentException if the currency code is not three letters
*/
@FromString
public static Currency of(String currencyCode) {
ArgumentChecker.notNull(currencyCode, "currencyCode");
// check cache before matching
Currency previous = s_instanceMap.get(currencyCode);
if (previous != null) {
return previous;
}
if (currencyCode.matches("[A-Z][A-Z][A-Z]") == false) {
throw new IllegalArgumentException("Invalid currency code: " + currencyCode);
}
s_instanceMap.putIfAbsent(currencyCode, new Currency(currencyCode));
return s_instanceMap.get(currencyCode);
}
/**
* Parses a string to obtain a {@code Currency}.
* <p>
* The parse is identical to {@link #of(String)} except that it will convert
* letters to upper case first.
*
* @param currencyCode the three letter currency code, ASCII, not null
* @return the singleton instance, not null
* @throws IllegalArgumentException if the currency code is not three letters
*/
public static Currency parse(String currencyCode) {
ArgumentChecker.notNull(currencyCode, "currencyCode");
return of(currencyCode.toUpperCase(Locale.ENGLISH));
}
//-------------------------------------------------------------------------
/**
* Restricted constructor.
*
* @param currencyCode the three letter currency code, not null
*/
private Currency(String currencyCode) {
_code = currencyCode;
}
/**
* Ensure singleton on deserialization.
*
* @return the singleton, not null
*/
private Object readResolve() {
return of(_code);
}
//-------------------------------------------------------------------------
/**
* Gets the three letter ISO code.
*
* @return the three letter ISO code, not null
*/
@ToString
public String getCode() {
return _code;
}
//-------------------------------------------------------------------------
/**
* Gets the object identifier for the currency.
* <p>
* This uses the scheme {@link #OBJECT_SCHEME CurrencyISO}.
*
* @return the object identifier, not null
*/
@Override
public ObjectId getObjectId() {
return ObjectId.of(OBJECT_SCHEME, _code);
}
/**
* Gets the unique identifier for the currency.
* <p>
* This uses the scheme {@link #OBJECT_SCHEME CurrencyISO}.
*
* @return the unique identifier, not null
*/
@Override
public UniqueId getUniqueId() {
return UniqueId.of(OBJECT_SCHEME, _code);
}
//-----------------------------------------------------------------------
/**
* Gets the JDK currency instance equivalent to this currency.
* <p>
* This attempts to convert a {@code Currency} to a JDK {@code Currency}.
*
* @return the JDK currency instance, not null
* @throws IllegalArgumentException if no matching currency exists in the JDK
*/
public java.util.Currency toCurrency() {
return java.util.Currency.getInstance(_code);
}
//-----------------------------------------------------------------------
/**
* Compares this currency to another by alphabetical comparison of the code.
*
* @param other the other currency, not null
* @return negative if earlier alphabetically, 0 if equal, positive if greater alphabetically
*/
@Override
public int compareTo(Currency other) {
return _code.compareTo(other._code);
}
/**
* Checks if this currency equals another currency.
* <p>
* The comparison checks the three letter currency code.
*
* @param obj the other currency, null returns false
* @return true if equal
*/
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof Currency) {
return _code.equals(((Currency) obj)._code);
}
return false;
}
/**
* Returns a suitable hash code for the currency.
*
* @return the hash code
*/
@Override
public int hashCode() {
return _code.hashCode();
}
//-----------------------------------------------------------------------
/**
* Gets the three letter currency code as a string.
*
* @return the three letter currency code, not null
*/
@Override
public String toString() {
return _code;
}
}