ICU-10600 cleaned up API and checked for currencies.

X-SVN-Rev: 36045
This commit is contained in:
Mark Davis 2014-07-16 14:14:56 +00:00
parent f45a95a200
commit 4661ffffa9
5 changed files with 50 additions and 60 deletions

View File

@ -10,14 +10,11 @@ import java.text.ParseException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import com.ibm.icu.text.NumberingSystem;
import com.ibm.icu.text.PluralRanges;
import com.ibm.icu.text.PluralRules;
import com.ibm.icu.text.PluralRules.PluralType;

View File

@ -16,6 +16,7 @@ import java.io.InvalidObjectException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.ObjectStreamException;
import java.nio.Buffer;
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.util.Arrays;
@ -33,6 +34,7 @@ import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.impl.SimpleCache;
import com.ibm.icu.impl.SimplePatternFormatter;
import com.ibm.icu.math.BigDecimal;
import com.ibm.icu.text.PluralRules.Factory;
import com.ibm.icu.text.PluralRules.StandardPluralCategories;
import com.ibm.icu.util.Currency;
import com.ibm.icu.util.CurrencyAmount;
@ -380,8 +382,10 @@ public class MeasureFormat extends UFormat {
/**
* Format a range of measures, such as "3.4-5.1 meters". It is the callers
* responsibility to have the appropriate values in appropriate order,
* and using the appropriate Number values. Typically the units should be
* in ascending order.
* and using the appropriate Number values.
* <br>Note: If the format doesnt have enough decimals, or lowValue highValue,
* the result will be a degenerate range, like 5-5 meters.
* <br>Currency Units are not yet supported.
*
* @param lowValue low value in range
* @param highValue high value in range
@ -400,22 +404,29 @@ public class MeasureFormat extends UFormat {
UFieldPosition fpos = new UFieldPosition();
StringBuffer lowFormatted = numberFormat.format(lowNumber, new StringBuffer(), fpos);
String keywordLow = rules.select(new PluralRules.FixedDecimal(lowNumber.doubleValue(), fpos.getCountVisibleFractionDigits(), fpos.getFractionDigits()));
final double lowDouble = lowNumber.doubleValue();
String keywordLow = rules.select(new PluralRules.FixedDecimal(lowDouble,
fpos.getCountVisibleFractionDigits(), fpos.getFractionDigits()));
StringBuffer highFormatted = numberFormat.format(highNumber, new StringBuffer(), fpos);
String keywordHigh = rules.select(new PluralRules.FixedDecimal(highNumber.doubleValue(), fpos.getCountVisibleFractionDigits(), fpos.getFractionDigits()));
String keywordHigh = rules.select(new PluralRules.FixedDecimal(highNumber.doubleValue(),
fpos.getCountVisibleFractionDigits(), fpos.getFractionDigits()));
StandardPluralCategories resolvedCategory = PluralRules.getRange(
getLocale(),
StandardPluralCategories.valueOf(keywordLow),
StandardPluralCategories.valueOf(keywordHigh));
final PluralRanges pluralRanges = Factory.getDefaultFactory().getPluralRanges(getLocale());
StandardPluralCategories resolvedCategory = pluralRanges.get(
StandardPluralCategories.valueOf(keywordLow), StandardPluralCategories.valueOf(keywordHigh));
Map<FormatWidth, QuantityFormatter> styleToCountToFormat = unitToStyleToCountToFormat.get(lowValue.getUnit());
QuantityFormatter countToFormat = styleToCountToFormat.get(formatWidth);
SimplePatternFormatter formatter = countToFormat.getByVariant(resolvedCategory.toString());
SimplePatternFormatter rangeFormatter = getRangeFormat(getLocale(), formatWidth);
String formattedNumber = rangeFormatter.format(lowFormatted, highFormatted);
return formatter.format(formattedNumber);
if (unit instanceof Currency) {
throw new IllegalArgumentException("Currency units not supported in ranges");
} else {
Map<FormatWidth, QuantityFormatter> styleToCountToFormat = unitToStyleToCountToFormat.get(lowValue.getUnit());
QuantityFormatter countToFormat = styleToCountToFormat.get(formatWidth);
SimplePatternFormatter formatter = countToFormat.getByVariant(resolvedCategory.toString());
return formatter.format(formattedNumber);
}
}
/**
@ -764,6 +775,13 @@ public class MeasureFormat extends UFormat {
public synchronized String format(Number number) {
return nf.format(number);
}
public String getPrefix(boolean positive) {
return positive ? ((DecimalFormat)nf).getPositivePrefix() : ((DecimalFormat)nf).getNegativePrefix();
}
public String getSuffix(boolean positive) {
return positive ? ((DecimalFormat)nf).getPositiveSuffix() : ((DecimalFormat)nf).getPositiveSuffix();
}
}
static final class PatternData {
@ -1075,10 +1093,10 @@ public class MeasureFormat extends UFormat {
}
return values[ordinal];
}
static final Map<ULocale, SimplePatternFormatter> localeIdToRangeFormat
= new ConcurrentHashMap<ULocale, SimplePatternFormatter>();
/**
* Return a simple pattern formatter for a range, such as "{0}{1}".
* @param forLocale locale to get the format for
@ -1097,7 +1115,7 @@ public class MeasureFormat extends UFormat {
SimplePatternFormatter result = localeIdToRangeFormat.get(forLocale);
if (result == null) {
ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.
getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, forLocale);
getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, forLocale);
ULocale realLocale = rb.getULocale();
if (!forLocale.equals(realLocale)) { // if the child would inherit, then add a cache entry for it.
result = localeIdToRangeFormat.get(forLocale);
@ -1109,7 +1127,7 @@ public class MeasureFormat extends UFormat {
// At this point, both the forLocale and the realLocale don't have an item
// So we have to make one.
NumberingSystem ns = NumberingSystem.getInstance(forLocale);
String resultString = null;
try {
resultString = rb.getStringWithFallback("NumberElements/" + ns.getName() + "/miscPatterns/range");

View File

@ -2446,41 +2446,4 @@ public class PluralRules implements Serializable {
public boolean computeLimited(String keyword, SampleType sampleType) {
return rules.computeLimited(keyword, sampleType);
}
/**
* Return the plural category for a range, such as 3.1-4.2.
* @param locale locale for the range
* @param startPluralCategory the plural category of the low end of the range.
* @param endPluralCategory the plural category of the high end of the range.
* @return the plural category of the range
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
static public StandardPluralCategories getRange(ULocale locale,
StandardPluralCategories startPluralCategory,
StandardPluralCategories endPluralCategory) {
final PluralRanges pluralRanges = Factory.getDefaultFactory().getPluralRanges(locale);
return pluralRanges.get(startPluralCategory, endPluralCategory);
}
/**
* Return the plural category for a range, such as 3.1-4.2.
* @param locale locale for the range
* @param startPluralCategory the plural category of the low end of the range.
* @param endPluralCategory the plural category of the high end of the range.
* @return the plural category of the range
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
static public String getRange(ULocale locale,
String startPluralCategory,
String endPluralCategory) {
final PluralRanges pluralRanges = Factory.getDefaultFactory().getPluralRanges(locale);
return pluralRanges.get(
StandardPluralCategories.valueOf(startPluralCategory),
StandardPluralCategories.valueOf(endPluralCategory))
.toString();
}
}

View File

@ -11,7 +11,9 @@ import com.ibm.icu.text.MeasureFormat;
import com.ibm.icu.text.MeasureFormat.FormatWidth;
import com.ibm.icu.text.PluralRanges;
import com.ibm.icu.text.PluralRules;
import com.ibm.icu.text.PluralRules.Factory;
import com.ibm.icu.text.PluralRules.StandardPluralCategories;
import com.ibm.icu.util.Currency;
import com.ibm.icu.util.Measure;
import com.ibm.icu.util.MeasureUnit;
import com.ibm.icu.util.ULocale;
@ -41,8 +43,9 @@ public class PluralRangesTest extends TestFmwk {
final StandardPluralCategories start = StandardPluralCategories.valueOf(test[1]);
final StandardPluralCategories end = StandardPluralCategories.valueOf(test[2]);
final StandardPluralCategories expected = StandardPluralCategories.valueOf(test[3]);
final PluralRanges pluralRanges = Factory.getDefaultFactory().getPluralRanges(locale);
StandardPluralCategories actual = PluralRules.getRange(locale, start, end);
StandardPluralCategories actual = pluralRanges.get(start, end);
assertEquals("Deriving range category", expected, actual);
}
}
@ -54,7 +57,10 @@ public class PluralRangesTest extends TestFmwk {
{3.1, 4.25, ULocale.FRANCE, FormatWidth.SHORT, MeasureUnit.FAHRENHEIT, "3,14,25 °F"},
{3.1, 4.25, ULocale.ENGLISH, FormatWidth.SHORT, MeasureUnit.FAHRENHEIT, "3.14.25°F"},
{3.1, 4.25, ULocale.CHINESE, FormatWidth.WIDE, MeasureUnit.INCH, "3.1-4.25英寸"},
{0.0, 1.0, new ULocale("xx"), FormatWidth.WIDE, MeasureUnit.INCH, "01 inches"},
{0.0, 1.0, ULocale.ENGLISH, FormatWidth.WIDE, MeasureUnit.INCH, "01 inches"},
{0.0, 1.0, ULocale.ENGLISH, FormatWidth.WIDE, Currency.getInstance("EUR"),
IllegalArgumentException.class},
};
for (Object[] test : tests) {
double low = (Double) test[0];
@ -62,10 +68,15 @@ public class PluralRangesTest extends TestFmwk {
final ULocale locale = (ULocale) test[2];
final FormatWidth width = (FormatWidth) test[3];
final MeasureUnit unit = (MeasureUnit) test[4];
final String expected = (String) test[5];
final Object expected = test[5];
MeasureFormat mf = MeasureFormat.getInstance(locale, width);
String actual = mf.formatMeasureRange(new Measure(low, unit), new Measure(high, unit));
Object actual;
try {
actual = mf.formatMeasureRange(new Measure(low, unit), new Measure(high, unit));
} catch (Exception e) {
actual = e.getClass();
}
assertEquals("Formatting unit", expected, actual);
}
}

View File

@ -110,6 +110,7 @@ public class TestAll extends TestGroup {
"PluralFormatUnitTest",
"PluralFormatTest",
"PluralRulesTest",
"PluralRangesTest",
});
}
}