ICU-13073 Adding API for setting custom compact data, for CLDR Survey Tool.
X-SVN-Rev: 40117
This commit is contained in:
parent
b9f7feaf26
commit
36c6e6c6a2
@ -12,6 +12,7 @@ import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
import com.ibm.icu.impl.number.Parse.GroupingMode;
|
||||
import com.ibm.icu.impl.number.Parse.ParseMode;
|
||||
@ -73,6 +74,7 @@ public class Properties
|
||||
/| or #equals(), but it will NOT catch if you forget to add it to #hashCode(). |/
|
||||
/+--------------------------------------------------------------------------------------------*/
|
||||
|
||||
private transient Map<String, Map<String, String>> compactCustomData;
|
||||
private transient CompactStyle compactStyle;
|
||||
private transient Currency currency;
|
||||
private transient CurrencyPluralInfo currencyPluralInfo;
|
||||
@ -132,6 +134,7 @@ public class Properties
|
||||
}
|
||||
|
||||
private Properties _clear() {
|
||||
compactCustomData = DEFAULT_COMPACT_CUSTOM_DATA;
|
||||
compactStyle = DEFAULT_COMPACT_STYLE;
|
||||
currency = DEFAULT_CURRENCY;
|
||||
currencyPluralInfo = DEFAULT_CURRENCY_PLURAL_INFO;
|
||||
@ -180,6 +183,7 @@ public class Properties
|
||||
}
|
||||
|
||||
private Properties _copyFrom(Properties other) {
|
||||
compactCustomData = other.compactCustomData;
|
||||
compactStyle = other.compactStyle;
|
||||
currency = other.currency;
|
||||
currencyPluralInfo = other.currencyPluralInfo;
|
||||
@ -229,6 +233,7 @@ public class Properties
|
||||
|
||||
private boolean _equals(Properties other) {
|
||||
boolean eq = true;
|
||||
eq = eq && _equalsHelper(compactCustomData, other.compactCustomData);
|
||||
eq = eq && _equalsHelper(compactStyle, other.compactStyle);
|
||||
eq = eq && _equalsHelper(currency, other.currency);
|
||||
eq = eq && _equalsHelper(currencyPluralInfo, other.currencyPluralInfo);
|
||||
@ -292,6 +297,7 @@ public class Properties
|
||||
|
||||
private int _hashCode() {
|
||||
int hashCode = 0;
|
||||
hashCode ^= _hashCodeHelper(compactCustomData);
|
||||
hashCode ^= _hashCodeHelper(compactStyle);
|
||||
hashCode ^= _hashCodeHelper(currency);
|
||||
hashCode ^= _hashCodeHelper(currencyPluralInfo);
|
||||
@ -386,6 +392,13 @@ public class Properties
|
||||
return _equals((Properties) other);
|
||||
}
|
||||
|
||||
/// BEGIN GETTERS/SETTERS ///
|
||||
|
||||
@Override
|
||||
public Map<String, Map<String, String>> getCompactCustomData() {
|
||||
return compactCustomData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompactStyle getCompactStyle() {
|
||||
return compactStyle;
|
||||
@ -396,8 +409,6 @@ public class Properties
|
||||
return currency;
|
||||
}
|
||||
|
||||
/// BEGIN GETTERS/SETTERS ///
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public CurrencyPluralInfo getCurrencyPluralInfo() {
|
||||
@ -660,6 +671,12 @@ public class Properties
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties setCompactCustomData(Map<String, Map<String, String>> compactCustomData) {
|
||||
this.compactCustomData = compactCustomData;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties setCompactStyle(CompactStyle compactStyle) {
|
||||
this.compactStyle = compactStyle;
|
||||
|
@ -49,6 +49,39 @@ public class CompactDecimalFormat extends Format.BeforeFormat {
|
||||
* @return The property bag, for chaining.
|
||||
*/
|
||||
public IProperties setCompactStyle(CompactStyle compactStyle);
|
||||
|
||||
static Map<String, Map<String, String>> DEFAULT_COMPACT_CUSTOM_DATA = null;
|
||||
|
||||
/** @see #setCompactCustomData */
|
||||
public Map<String, Map<String, String>> getCompactCustomData();
|
||||
|
||||
/**
|
||||
* Specifies custom data to be used instead of CLDR data when constructing a
|
||||
* CompactDecimalFormat. The argument should be a map with the following structure:
|
||||
*
|
||||
* <pre>
|
||||
* {
|
||||
* "1000": {
|
||||
* "one": "0 thousand",
|
||||
* "other": "0 thousand"
|
||||
* },
|
||||
* "10000": {
|
||||
* "one": "00 thousand",
|
||||
* "other": "00 thousand"
|
||||
* },
|
||||
* // ...
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* This API endpoint is used by the CLDR Survey Tool.
|
||||
*
|
||||
* @param compactCustomData A map with the above structure.
|
||||
* @return The property bag, for chaining.
|
||||
* @internal
|
||||
* @deprecated This API is ICU internal only.
|
||||
*/
|
||||
@Deprecated
|
||||
public IProperties setCompactCustomData(Map<String, Map<String, String>> compactCustomData);
|
||||
}
|
||||
|
||||
public static boolean useCompactDecimalFormat(IProperties properties) {
|
||||
@ -179,7 +212,12 @@ public class CompactDecimalFormat extends Format.BeforeFormat {
|
||||
private CompactDecimalFormat(DecimalFormatSymbols symbols, IProperties properties) {
|
||||
CompactDecimalFingerprint fingerprint = new CompactDecimalFingerprint(symbols, properties);
|
||||
this.rounder = getRounder(properties);
|
||||
this.data = getData(symbols, fingerprint);
|
||||
// Short-circuit and use custom data if provided
|
||||
if (properties.getCompactCustomData() != null) {
|
||||
this.data = createDataFromCustom(symbols, fingerprint, properties.getCompactCustomData());
|
||||
} else {
|
||||
this.data = getData(symbols, fingerprint);
|
||||
}
|
||||
this.defaultMod = getDefaultMod(symbols, fingerprint);
|
||||
this.style = properties.getCompactStyle(); // for exporting only
|
||||
}
|
||||
@ -492,4 +530,34 @@ public class CompactDecimalFormat extends Format.BeforeFormat {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses data from the custom powersToPluralsToPatterns map instead of an ICUResourceBundle to
|
||||
* populate an instance of CompactDecimalData.
|
||||
*/
|
||||
static CompactDecimalData createDataFromCustom(
|
||||
DecimalFormatSymbols symbols,
|
||||
CompactDecimalFingerprint fingerprint,
|
||||
Map<String, Map<String, String>> powersToPluralsToPatterns) {
|
||||
CompactDecimalData data = new CompactDecimalData();
|
||||
PNAffixGenerator pnag = PNAffixGenerator.getThreadLocalInstance();
|
||||
for (Map.Entry<String, Map<String, String>> magnitudeEntry :
|
||||
powersToPluralsToPatterns.entrySet()) {
|
||||
byte magnitude = (byte) (magnitudeEntry.getKey().length() - 1);
|
||||
for (Map.Entry<String, String> pluralEntry : magnitudeEntry.getValue().entrySet()) {
|
||||
StandardPlural plural = StandardPlural.fromString(pluralEntry.getKey().toString());
|
||||
String patternString = pluralEntry.getValue().toString();
|
||||
Properties properties = PatternString.parseToProperties(patternString);
|
||||
byte _multiplier = (byte) -(magnitude - properties.getMinimumIntegerDigits() + 1);
|
||||
if (_multiplier != data.setOrGetMultiplier(magnitude, _multiplier)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Different number of zeros for same power of ten in custom compact decimal format data");
|
||||
}
|
||||
PNAffixGenerator.Result result =
|
||||
pnag.getModifiers(symbols, fingerprint.currencySymbol, properties);
|
||||
data.setModifiers(result.positive, result.negative, magnitude, plural);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
@ -20,14 +20,18 @@ import java.text.AttributedCharacterIterator;
|
||||
import java.text.CharacterIterator;
|
||||
import java.text.FieldPosition;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ibm.icu.dev.test.TestFmwk;
|
||||
import com.ibm.icu.impl.number.Properties;
|
||||
import com.ibm.icu.text.CompactDecimalFormat;
|
||||
import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
|
||||
import com.ibm.icu.text.DecimalFormat;
|
||||
import com.ibm.icu.text.DecimalFormat.PropertySetter;
|
||||
import com.ibm.icu.text.NumberFormat;
|
||||
import com.ibm.icu.util.Currency;
|
||||
import com.ibm.icu.util.CurrencyAmount;
|
||||
@ -649,6 +653,27 @@ public class CompactDecimalFormatTest extends TestFmwk {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestCustomData() {
|
||||
final Map<String,Map<String,String>> customData = new HashMap<String,Map<String,String>>();
|
||||
Map<String,String> inner = new HashMap<String,String>();
|
||||
inner.put("one", "0 qwerty");
|
||||
inner.put("other", "0 dvorak");
|
||||
customData.put("1000", inner);
|
||||
CompactDecimalFormat cdf = CompactDecimalFormat.getInstance(ULocale.ENGLISH, CompactStyle.SHORT);
|
||||
cdf.setProperties(new PropertySetter() {
|
||||
@Override
|
||||
public void set(Properties props) {
|
||||
props.setCompactCustomData(customData);
|
||||
}
|
||||
});
|
||||
assertEquals("Below custom range", "120", cdf.format(123));
|
||||
assertEquals("Plural form one", "1 qwerty", cdf.format(1000));
|
||||
assertEquals("Plural form other", "1.2 dvorak", cdf.format(1234));
|
||||
assertEquals("Above custom range", "12 dvorak", cdf.format(12345));
|
||||
assertEquals("Negative number", "-1 qwerty", cdf.format(-1000));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestBug12422() {
|
||||
CompactDecimalFormat cdf;
|
||||
|
@ -21,7 +21,9 @@ import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
@ -259,6 +261,20 @@ public class PropertiesTest {
|
||||
FormatWidth[] values = FormatWidth.values();
|
||||
return values[seed % values.length];
|
||||
|
||||
} else if (type == Map.class) {
|
||||
// Map<String,Map<String,String>> for compactCustomData property
|
||||
if (seed == 0) return null;
|
||||
Map<String, Map<String, String>> outer = new HashMap<String, Map<String, String>>();
|
||||
Map<String, String> inner = new HashMap<String, String>();
|
||||
inner.put("one", "0 thousand");
|
||||
StringBuilder magnitudeKey = new StringBuilder();
|
||||
magnitudeKey.append("1000");
|
||||
for (int i = 0; i < seed % 9; i++) {
|
||||
magnitudeKey.append("0");
|
||||
}
|
||||
outer.put(magnitudeKey.toString(), inner);
|
||||
return outer;
|
||||
|
||||
} else if (type == MathContext.class) {
|
||||
if (seed == 0) return null;
|
||||
RoundingMode[] modes = RoundingMode.values();
|
||||
|
Loading…
Reference in New Issue
Block a user