diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRDecimalData.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRDecimalData.java new file mode 100644 index 000000000..77777ad42 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRDecimalData.java @@ -0,0 +1,40 @@ +/* + * Copyright 2014 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 CLDRDecimalData extends Resource { + int getMaximumFractionDigits(); + + void setMaximumFractionDigits(int value); + + int getMaximumIntegerDigits(); + + void setMaximumIntegerDigits(int value); + + int getMinimumFractionDigits(); + + void setMinimumFractionDigits(int value); + + int getMinimumIntegerDigits(); + + void setMinimumIntegerDigits(int value); +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormat.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormat.java new file mode 100644 index 000000000..cb237ce16 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormat.java @@ -0,0 +1,68 @@ +/* + * Copyright 2014 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.java.text; + +import java.text.DecimalFormatSymbols; +import org.teavm.classlib.impl.unicode.CLDRDecimalData; +import org.teavm.classlib.impl.unicode.CLDRHelper; +import org.teavm.classlib.java.util.TLocale; + +/** + * + * @author Alexey Andreev + */ +public class TDecimalFormat extends TNumberFormat { + private transient boolean parseBigDecimal = false; + private transient TDecimalFormatSymbols symbols; + + public TDecimalFormat() { + this(CLDRHelper.resolveDecimalFormat(TLocale.getDefault().getLanguage(), TLocale.getDefault().getCountry())); + } + + public TDecimalFormat(String pattern) { + this(pattern, new TDecimalFormatSymbols()); + } + + public TDecimalFormat(String pattern, TDecimalFormatSymbols value) { + symbols = (TDecimalFormatSymbols) value.clone(); + TLocale locale = symbols.getLocale(); + + CLDRDecimalData decimalData = CLDRHelper.resolveDecimalData(locale.getLanguage(), locale.getCountry()); + super.setMaximumFractionDigits(decimalData.getMaximumFractionDigits()); + super.setMaximumIntegerDigits(decimalData.getMaximumIntegerDigits()); + super.setMinimumFractionDigits(decimalData.getMinimumFractionDigits()); + super.setMinimumIntegerDigits(decimalData.getMinimumIntegerDigits()); + } + + public DecimalFormatSymbols getDecimalFormatSymbols() { + return (DecimalFormatSymbols) symbols.clone(); + } + + @Override + public StringBuffer format(double value, StringBuffer buffer, TFieldPosition field) { + return null; + } + + @Override + public StringBuffer format(long value, StringBuffer buffer, TFieldPosition field) { + return null; + } + + @Override + public Number parse(String string, TParsePosition position) { + return null; + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormatSymbols.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormatSymbols.java new file mode 100644 index 000000000..68b19d26d --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormatSymbols.java @@ -0,0 +1,40 @@ +/* + * Copyright 2014 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.java.text; + +import org.teavm.classlib.java.util.TLocale; + +/** + * + * @author Alexey Andreev + */ +public class TDecimalFormatSymbols { + public TDecimalFormatSymbols() { + + } + + public TDecimalFormatSymbols(TLocale locale) { + + } + + public TLocale getLocale() { + return null; + } + + public Object clone() { + return null; + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TNumberFormat.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TNumberFormat.java new file mode 100644 index 000000000..7fd558fa5 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/text/TNumberFormat.java @@ -0,0 +1,232 @@ +/* + * Copyright 2014 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.java.text; + +import org.teavm.classlib.impl.unicode.CLDRHelper; +import org.teavm.classlib.java.util.TLocale; + +/** + * + * @author Alexey Andreev + */ +public abstract class TNumberFormat extends TFormat { + public static final int INTEGER_FIELD = 0; + public static final int FRACTION_FIELD = 1; + private boolean groupingUsed = true, parseIntegerOnly = false; + private int maximumIntegerDigits = 40, minimumIntegerDigits = 1, + maximumFractionDigits = 3, minimumFractionDigits = 0; + + public TNumberFormat() { + } + + @Override + public Object clone() { + return super.clone(); + } + + @Override + public boolean equals(Object object) { + if (object == this) { + return true; + } + if (!(object instanceof TNumberFormat)) { + return false; + } + TNumberFormat obj = (TNumberFormat) object; + return groupingUsed == obj.groupingUsed + && parseIntegerOnly == obj.parseIntegerOnly + && maximumFractionDigits == obj.maximumFractionDigits + && maximumIntegerDigits == obj.maximumIntegerDigits + && minimumFractionDigits == obj.minimumFractionDigits + && minimumIntegerDigits == obj.minimumIntegerDigits; + } + + public final String format(double value) { + return format(value, new StringBuffer(), new TFieldPosition(0)).toString(); + } + + public abstract StringBuffer format(double value, StringBuffer buffer, TFieldPosition field); + + public final String format(long value) { + return format(value, new StringBuffer(), new TFieldPosition(0)).toString(); + } + + public abstract StringBuffer format(long value, StringBuffer buffer, TFieldPosition field); + + @Override + public StringBuffer format(Object object, StringBuffer buffer, TFieldPosition field) { + if (object instanceof Number) { + double dv = ((Number) object).doubleValue(); + long lv = ((Number) object).longValue(); + if (dv == lv) { + return format(lv, buffer, field); + } + return format(dv, buffer, field); + } + throw new IllegalArgumentException(); + } + + public static TLocale[] getAvailableLocales() { + return TLocale.getAvailableLocales(); + } + + public final static TNumberFormat getIntegerInstance() { + return getIntegerInstance(TLocale.getDefault()); + } + + public static TNumberFormat getIntegerInstance(TLocale locale) { + String pattern = CLDRHelper.resolveNumberFormat(locale.getLanguage(), locale.getCountry()); + TDecimalFormat format = new TDecimalFormat(pattern, new TDecimalFormatSymbols(locale)); + format.setParseIntegerOnly(true); + return format; + } + + public final static TNumberFormat getInstance() { + return getNumberInstance(); + } + + public static TNumberFormat getInstance(TLocale locale) { + return getNumberInstance(locale); + } + + public int getMaximumFractionDigits() { + return maximumFractionDigits; + } + + public int getMaximumIntegerDigits() { + return maximumIntegerDigits; + } + + public int getMinimumFractionDigits() { + return minimumFractionDigits; + } + + public int getMinimumIntegerDigits() { + return minimumIntegerDigits; + } + + public final static TNumberFormat getNumberInstance() { + return getNumberInstance(TLocale.getDefault()); + } + + public static TNumberFormat getNumberInstance(TLocale locale) { + String pattern = CLDRHelper.resolveDecimalFormat(locale.getLanguage(), locale.getCountry()); + return new TDecimalFormat(pattern, new TDecimalFormatSymbols(locale)); + } + + public final static TNumberFormat getPercentInstance() { + return getPercentInstance(TLocale.getDefault()); + } + + public static TNumberFormat getPercentInstance(TLocale locale) { + String pattern = CLDRHelper.resolvePercentFormat(locale.getLanguage(), locale.getCountry()); + return new TDecimalFormat(pattern, new TDecimalFormatSymbols(locale)); + } + + @Override + public int hashCode() { + return (groupingUsed ? 1231 : 1237) + (parseIntegerOnly ? 1231 : 1237) + + maximumFractionDigits + maximumIntegerDigits + + minimumFractionDigits + minimumIntegerDigits; + } + + public boolean isGroupingUsed() { + return groupingUsed; + } + + public boolean isParseIntegerOnly() { + return parseIntegerOnly; + } + + public Number parse(String string) throws TParseException { + TParsePosition pos = new TParsePosition(0); + Number number = parse(string, pos); + if (pos.getIndex() == 0) { + // text.1D=: {0} + throw new TParseException("Unparseable number: " + string, pos.getErrorIndex()); + } + return number; + } + + public abstract Number parse(String string, TParsePosition position); + + @Override + public final Object parseObject(String string, TParsePosition position) { + if (position == null) { + throw new NullPointerException("position is null"); + } + + try { + return parse(string, position); + } catch (Exception e) { + return null; + } + } + + public void setGroupingUsed(boolean value) { + groupingUsed = value; + } + + public void setMaximumFractionDigits(int value) { + maximumFractionDigits = value < 0 ? 0 : value; + if (maximumFractionDigits < minimumFractionDigits) { + minimumFractionDigits = maximumFractionDigits; + } + } + + public void setMaximumIntegerDigits(int value) { + maximumIntegerDigits = value < 0 ? 0 : value; + if (maximumIntegerDigits < minimumIntegerDigits) { + minimumIntegerDigits = maximumIntegerDigits; + } + } + + public void setMinimumFractionDigits(int value) { + minimumFractionDigits = value < 0 ? 0 : value; + if (maximumFractionDigits < minimumFractionDigits) { + maximumFractionDigits = minimumFractionDigits; + } + } + + public void setMinimumIntegerDigits(int value) { + minimumIntegerDigits = value < 0 ? 0 : value; + if (maximumIntegerDigits < minimumIntegerDigits) { + maximumIntegerDigits = minimumIntegerDigits; + } + } + + public void setParseIntegerOnly(boolean value) { + parseIntegerOnly = value; + } + + public static class Field extends TFormat.Field { + public static final Field SIGN = new Field("sign"); + public static final Field INTEGER = new Field("integer"); + public static final Field FRACTION = new Field("fraction"); + public static final Field EXPONENT = new Field("exponent"); + public static final Field EXPONENT_SIGN = new Field("exponent sign"); + public static final Field EXPONENT_SYMBOL = new Field("exponent symbol"); + public static final Field DECIMAL_SEPARATOR = new Field("decimal separator"); + public static final Field GROUPING_SEPARATOR = new Field("grouping separator"); + public static final Field PERCENT = new Field("percent"); + public static final Field PERMILLE = new Field("per mille"); + public static final Field CURRENCY = new Field("currency"); + + protected Field(String fieldName) { + super(fieldName); + } + } +}