Add support for NumberFormat.get*Format methods

This commit is contained in:
Alexey Andreev 2015-06-20 18:37:48 +03:00
parent dbd2c3f6bc
commit 4e5e4af3e6
8 changed files with 169 additions and 10 deletions

View File

@ -173,20 +173,23 @@ public class CLDRHelper {
return resolveFormatSymbols(getNumberFormatMap(), language, country); return resolveFormatSymbols(getNumberFormatMap(), language, country);
} }
@MetadataProvider(NumberFormatMetadataGenerator.class)
private static native ResourceMap<StringResource> getNumberFormatMap(); private static native ResourceMap<StringResource> getNumberFormatMap();
public static String resolveDecimalFormat(String language, String country) {
return resolveFormatSymbols(getDecimalFormatMap(), language, country);
}
private static native ResourceMap<StringResource> getDecimalFormatMap();
public static String resolvePercentFormat(String language, String country) { public static String resolvePercentFormat(String language, String country) {
return resolveFormatSymbols(getPercentFormatMap(), language, country); return resolveFormatSymbols(getPercentFormatMap(), language, country);
} }
@MetadataProvider(NumberFormatMetadataGenerator.class)
private static native ResourceMap<StringResource> getPercentFormatMap(); private static native ResourceMap<StringResource> getPercentFormatMap();
public static String resolveCurrencyFormat(String language, String country) {
return resolveFormatSymbols(getCurrencyFormatMap(), language, country);
}
@MetadataProvider(NumberFormatMetadataGenerator.class)
private static native ResourceMap<StringResource> getCurrencyFormatMap();
private static DateFormatCollection resolveDateFormats(ResourceMap<DateFormatCollection> map, private static DateFormatCollection resolveDateFormats(ResourceMap<DateFormatCollection> map,
String language, String country) { String language, String country) {
String localeCode = getCode(language, country); String localeCode = getCode(language, country);

View File

@ -39,6 +39,9 @@ public class CLDRLocale {
CLDRDateFormats dateTimeFormats; CLDRDateFormats dateTimeFormats;
CLDRTimeZone[] timeZones; CLDRTimeZone[] timeZones;
CLDRDecimalData decimalData = new CLDRDecimalData(); CLDRDecimalData decimalData = new CLDRDecimalData();
String numberFormat;
String percentFormat;
String currencyFormat;
public Map<String, String> getLanguages() { public Map<String, String> getLanguages() {
return Collections.unmodifiableMap(languages); return Collections.unmodifiableMap(languages);
@ -95,4 +98,16 @@ public class CLDRLocale {
public CLDRDecimalData getDecimalData() { public CLDRDecimalData getDecimalData() {
return decimalData; return decimalData;
} }
public String getNumberFormat() {
return numberFormat;
}
public String getPercentFormat() {
return percentFormat;
}
public String getCurrencyFormat() {
return currencyFormat;
}
} }

View File

@ -225,6 +225,15 @@ public class CLDRReader {
locale.decimalData.perMille = symbolsJson.get("perMille").getAsString().charAt(0); locale.decimalData.perMille = symbolsJson.get("perMille").getAsString().charAt(0);
locale.decimalData.infinity = symbolsJson.get("infinity").getAsString(); locale.decimalData.infinity = symbolsJson.get("infinity").getAsString();
locale.decimalData.NaN = symbolsJson.get("nan").getAsString(); locale.decimalData.NaN = symbolsJson.get("nan").getAsString();
JsonObject numberJson = numbersJson.get("decimalFormats-numberSystem-" + numbering).getAsJsonObject();
locale.numberFormat = numberJson.get("standard").getAsString();
JsonObject percentJson = numbersJson.get("percentFormats-numberSystem-" + numbering).getAsJsonObject();
locale.percentFormat = percentJson.get("standard").getAsString();
JsonObject currencyJson = numbersJson.get("currencyFormats-numberSystem-" + numbering).getAsJsonObject();
locale.currencyFormat = currencyJson.get("standard").getAsString();
} }
private void readEras(String localeCode, CLDRLocale locale, JsonObject root) { private void readEras(String localeCode, CLDRLocale locale, JsonObject root) {

View File

@ -29,7 +29,7 @@ public class DefaultLocaleMetadataGenerator implements MetadataGenerator {
@Override @Override
public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) { public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) {
StringResource result = context.createResource(StringResource.class); StringResource result = context.createResource(StringResource.class);
result.setValue(context.getProperties().getProperty("java.util.Locale.default", "en_EN")); result.setValue(context.getProperties().getProperty("java.util.Locale.default", "en_GB"));
return result; return result;
} }
} }

View File

@ -0,0 +1,72 @@
/*
* 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;
import org.teavm.platform.metadata.StringResource;
/**
*
* @author Alexey Andreev
*/
public class NumberFormatMetadataGenerator implements MetadataGenerator {
@Override
public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) {
CLDRReader reader = context.getService(CLDRReader.class);
ResourceMap<StringResource> result = context.createResourceMap();
FormatAccessor accessor;
switch (method.getName()) {
case "getNumberFormatMap":
accessor = new FormatAccessor() {
@Override public String getFormat(CLDRLocale locale) {
return locale.numberFormat;
}
};
break;
case "getCurrencyFormatMap":
accessor = new FormatAccessor() {
@Override public String getFormat(CLDRLocale locale) {
return locale.currencyFormat;
}
};
break;
case "getPercentFormatMap":
accessor = new FormatAccessor() {
@Override public String getFormat(CLDRLocale locale) {
return locale.percentFormat;
}
};
break;
default:
throw new AssertionError();
}
for (Map.Entry<String, CLDRLocale> entry : reader.getKnownLocales().entrySet()) {
StringResource format = context.createResource(StringResource.class);
format.setValue(accessor.getFormat(entry.getValue()));
result.put(entry.getKey(), format);
}
return result;
}
interface FormatAccessor {
String getFormat(CLDRLocale locale);
}
}

View File

@ -51,7 +51,7 @@ public class TDecimalFormat extends TNumberFormat {
int exponentDigits; int exponentDigits;
public TDecimalFormat() { public TDecimalFormat() {
this(CLDRHelper.resolveDecimalFormat(TLocale.getDefault().getLanguage(), TLocale.getDefault().getCountry())); this(CLDRHelper.resolveNumberFormat(TLocale.getDefault().getLanguage(), TLocale.getDefault().getCountry()));
} }
public TDecimalFormat(String pattern) { public TDecimalFormat(String pattern) {
@ -1227,9 +1227,13 @@ public class TDecimalFormat extends TNumberFormat {
static class CurrencyField implements FormatField { static class CurrencyField implements FormatField {
@Override @Override
public void render(TDecimalFormat format, StringBuffer buffer) { public void render(TDecimalFormat format, StringBuffer buffer) {
if (format.getCurrency() == null) {
buffer.append('¤');
} else {
buffer.append(format.getCurrency().getSymbol(format.symbols.getLocale())); buffer.append(format.getCurrency().getSymbol(format.symbols.getLocale()));
} }
} }
}
static class PercentField implements FormatField { static class PercentField implements FormatField {
@Override @Override

View File

@ -106,6 +106,9 @@ public abstract class TNumberFormat extends TFormat {
String pattern = CLDRHelper.resolveNumberFormat(locale.getLanguage(), locale.getCountry()); String pattern = CLDRHelper.resolveNumberFormat(locale.getLanguage(), locale.getCountry());
TDecimalFormat format = new TDecimalFormat(pattern, new TDecimalFormatSymbols(locale)); TDecimalFormat format = new TDecimalFormat(pattern, new TDecimalFormatSymbols(locale));
format.setParseIntegerOnly(true); format.setParseIntegerOnly(true);
format.setMinimumFractionDigits(0);
format.setMaximumFractionDigits(0);
format.setDecimalSeparatorAlwaysShown(false);
return format; return format;
} }
@ -138,7 +141,7 @@ public abstract class TNumberFormat extends TFormat {
} }
public static TNumberFormat getNumberInstance(TLocale locale) { public static TNumberFormat getNumberInstance(TLocale locale) {
String pattern = CLDRHelper.resolveDecimalFormat(locale.getLanguage(), locale.getCountry()); String pattern = CLDRHelper.resolveNumberFormat(locale.getLanguage(), locale.getCountry());
return new TDecimalFormat(pattern, new TDecimalFormatSymbols(locale)); return new TDecimalFormat(pattern, new TDecimalFormatSymbols(locale));
} }
@ -151,6 +154,15 @@ public abstract class TNumberFormat extends TFormat {
return new TDecimalFormat(pattern, new TDecimalFormatSymbols(locale)); return new TDecimalFormat(pattern, new TDecimalFormatSymbols(locale));
} }
public final static TNumberFormat getCurrencyInstance() {
return getCurrencyInstance(TLocale.getDefault());
}
public final static TNumberFormat getCurrencyInstance(TLocale locale) {
String pattern = CLDRHelper.resolveCurrencyFormat(locale.getLanguage(), locale.getCountry());
return new TDecimalFormat(pattern, new TDecimalFormatSymbols(locale));
}
@Override @Override
public int hashCode() { public int hashCode() {
return (groupingUsed ? 1231 : 1237) + (parseIntegerOnly ? 1231 : 1237) return (groupingUsed ? 1231 : 1237) + (parseIntegerOnly ? 1231 : 1237)

View File

@ -0,0 +1,44 @@
package org.teavm.classlib.java.text;
import static org.junit.Assert.*;
import java.text.NumberFormat;
import java.util.Currency;
import java.util.Locale;
import org.junit.Ignore;
import org.junit.Test;
/**
*
* @author Alexey Andreev
*/
public class NumberFormatTest {
@Test
public void formatsNumber() {
NumberFormat format = NumberFormat.getNumberInstance(new Locale("en"));
assertEquals("123,456.789", format.format(123456.789123));
format = NumberFormat.getNumberInstance(new Locale("ru"));
assertEquals("123\u00A0456,789", format.format(123456.789123));
}
@Test
public void formatsCurrency() {
NumberFormat format = NumberFormat.getCurrencyInstance(new Locale("en", "US"));
format.setCurrency(Currency.getInstance("RUB"));
assertEquals("RUB123,456.79", format.format(123456.789123));
format = NumberFormat.getCurrencyInstance(new Locale("ru", "RU"));
format.setCurrency(Currency.getInstance("RUB"));
assertEquals("123 456,79 руб.", format.format(123456.789123).replace('\u00A0', ' '));
}
@Test
@Ignore
public void formatsPercent() {
NumberFormat format = NumberFormat.getPercentInstance(new Locale("en", "US"));
assertEquals("12,345,679%", format.format(123456.789123));
format = NumberFormat.getPercentInstance(new Locale("ru", "RU"));
assertEquals("12 345 679 %", format.format(123456.789123).replace('\u00A0', ' '));
}
}