Add localization support to currencies

This commit is contained in:
Alexey Andreev 2015-05-30 18:24:42 +03:00
parent 04058df517
commit d1739bb196
6 changed files with 161 additions and 1 deletions

View File

@ -208,4 +208,25 @@ public class CLDRHelper {
} }
private static native ResourceMap<CLDRDecimalData> getDecimalDataMap(); private static native ResourceMap<CLDRDecimalData> getDecimalDataMap();
public static CurrencyLocalization resolveCurrency(String language, String country, String currency) {
String localeCode = getCode(language, country);
ResourceMap<ResourceMap<CurrencyLocalization>> map = getCurrencyMap();
if (map.has(localeCode)) {
ResourceMap<CurrencyLocalization> currencies = map.get(localeCode);
if (currencies.has(currency)) {
return currencies.get(currency);
}
}
if (map.has(language)) {
ResourceMap<CurrencyLocalization> currencies = map.get(language);
if (currencies.has(currency)) {
return currencies.get(currency);
}
}
return null;
}
@MetadataProvider(CurrencyLocalizationMetadataGenerator.class)
private static native ResourceMap<ResourceMap<CurrencyLocalization>> getCurrencyMap();
} }

View File

@ -200,7 +200,9 @@ public class CLDRReader {
JsonObject currencyJson = currencyEntry.getValue().getAsJsonObject(); JsonObject currencyJson = currencyEntry.getValue().getAsJsonObject();
CLDRCurrency currency = new CLDRCurrency(); CLDRCurrency currency = new CLDRCurrency();
currency.name = currencyJson.get("displayName").getAsString(); currency.name = currencyJson.get("displayName").getAsString();
currency.symbol = currencyJson.get("symbol").getAsString(); if (currencyJson.has("symbol")) {
currency.symbol = currencyJson.get("symbol").getAsString();
}
locale.currencies.put(currencyCode, currency); locale.currencies.put(currencyCode, currency);
} }
} }

View File

@ -0,0 +1,32 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.impl.unicode;
import org.teavm.platform.metadata.Resource;
/**
*
* @author Alexey Andreev
*/
public interface CurrencyLocalization extends Resource {
String getName();
void setName(String name);
String getSymbol();
void setSymbol(String symbol);
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.impl.unicode;
import java.util.Map;
import org.teavm.model.MethodReference;
import org.teavm.platform.metadata.MetadataGenerator;
import org.teavm.platform.metadata.MetadataGeneratorContext;
import org.teavm.platform.metadata.Resource;
import org.teavm.platform.metadata.ResourceMap;
/**
*
* @author Alexey Andreev
*/
public class CurrencyLocalizationMetadataGenerator implements MetadataGenerator {
@Override
public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) {
CLDRReader reader = context.getService(CLDRReader.class);
ResourceMap<ResourceMap<CurrencyLocalization>> map = context.createResourceMap();
for (Map.Entry<String, CLDRLocale> localeEntry : reader.getKnownLocales().entrySet()) {
CLDRLocale locale = localeEntry.getValue();
ResourceMap<CurrencyLocalization> currencies = context.createResourceMap();
map.put(localeEntry.getKey(), currencies);
for (Map.Entry<String, CLDRCurrency> currencyEntry : locale.getCurrencies().entrySet()) {
CLDRCurrency currency = currencyEntry.getValue();
CurrencyLocalization localization = context.createResource(CurrencyLocalization.class);
localization.setName(currency.getName());
localization.setSymbol(currency.getSymbol() != null ? currency.getSymbol() : "");
currencies.put(currencyEntry.getKey(), localization);
}
}
return map;
}
}

View File

@ -22,6 +22,7 @@ import java.util.Set;
import org.teavm.classlib.impl.currency.CurrencyHelper; import org.teavm.classlib.impl.currency.CurrencyHelper;
import org.teavm.classlib.impl.currency.CurrencyResource; import org.teavm.classlib.impl.currency.CurrencyResource;
import org.teavm.classlib.impl.unicode.CLDRHelper; import org.teavm.classlib.impl.unicode.CLDRHelper;
import org.teavm.classlib.impl.unicode.CurrencyLocalization;
import org.teavm.classlib.java.io.TSerializable; import org.teavm.classlib.java.io.TSerializable;
import org.teavm.platform.metadata.ResourceArray; import org.teavm.platform.metadata.ResourceArray;
import org.teavm.platform.metadata.ResourceMap; import org.teavm.platform.metadata.ResourceMap;
@ -84,6 +85,17 @@ public final class TCurrency implements TSerializable {
return resource.getCode(); return resource.getCode();
} }
public String getSymbol() {
return getSymbol(TLocale.getDefault());
}
public String getSymbol(TLocale locale) {
CurrencyLocalization localization = CLDRHelper.resolveCurrency(locale.getLanguage(), locale.getCountry(),
getCurrencyCode());
return localization != null && !localization.getSymbol().isEmpty() ?
localization.getSymbol() : getCurrencyCode();
}
public int getDefaultFractionDigits() { public int getDefaultFractionDigits() {
return resource.getFractionDigits(); return resource.getFractionDigits();
} }
@ -92,6 +104,16 @@ public final class TCurrency implements TSerializable {
return resource.getNumericCode(); return resource.getNumericCode();
} }
public String getDisplayName() {
return getDisplayName(TLocale.getDefault());
}
public String getDisplayName(TLocale locale) {
CurrencyLocalization localization = CLDRHelper.resolveCurrency(locale.getLanguage(), locale.getCountry(),
getCurrencyCode());
return localization != null ? localization.getName() : getCurrencyCode();
}
@Override @Override
public String toString() { public String toString() {
return resource.getCode(); return resource.getCode();

View File

@ -18,6 +18,7 @@ package org.teavm.classlib.java.util;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.util.Currency; import java.util.Currency;
import java.util.Locale; import java.util.Locale;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
/** /**
@ -45,6 +46,40 @@ public class CurrencyTest {
assertEquals("GBP", currency.getCurrencyCode()); assertEquals("GBP", currency.getCurrencyCode());
} }
@Test
@Ignore
// It seems that JDK can't translate currency names into Russian
public void getsDisplayName() {
Locale russian = new Locale("ru");
Locale english = new Locale("en");
Currency currency = Currency.getInstance("USD");
assertEquals("US Dollar", currency.getDisplayName(english));
assertEquals("Доллар США", currency.getDisplayName(russian));
currency = Currency.getInstance("RUB");
assertEquals("Russian Ruble", currency.getDisplayName(english));
assertEquals("Российский рубль", currency.getDisplayName(russian));
assertEquals("CHF", Currency.getInstance("CHF").getDisplayName(new Locale("xx", "YY")));
}
@Test
@Ignore
// It seems that JDK does not know about currency symbols
public void getsSymbol() {
Locale russian = new Locale("ru");
Locale english = new Locale("en");
Currency currency = Currency.getInstance("USD");
assertEquals("$", currency.getSymbol(english));
assertEquals("$", currency.getSymbol(russian));
currency = Currency.getInstance("RUB");
assertEquals("RUB", currency.getSymbol(english));
assertEquals("руб.", currency.getSymbol(russian));
}
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void rejectsWrongCode() { public void rejectsWrongCode() {
Currency.getInstance("WWW"); Currency.getInstance("WWW");