Java 6 переопределение символа валюты (через CurrencyNameProvider?)
Недавно Sun/Oracle изменила код валюты для украинской гривны на неправильный, и я должен это исправить в своем коде.
Я обнаружил, что Java 6 должна позволять мне делать это на уровне Java (подробности здесь) через CurrencyNameProvider ( см. Также).
К сожалению, я не понимаю, какие локали должны возвращать метод
public Locale[] getAvailableLocales() {}
Любые рабочие примеры приветствуются!
2 ответа
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.
Таким образом, если JRE поддерживает запрошенный языковой стандарт, вы не можете переопределить его с помощью собственного поставщика в вашем расширении, потому что сначала будут заданы стандартные поставщики.
Пример, который пытается предоставить новый символ для UAH
для локали xx_YY
Бунга Бунга и 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();
}
}
Код
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));}
будет выводить
xx_YY: Бунга Бунга
uk_UA: грл.
потому что стандарт JRE знает о uk_UA и предоставит его уже известный символ валюты грл., Для xx_YY JRE не имеет информации и спросит поставщиков в расширении. Таможенный поставщик вернет BungaBunga.
// 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;
}
}
}