开发者

Java 6 redefining currency symbol (via CurrencyNameProvider?)

Recently Sun/Oracle changed currency code for Ukrainian hrivna to incorrect one and I've to fix that in my code.

I find out that Java 6 should allows me to do that at Java level (details are here) via CurrencyNameProvider (see also).

Unfortunately I don't understand which locales should return meth开发者_如何学Good

public Locale[] getAvailableLocales() {}

Any working examples are welcome!


// Be aware that you need to provide ukrainian names to ALL currency symbols which
// your program uses.

import java.util.Locale;
import java.util.spi.CurrencyNameProvider;

public class UaCurrencyNameProvider extends CurrencyNameProvider {

    private static final Locale UKRAINE = new Locale("uk", "UA");
    private static final String UAH_SYMB = "грн.";
    private Locale[] availableLocales = new Locale[] {UKRAINE};

    @Override
    public Locale[] getAvailableLocales() {
        return availableLocales;
    }

    @Override
    public String getSymbol(String currencyCode, Locale locale) {
        if(currencyCode == null) {
            throw new NullPointerException();
        }
        else if(!UKRAINE.equals(locale)) {
            throw new IllegalArgumentException("Locale not supported");
        }
        else if("UAH".equals(currencyCode)) {
            return UAH_SYMB;
        } else {
            return null;
        }
    }
}


LocaleServiceProvider:Locale sensitive factory methods and methods for name retrieval in the java.text and java.util packages invoke service provider methods when needed to support the requested locale. The methods first check whether the Java runtime environment itself supports the requested locale, and use its support if available. Otherwise, they call the getAvailableLocales() methods of installed providers for the appropriate interface to find one that supports the requested locale.

So if the JRE has support for the requested Locale, you cannot override it with a custom provider in your extension, because the default providers will be asked first.

Example, which tries to provide a new symbol for UAH for Locale xx_YY BungaBunga and uk_UA ungarn$$$ :

public class UkCurrencyNameProvider extends CurrencyNameProvider {
private static final Locale XX_YY = new Locale("xx", "YY");
private static final Locale UK_UA = new Locale("uk", "UA");
private static final Map<Locale, String> SYMBOL_MAP;
static {
SYMBOL_MAP = new HashMap<Locale, String>();
UkCurrencyNameProvider.SYMBOL_MAP.put(UkCurrencyNameProvider.XX_YY,
        "BungaBunga");
UkCurrencyNameProvider.SYMBOL_MAP.put(UK_UA, "ungarn$$$");
}
private static final Locale[] AVAILABLE_LOCALES = UkCurrencyNameProvider.SYMBOL_MAP
        .keySet().toArray(
                new Locale[UkCurrencyNameProvider.SYMBOL_MAP.size()]);

/*
 * (non-Javadoc)
 * @see java.util.spi.CurrencyNameProvider#getSymbol(java.lang.String,
 * java.util.Locale)
 */
@Override
public String getSymbol(final String currencyCode, final Locale locale) {
    final String result;
    if ("UAH".equals(currencyCode)) {
    result = UkCurrencyNameProvider.SYMBOL_MAP.get(locale);
    } else {
    result = null;
    }
    return result;
}

/*
 * (non-Javadoc)
 * @see java.util.spi.LocaleServiceProvider#getAvailableLocales()
 */
@Override
public Locale[] getAvailableLocales() {
    return UkCurrencyNameProvider.AVAILABLE_LOCALES.clone();

}

}

The code

Locale[] test=new Locale[] {new Locale("xx","YY"),new Locale("uk","UA")};
for (Locale loc:test)
 {System.out.println(loc+": "+Currency.getInstance("UAH").getSymbol(loc));}

will output

xx_YY: BungaBunga

uk_UA: грл.

because the standard JRE knows about uk_UA and will provide its already known currency symbol грл.. For xx_YY the JRE has none information and will ask the providers in the extension. The custom provider will return BungaBunga.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜