--- old/src/java.base/share/classes/java/util/Locale.java 2016-12-02 15:54:54.000000000 +0530 +++ new/src/java.base/share/classes/java/util/Locale.java 2016-12-02 15:54:54.000000000 +0530 @@ -46,6 +46,7 @@ import java.io.ObjectStreamField; import java.io.Serializable; import java.text.MessageFormat; +import java.util.concurrent.ConcurrentHashMap; import java.util.spi.LocaleNameProvider; import sun.security.action.GetPropertyAction; @@ -600,6 +601,70 @@ static final long serialVersionUID = 9149081749638150636L; /** + * Enum for specifying the type defined in ISO 3166. This enum is used to + * retrieve the two-letter ISO3166-1 alpha-2, three-letter ISO3166-1 + * alpha-3, four-letter ISO3166-3 country codes. + * + * @see #getISOCountries(Locale.IsoCountryCode) + * @since 9 + */ + public static enum IsoCountryCode { + /** + * PART1_ALPHA2 is used to represent the ISO3166-1 alpha-2 two letter + * country codes. + */ + PART1_ALPHA2 { + @Override + Set getISOCountriesImpl() { + return Set.of(Locale.getISOCountries()); + } + }, + + /** + * + * PART1_ALPHA3 is used to represent the ISO3166-1 alpha-3 three letter + * country codes. + */ + + PART1_ALPHA3 { + @Override + Set getISOCountriesImpl() { + return LocaleISOData.computeISO3166_1Alpha3Countries(); + } + }, + + /** + * PART3 is used to represent the ISO3166-3 four letter country codes. + */ + + PART3 { + @Override + Set getISOCountriesImpl() { + return Set.of(LocaleISOData.ISO3166_3); + } + }; + + /** + * Concrete implementation of this mapping function attempts to compute value + * for iso3166CodesMap for each IsoCountryCode type key. + */ + abstract Set getISOCountriesImpl(); + + /** + * Map to hold country codes for each ISO3166 part. + */ + private static Map> iso3166CodesMap = new ConcurrentHashMap<>(); + + /** + * This method is called from Locale class to retrieve country code set + * for getISOCountries(type) + */ + static Set retrieveISOCountryCodes(IsoCountryCode type) { + return iso3166CodesMap.computeIfAbsent(type, IsoCountryCode::getISOCountriesImpl); + } + } + + /** * Display types for retrieving localized names from the name providers. */ private static final int DISPLAY_LANGUAGE = 0; @@ -996,12 +1061,18 @@ /** * Returns a list of all 2-letter country codes defined in ISO 3166. * Can be used to create Locales. + * This method is equivalent to {@link #getISOCountries(Locale.IsoCountryCode type)} + * with {@code type} {@link IsoCountryCode#PART1_ALPHA2}. *

* Note: The Locale class also supports other codes for * country (region), such as 3-letter numeric UN M.49 area codes. * Therefore, the list returned by this method does not contain ALL valid * codes that can be used to create Locales. - * + *

+ * Note that this method does not return obsolete 2-letter country codes. + * ISO3166-3 codes which designate country codes for those obsolete codes, + * can be retrieved from {@link #getISOCountries(Locale.IsoCountryCode type)} with + * {@code type} {@link IsoCountryCode#PART3}. * @return An array of ISO 3166 two-letter country codes. */ public static String[] getISOCountries() { @@ -1014,6 +1085,20 @@ } /** + * Returns a {@code Set} of ISO3166 country codes for the specified type. + * + * @param type {@link Locale.IsoCountryCode} specified ISO code type. + * @see java.util.Locale.IsoCountryCode + * @throws NullPointerException if type is null + * @return a {@code Set} of ISO country codes for the specified type. + * @since 9 + */ + public static Set getISOCountries(IsoCountryCode type) { + Objects.requireNonNull(type); + return IsoCountryCode.retrieveISOCountryCodes(type); + } + + /** * Returns a list of all 2-letter language codes defined in ISO 639. * Can be used to create Locales. *