ICU-12029 Measure unit display names, Java version.

X-SVN-Rev: 39242
This commit is contained in:
Shane Carr 2016-09-15 08:37:24 +00:00
parent 67b23a4aa6
commit f8620a567b
2 changed files with 98 additions and 9 deletions

View File

@ -564,9 +564,38 @@ public class MeasureFormat extends UFormat {
measures[i],
i == measures.length - 1 ? numberFormat : integerFormat);
}
return appendTo.append(listFormatter.format((Object[]) results));
return appendTo.append(listFormatter.format((Object[]) results));
}
}
/**
* Gets the display name of the specified {@link MeasureUnit} corresponding to the current
* locale and format width.
* @param unit The unit for which to get a display name.
* @return The display name in the locale and width specified in
* {@link MeasureFormat#getInstance}, or null if there is no display name available
* for the specified unit.
*
* @draft ICU 58
* @provisional This API might change or be removed in a future release.
*/
public String getUnitDisplayName(MeasureUnit unit) {
FormatWidth width = getRegularWidth(formatWidth);
Map<FormatWidth, String> styleToDnam = cache.unitToStyleToDnam.get(unit);
if (styleToDnam == null) {
return null;
}
String dnam = styleToDnam.get(width);
if (dnam != null) {
return dnam;
}
FormatWidth fallbackWidth = cache.widthFallback[width.ordinal()];
if (fallbackWidth != null) {
dnam = styleToDnam.get(fallbackWidth);
}
return dnam;
}
/**
* Two MeasureFormats, a and b, are equal if and only if they have the same formatWidth,
@ -766,13 +795,25 @@ public class MeasureFormat extends UFormat {
}
}
void setDnamIfAbsent(UResource.Value value) {
EnumMap<FormatWidth, String> styleToDnam = cacheData.unitToStyleToDnam.get(unit);
if (styleToDnam == null) {
styleToDnam = new EnumMap<FormatWidth, String>(FormatWidth.class);
cacheData.unitToStyleToDnam.put(unit, styleToDnam);
}
if (styleToDnam.get(width) == null) {
styleToDnam.put(width, value.getString());
}
}
/**
* Consume a display pattern. For example,
* unitsShort/duration/hour contains other{"{0} hrs"}.
*/
void consumePattern(UResource.Key key, UResource.Value value) {
if (key.contentEquals("dnam")) {
// Skip the unit display name for now.
// The display name for the unit in the current width.
setDnamIfAbsent(value);
} else if (key.contentEquals("per")) {
// For example, "{0}/h".
setFormatterIfAbsent(MeasureFormatData.PER_UNIT_INDEX, value, 1);
@ -1076,6 +1117,8 @@ public class MeasureFormat extends UFormat {
/** Measure unit -> format width -> array of patterns ("{0} meters") (plurals + PER_UNIT_INDEX) */
final Map<MeasureUnit, EnumMap<FormatWidth, String[]>> unitToStyleToPatterns =
new HashMap<MeasureUnit, EnumMap<FormatWidth, String[]>>();
final Map<MeasureUnit, EnumMap<FormatWidth, String>> unitToStyleToDnam =
new HashMap<MeasureUnit, EnumMap<FormatWidth, String>>();
final EnumMap<FormatWidth, String> styleToPerPattern =
new EnumMap<FormatWidth, String>(FormatWidth.class);;
}

View File

@ -64,6 +64,7 @@ public class MeasureUnitTest extends TestFmwk {
return new OrderedPair<F, S>(first, second);
}
@Override
public int compareTo(OrderedPair<F, S> other) {
int result = first.compareTo(other.first);
if (result != 0) {
@ -1035,7 +1036,7 @@ public class MeasureUnitTest extends TestFmwk {
StringBuilder builder = new StringBuilder();
boolean failure = false;
for (Object[] testCase : testData) {
String actual = mf.format((Measure[]) testCase[0]);
String actual = mf.format(testCase[0]);
if (!testCase[1].equals(actual)) {
builder.append(String.format("%s: Expected: '%s', got: '%s'\n", desc, testCase[1], actual));
failure = true;
@ -1270,14 +1271,14 @@ public class MeasureUnitTest extends TestFmwk {
try{
mf = MeasureFormat.getInstance( (ULocale)row[0], (FormatWidth)row[1] );
} catch(Exception e) {
errln("Exception creating MeasureFormat for locale " + (ULocale)row[0] + ", width " +
(FormatWidth)row[1] + ": " + e);
errln("Exception creating MeasureFormat for locale " + row[0] + ", width " +
row[1] + ": " + e);
continue;
}
String result = mf.formatMeasures(hours, minutes);
if (!result.equals((String)row[2])) {
errln("MeasureFormat.formatMeasures for locale " + (ULocale)row[0] + ", width " +
(FormatWidth)row[1] + ", expected \"" + (String)row[2] + "\", got \"" + result + "\"" );
if (!result.equals(row[2])) {
errln("MeasureFormat.formatMeasures for locale " + row[0] + ", width " +
row[1] + ", expected \"" + (String)row[2] + "\", got \"" + result + "\"" );
}
}
}
@ -1402,6 +1403,46 @@ public class MeasureUnitTest extends TestFmwk {
assertEquals("Wide currency", "2.00\u7C73\u30C9\u30EB", mf.format(USD_2));
}
@Test
public void testDisplayNames() {
Object[][] data = new Object[][] {
// Unit, locale, width, expected result
{ MeasureUnit.YEAR, "en", FormatWidth.WIDE, "years" },
{ MeasureUnit.YEAR, "ja", FormatWidth.WIDE, "" },
{ MeasureUnit.YEAR, "es", FormatWidth.WIDE, "años" },
{ MeasureUnit.YEAR, "pt", FormatWidth.WIDE, "anos" },
{ MeasureUnit.YEAR, "pt-PT", FormatWidth.WIDE, "anos" },
{ MeasureUnit.AMPERE, "en", FormatWidth.WIDE, "amperes" },
{ MeasureUnit.AMPERE, "ja", FormatWidth.WIDE, "アンペア" },
{ MeasureUnit.AMPERE, "es", FormatWidth.WIDE, "amperios" },
{ MeasureUnit.AMPERE, "pt", FormatWidth.WIDE, "amperes" },
{ MeasureUnit.AMPERE, "pt-PT", FormatWidth.WIDE, "amperes" },
{ MeasureUnit.METER_PER_SECOND_SQUARED, "pt", FormatWidth.WIDE, "metros por segundo ao quadrado" },
{ MeasureUnit.METER_PER_SECOND_SQUARED, "pt-PT", FormatWidth.WIDE, "metros por segundo quadrado" },
{ MeasureUnit.SQUARE_KILOMETER, "pt", FormatWidth.NARROW, "km²" },
{ MeasureUnit.SQUARE_KILOMETER, "pt", FormatWidth.SHORT, "km²" },
{ MeasureUnit.SQUARE_KILOMETER, "pt", FormatWidth.WIDE, "quilômetros quadrados" },
{ MeasureUnit.SECOND, "pt-PT", FormatWidth.NARROW, "s" },
{ MeasureUnit.SECOND, "pt-PT", FormatWidth.SHORT, "s" },
{ MeasureUnit.SECOND, "pt-PT", FormatWidth.WIDE, "segundos" },
{ MeasureUnit.SECOND, "pt", FormatWidth.NARROW, "seg" },
{ MeasureUnit.SECOND, "pt", FormatWidth.SHORT, "segs" },
{ MeasureUnit.SECOND, "pt", FormatWidth.WIDE, "segundos" },
};
for (Object[] test : data) {
MeasureUnit unit = (MeasureUnit) test[0];
ULocale locale = ULocale.forLanguageTag((String) test[1]);
FormatWidth formatWidth = (FormatWidth) test[2];
String expected = (String) test[3];
MeasureFormat mf = MeasureFormat.getInstance(locale, formatWidth);
String actual = mf.getUnitDisplayName(unit);
assertEquals(String.format("Unit Display Name for %s, %s, %s", unit, locale, formatWidth),
expected, actual);
}
}
@Test
public void testFieldPosition() {
MeasureFormat fmt = MeasureFormat.getInstance(
@ -1804,6 +1845,7 @@ public class MeasureUnitTest extends TestFmwk {
units,
new Comparator<MeasureUnit>() {
@Override
public int compare(MeasureUnit o1, MeasureUnit o2) {
return o1.getSubtype().compareTo(o2.getSubtype());
}
@ -2146,6 +2188,7 @@ public class MeasureUnitTest extends TestFmwk {
public static class MeasureUnitHandler implements SerializableTestUtility.Handler
{
@Override
public Object[] getTestObjects()
{
MeasureUnit items[] = {
@ -2154,6 +2197,7 @@ public class MeasureUnitTest extends TestFmwk {
};
return items;
}
@Override
public boolean hasSameBehavior(Object a, Object b)
{
MeasureUnit a1 = (MeasureUnit) a;
@ -2165,6 +2209,7 @@ public class MeasureUnitTest extends TestFmwk {
public static class MeasureFormatHandler implements SerializableTestUtility.Handler
{
@Override
public Object[] getTestObjects()
{
MeasureFormat items[] = {
@ -2176,6 +2221,7 @@ public class MeasureUnitTest extends TestFmwk {
};
return items;
}
@Override
public boolean hasSameBehavior(Object a, Object b)
{
MeasureFormat a1 = (MeasureFormat) a;