mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-09 08:24:10 -08:00
Add support of ISO 3166
This commit is contained in:
parent
eb4e74a778
commit
1cc1d60f9e
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* 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.currency;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
import org.teavm.platform.metadata.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public class CountriesGenerator implements MetadataGenerator {
|
||||||
|
@Override
|
||||||
|
public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) {
|
||||||
|
try (InputStream input = context.getClassLoader().getResourceAsStream(
|
||||||
|
"org/teavm/classlib/impl/currency/iso3166.csv")) {
|
||||||
|
if (input == null) {
|
||||||
|
throw new AssertionError("ISO 3166 table was not found");
|
||||||
|
}
|
||||||
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(input, "UTF-8"))) {
|
||||||
|
return readIso3166(context, reader);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Error reading ISO 3166 table", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResourceMap<StringResource> readIso3166(MetadataGeneratorContext context, BufferedReader reader)
|
||||||
|
throws IOException {
|
||||||
|
ResourceMap<StringResource> result = context.createResourceMap();
|
||||||
|
int index = 0;
|
||||||
|
while (true) {
|
||||||
|
String line = reader.readLine();
|
||||||
|
if (line == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (index++ == 0 || line.trim().isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String[] cells = readCsvRow(index - 1, line);
|
||||||
|
StringResource currency = context.createResource(StringResource.class);
|
||||||
|
currency.setValue(cells[7]);
|
||||||
|
result.put(cells[10], currency);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] readCsvRow(int rowIndex, String row) {
|
||||||
|
List<String> values = new ArrayList<>();
|
||||||
|
int index = 0;
|
||||||
|
while (index < row.length()) {
|
||||||
|
char c = row.charAt(index);
|
||||||
|
int next = index;
|
||||||
|
if (c == '"') {
|
||||||
|
++index;
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
while (index < row.length()) {
|
||||||
|
next = row.indexOf('"', index);
|
||||||
|
if (next == -1) {
|
||||||
|
throw new IllegalStateException("Syntax error at row " + rowIndex +
|
||||||
|
": closing quote not found");
|
||||||
|
}
|
||||||
|
if (next + 1 == row.length() || row.charAt(next + 1) != '"') {
|
||||||
|
sb.append(row.substring(index, next));
|
||||||
|
index = next + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index = next + 2;
|
||||||
|
}
|
||||||
|
if (index < row.length() && row.charAt(index) != ',') {
|
||||||
|
throw new IllegalStateException("Syntax error at row " + rowIndex + ": closing quote must be " +
|
||||||
|
"followed by either line separator or comma");
|
||||||
|
}
|
||||||
|
values.add(sb.toString());
|
||||||
|
} else {
|
||||||
|
next = row.indexOf(',', index);
|
||||||
|
if (next == -1) {
|
||||||
|
values.add(row.substring(index));
|
||||||
|
index = row.length();
|
||||||
|
} else {
|
||||||
|
values.add(row.substring(index, next));
|
||||||
|
++next;
|
||||||
|
index = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values.toArray(new String[values.size()]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,8 @@ package org.teavm.classlib.impl.currency;
|
||||||
|
|
||||||
import org.teavm.platform.metadata.MetadataProvider;
|
import org.teavm.platform.metadata.MetadataProvider;
|
||||||
import org.teavm.platform.metadata.ResourceArray;
|
import org.teavm.platform.metadata.ResourceArray;
|
||||||
|
import org.teavm.platform.metadata.ResourceMap;
|
||||||
|
import org.teavm.platform.metadata.StringResource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -25,4 +27,7 @@ import org.teavm.platform.metadata.ResourceArray;
|
||||||
public final class CurrencyHelper {
|
public final class CurrencyHelper {
|
||||||
@MetadataProvider(CurrenciesGenerator.class)
|
@MetadataProvider(CurrenciesGenerator.class)
|
||||||
public static native ResourceArray<CurrencyResource> getCurrencies();
|
public static native ResourceArray<CurrencyResource> getCurrencies();
|
||||||
|
|
||||||
|
@MetadataProvider(CountriesGenerator.class)
|
||||||
|
public static native ResourceMap<StringResource> getCountryToCurrencyMap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,15 @@ public class CLDRHelper {
|
||||||
return map.has(localeCode) ? map.get(localeCode).getValue() : localeCode;
|
return map.has(localeCode) ? map.get(localeCode).getValue() : localeCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String resolveCountry(String language, String country) {
|
||||||
|
if (country.isEmpty()) {
|
||||||
|
String subtags = getLikelySubtags(language);
|
||||||
|
int index = subtags.lastIndexOf('_');
|
||||||
|
country = index > 0 ? subtags.substring(index + 1) : "";
|
||||||
|
}
|
||||||
|
return country;
|
||||||
|
}
|
||||||
|
|
||||||
@MetadataProvider(LikelySubtagsMetadataGenerator.class)
|
@MetadataProvider(LikelySubtagsMetadataGenerator.class)
|
||||||
private static native ResourceMap<StringResource> getLikelySubtagsMap();
|
private static native ResourceMap<StringResource> getLikelySubtagsMap();
|
||||||
|
|
||||||
|
|
|
@ -175,21 +175,11 @@ public abstract class TCalendar implements TSerializable, TCloneable, TComparabl
|
||||||
cacheFor = locale;
|
cacheFor = locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String resolveCountry(TLocale locale) {
|
|
||||||
String country = locale.getCountry();
|
|
||||||
if (country.isEmpty()) {
|
|
||||||
String subtags = CLDRHelper.getLikelySubtags(locale.getLanguage());
|
|
||||||
int index = subtags.lastIndexOf('_');
|
|
||||||
country = index > 0 ? subtags.substring(index + 1) : "";
|
|
||||||
}
|
|
||||||
return country;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int resolveFirstDayOfWeek(TLocale locale) {
|
private static int resolveFirstDayOfWeek(TLocale locale) {
|
||||||
if (locale == cacheFor && firstDayOfWeekCache >= 0) {
|
if (locale == cacheFor && firstDayOfWeekCache >= 0) {
|
||||||
return firstDayOfWeekCache;
|
return firstDayOfWeekCache;
|
||||||
}
|
}
|
||||||
String country = resolveCountry(locale);
|
String country = CLDRHelper.resolveCountry(locale.getLanguage(), locale.getCountry());
|
||||||
ResourceMap<IntResource> dayMap = CLDRHelper.getFirstDayOfWeek();
|
ResourceMap<IntResource> dayMap = CLDRHelper.getFirstDayOfWeek();
|
||||||
firstDayOfWeekCache = dayMap.has(country) ? dayMap.get(country).getValue() : dayMap.get("001").getValue();
|
firstDayOfWeekCache = dayMap.has(country) ? dayMap.get(country).getValue() : dayMap.get("001").getValue();
|
||||||
return firstDayOfWeekCache;
|
return firstDayOfWeekCache;
|
||||||
|
@ -199,7 +189,7 @@ public abstract class TCalendar implements TSerializable, TCloneable, TComparabl
|
||||||
if (locale == cacheFor && minimalDaysInFirstWeekCache >= 0) {
|
if (locale == cacheFor && minimalDaysInFirstWeekCache >= 0) {
|
||||||
return minimalDaysInFirstWeekCache;
|
return minimalDaysInFirstWeekCache;
|
||||||
}
|
}
|
||||||
String country = resolveCountry(locale);
|
String country = CLDRHelper.resolveCountry(locale.getLanguage(), locale.getCountry());
|
||||||
ResourceMap<IntResource> dayMap = CLDRHelper.getMinimalDaysInFirstWeek();
|
ResourceMap<IntResource> dayMap = CLDRHelper.getMinimalDaysInFirstWeek();
|
||||||
minimalDaysInFirstWeekCache = dayMap.has(country) ? dayMap.get(country).getValue() :
|
minimalDaysInFirstWeekCache = dayMap.has(country) ? dayMap.get(country).getValue() :
|
||||||
dayMap.get("001").getValue();
|
dayMap.get("001").getValue();
|
||||||
|
|
|
@ -21,8 +21,11 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
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.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.StringResource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -60,6 +63,18 @@ public final class TCurrency implements TSerializable {
|
||||||
return currency;
|
return currency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TCurrency getInstance(TLocale locale) {
|
||||||
|
if (locale == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
String coutry = CLDRHelper.resolveCountry(locale.getLanguage(), locale.getCountry());
|
||||||
|
ResourceMap<StringResource> countryMap = CurrencyHelper.getCountryToCurrencyMap();
|
||||||
|
if (!countryMap.has(coutry)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return getInstance(countryMap.get(coutry).getValue());
|
||||||
|
}
|
||||||
|
|
||||||
public static Set<TCurrency> getAvailableCurrencies() {
|
public static Set<TCurrency> getAvailableCurrencies() {
|
||||||
initCurrencies();
|
initCurrencies();
|
||||||
return new HashSet<>(currencies.values());
|
return new HashSet<>(currencies.values());
|
||||||
|
|
|
@ -17,6 +17,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 org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,6 +33,18 @@ public class CurrencyTest {
|
||||||
assertEquals(643, currency.getNumericCode());
|
assertEquals(643, currency.getNumericCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findsByLocale() {
|
||||||
|
Currency currency = Currency.getInstance(new Locale("ru", "RU"));
|
||||||
|
assertEquals("RUB", currency.getCurrencyCode());
|
||||||
|
|
||||||
|
currency = Currency.getInstance(new Locale("en", "US"));
|
||||||
|
assertEquals("USD", currency.getCurrencyCode());
|
||||||
|
|
||||||
|
currency = Currency.getInstance(new Locale("en", "GB"));
|
||||||
|
assertEquals("GBP", currency.getCurrencyCode());
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void rejectsWrongCode() {
|
public void rejectsWrongCode() {
|
||||||
Currency.getInstance("WWW");
|
Currency.getInstance("WWW");
|
||||||
|
|
Loading…
Reference in New Issue
Block a user