/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.util.i18n; 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 country as represented by an ISO-3166 style code. * <p> * This class represents country or territory as defined by ISO-3166. * Additional codes may be added if necessary. * <p> * This class is immutable and thread-safe. */ @PublicAPI public final class Country implements ObjectIdentifiable, UniqueIdentifiable, Comparable<Country>, Serializable { /** Serialization version. */ private static final long serialVersionUID = 1L; /** * A cache of instances. */ private static final ConcurrentMap<String, Country> s_instanceMap = new ConcurrentHashMap<>(16, 0.75f, 4); /** * The scheme to use in object identifiers. */ public static final String OBJECT_SCHEME = "CountryISO"; // Europe /** * The region of 'EU' - Europe (special status in ISO-3166). */ public static final Country EU = of("EU"); /** * The country 'BE' - Belgium. */ public static final Country BE = of("BE"); /** * The country 'CH' - Switzerland. */ public static final Country CH = of("CH"); /** * The currency 'CZ' - Czech Republic. */ public static final Country CZ = of("CZ"); /** * The country 'DE' - Germany. */ public static final Country DE = of("DE"); /** * The country 'DK' - Denmark. */ public static final Country DK = of("DK"); /** * The currency 'ES' - Spain. */ public static final Country ES = of("ES"); /** * The currency 'FI' - Finland. */ public static final Country FI = of("FI"); /** * The currency 'FR' - France. */ public static final Country FR = of("FR"); /** * The country 'GB' - United Kingdom. */ public static final Country GB = of("GB"); /** * The country 'GR' - Greece. */ public static final Country GR = of("GR"); /** * The currency 'HU' = Hungary. */ public static final Country HU = of("HU"); /** * The currency 'IT' - Italy. */ public static final Country IT = of("IT"); /** * The currency 'LU' - Luxembourg. */ public static final Country LU = of("LU"); /** * The currency 'NL' - Netherlands. */ public static final Country NL = of("NL"); /** * The currency 'NO' - Norway. */ public static final Country NO = of("NO"); /** * The currency 'SK' - Slovakia. */ public static final Country SK = of("SK"); /** * The currency 'PL' = Poland. */ public static final Country PL = of("PL"); /** * The currency 'PT' - Portugal. */ public static final Country PT = of("PT"); /** * The currency 'RU' = Russia. */ public static final Country RU = of("RU"); /** * The currency 'SE' - Sweden. */ public static final Country SE = of("SE"); // Americas /** * The country 'AR' - Argentina. */ public static final Country AR = of("AR"); /** * The country 'BR' - Brazil. */ public static final Country BR = of("BR"); /** * The country 'CA' - Canada. */ public static final Country CA = of("CA"); /** * The country 'CL' - Chile. */ public static final Country CL = of("CL"); /** * The country 'MX' - Mexico. */ public static final Country MX = of("MX"); /** * The country 'US' - United States. */ public static final Country US = of("US"); // Asia-Pacific /** * The country 'AU' - Australia. */ public static final Country AU = of("AU"); /** * The country 'CN' - China. */ public static final Country CN = of("CN"); /** * The currency 'HK' - Hong Kong. */ public static final Country HK = of("HK"); /** * The country 'IN' - India. */ public static final Country IN = of("IN"); /** * The country 'JP' - Japan. */ public static final Country JP = of("JP"); /** * The country 'NZ' - New Zealand. */ public static final Country NZ = of("NZ"); /** * The country 'TH' - Thailand. */ public static final Country TH = of("TH"); /** * The country code, not null. */ private final String _code; //----------------------------------------------------------------------- /** * Lists the available countries. * * @return an immutable set containing all registered countries, not null */ public static Set<Country> getAvailableCountries() { return ImmutableSet.copyOf(s_instanceMap.values()); } //----------------------------------------------------------------------- /** * Obtains an instance of {@code Country} for the specified ISO-3166 * three letter currency code dynamically creating an instance if necessary. * <p> * A country is uniquely identified by ISO-3166 two letter code. * This method creates the country object if it is not known. * * @param countryCode the two letter country code, ASCII and upper case, not null * @return the singleton instance, not null * @throws IllegalArgumentException if the country code is not two letters */ @FromString public static Country of(String countryCode) { ArgumentChecker.notNull(countryCode, "countryCode"); if (countryCode.matches("[A-Z][A-Z]") == false) { throw new IllegalArgumentException("Invalid country code: " + countryCode); } s_instanceMap.putIfAbsent(countryCode, new Country(countryCode)); return s_instanceMap.get(countryCode); } /** * Parses a string to obtain a {@code Country}. * <p> * The parse is identical to {@link #of(String)} except that it will convert * letters to upper case first. * * @param countryCode the two letter currency code, ASCII, not null * @return the singleton instance, not null * @throws IllegalArgumentException if the country code is not three letters */ public static Country parse(String countryCode) { ArgumentChecker.notNull(countryCode, "countryCode"); return of(countryCode.toUpperCase(Locale.ENGLISH)); } //------------------------------------------------------------------------- /** * Restricted constructor. * * @param countryCode the two letter country code, not null */ private Country(String countryCode) { _code = countryCode; } /** * Ensure singleton on deserialization. * * @return the singleton, not null */ private Object readResolve() { return of(_code); } //------------------------------------------------------------------------- /** * Gets the two letter ISO code. * * @return the two letter ISO code, not null */ @ToString public String getCode() { return _code; } //------------------------------------------------------------------------- /** * Gets the object identifier for the country. * <p> * This uses the scheme {@link #OBJECT_SCHEME CountryISO}. * * @return the object identifier, not null */ @Override public ObjectId getObjectId() { return ObjectId.of(OBJECT_SCHEME, _code); } /** * Gets the unique identifier for the country. * <p> * This uses the scheme {@link #OBJECT_SCHEME CountryISO}. * * @return the unique identifier, not null */ @Override public UniqueId getUniqueId() { return UniqueId.of(OBJECT_SCHEME, _code); } //----------------------------------------------------------------------- /** * Compares this country to another by alphabetical comparison of the code. * * @param other the other country, not null * @return negative if earlier alphabetically, 0 if equal, positive if greater alphabetically */ @Override public int compareTo(Country other) { return _code.compareTo(other._code); } /** * Checks if this country equals another country. * <p> * The comparison checks the two letter country code. * * @param obj the other country, null returns false * @return true if equal */ @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj instanceof Country) { return _code.equals(((Country) obj)._code); } return false; } /** * Returns a suitable hash code for the country. * * @return the hash code */ @Override public int hashCode() { return _code.hashCode(); } //----------------------------------------------------------------------- /** * Gets the two letter country code as a string. * * @return the two letter country code, not null */ @Override public String toString() { return _code; } }