]> granicus.if.org Git - icu/commitdiff
ICU-12029 Measure unit display names, Java version.
authorShane Carr <shane@unicode.org>
Thu, 15 Sep 2016 08:37:24 +0000 (08:37 +0000)
committerShane Carr <shane@unicode.org>
Thu, 15 Sep 2016 08:37:24 +0000 (08:37 +0000)
X-SVN-Rev: 39242

icu4j/main/classes/core/src/com/ibm/icu/text/MeasureFormat.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/MeasureUnitTest.java

index d8b6359fdde6f1c1028095d7b90bcac77cd02034..ca7dcde57174e50b955498b927500b57b14036b5 100644 (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);;
     }
index 0593f6653576c514ccddfedc0043036305bc8cf9..4ae945961c74a8b47207e778d13e400e12fccec3 100644 (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;