changeset 49165:3381b1e0713e

8060094: java/util/Formatter/Basic.java failed in tr locale Reviewed-by: naoto
author nishjain
date Mon, 26 Feb 2018 11:16:24 +0530
parents 3fbc7f109dad
children 513e98643998
files src/java.base/share/classes/java/util/Formatter.java test/jdk/java/util/Formatter/FormatLocale.java
diffstat 2 files changed, 103 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/util/Formatter.java	Mon Feb 26 08:30:30 2018 +0800
+++ b/src/java.base/share/classes/java/util/Formatter.java	Mon Feb 26 11:16:24 2018 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -284,11 +284,11 @@
  * {@code 'A'}, and {@code 'T'}) are the same as those for the corresponding
  * lower-case conversion characters except that the result is converted to
  * upper case according to the rules of the prevailing {@link java.util.Locale
- * Locale}.  The result is equivalent to the following invocation of {@link
- * String#toUpperCase(Locale)}
- *
- * <pre>
- *    out.toUpperCase(Locale.getDefault(Locale.Category.FORMAT)) </pre>
+ * Locale}. If there is no explicit locale specified, either at the
+ * construction of the instance or as a parameter to its method
+ * invocation, then the {@link java.util.Locale.Category#FORMAT default locale}
+ * is used.
+ *
  *
  * <table class="striped">
  * <caption style="display:none">genConv</caption>
@@ -709,11 +709,10 @@
  * {@code 'G'}, {@code 'A'}, and {@code 'T'}) are the same as those for the
  * corresponding lower-case conversion characters except that the result is
  * converted to upper case according to the rules of the prevailing {@link
- * java.util.Locale Locale}.  The result is equivalent to the following
- * invocation of {@link String#toUpperCase(Locale)}
- *
- * <pre>
- *    out.toUpperCase(Locale.getDefault(Locale.Category.FORMAT)) </pre>
+ * java.util.Locale Locale}. If there is no explicit locale specified,
+ * either at the construction of the instance or as a parameter to its method
+ * invocation, then the {@link java.util.Locale.Category#FORMAT default locale}
+ * is used.
  *
  * <h4><a id="dgen">General</a></h4>
  *
@@ -2897,16 +2896,16 @@
                 break;
             case Conversion.CHARACTER:
             case Conversion.CHARACTER_UPPER:
-                printCharacter(arg);
+                printCharacter(arg, l);
                 break;
             case Conversion.BOOLEAN:
-                printBoolean(arg);
+                printBoolean(arg, l);
                 break;
             case Conversion.STRING:
                 printString(arg, l);
                 break;
             case Conversion.HASHCODE:
-                printHashCode(arg);
+                printHashCode(arg, l);
                 break;
             case Conversion.LINE_SEPARATOR:
                 a.append(System.lineSeparator());
@@ -2921,7 +2920,7 @@
 
         private void printInteger(Object arg, Locale l) throws IOException {
             if (arg == null)
-                print("null");
+                print("null", l);
             else if (arg instanceof Byte)
                 print(((Byte)arg).byteValue(), l);
             else if (arg instanceof Short)
@@ -2938,7 +2937,7 @@
 
         private void printFloat(Object arg, Locale l) throws IOException {
             if (arg == null)
-                print("null");
+                print("null", l);
             else if (arg instanceof Float)
                 print(((Float)arg).floatValue(), l);
             else if (arg instanceof Double)
@@ -2951,7 +2950,7 @@
 
         private void printDateTime(Object arg, Locale l) throws IOException {
             if (arg == null) {
-                print("null");
+                print("null", l);
                 return;
             }
             Calendar cal = null;
@@ -2982,9 +2981,9 @@
             print(cal, c, l);
         }
 
-        private void printCharacter(Object arg) throws IOException {
+        private void printCharacter(Object arg, Locale l) throws IOException {
             if (arg == null) {
-                print("null");
+                print("null", l);
                 return;
             }
             String s = null;
@@ -3011,7 +3010,7 @@
             } else {
                 failConversion(c, arg);
             }
-            print(s);
+            print(s, l);
         }
 
         private void printString(Object arg, Locale l) throws IOException {
@@ -3024,13 +3023,13 @@
                 if (f.contains(Flags.ALTERNATE))
                     failMismatch(Flags.ALTERNATE, 's');
                 if (arg == null)
-                    print("null");
+                    print("null", l);
                 else
-                    print(arg.toString());
+                    print(arg.toString(), l);
             }
         }
 
-        private void printBoolean(Object arg) throws IOException {
+        private void printBoolean(Object arg, Locale l) throws IOException {
             String s;
             if (arg != null)
                 s = ((arg instanceof Boolean)
@@ -3038,24 +3037,29 @@
                      : Boolean.toString(true));
             else
                 s = Boolean.toString(false);
-            print(s);
+            print(s, l);
         }
 
-        private void printHashCode(Object arg) throws IOException {
+        private void printHashCode(Object arg, Locale l) throws IOException {
             String s = (arg == null
                         ? "null"
                         : Integer.toHexString(arg.hashCode()));
-            print(s);
+            print(s, l);
         }
 
-        private void print(String s) throws IOException {
+        private void print(String s, Locale l) throws IOException {
             if (precision != -1 && precision < s.length())
                 s = s.substring(0, precision);
             if (f.contains(Flags.UPPERCASE))
-                s = s.toUpperCase(Locale.getDefault(Locale.Category.FORMAT));
+                s = toUpperCaseWithLocale(s, l);
             appendJustified(a, s);
         }
 
+        private String toUpperCaseWithLocale(String s, Locale l) {
+            return s.toUpperCase(Objects.requireNonNullElse(l,
+                    Locale.getDefault(Locale.Category.FORMAT)));
+        }
+
         private Appendable appendJustified(Appendable a, CharSequence cs) throws IOException {
              if (width == -1) {
                  return a.append(cs);
@@ -3276,7 +3280,7 @@
                     trailingZeros(sb, width - len);
                 }
                 if (f.contains(Flags.UPPERCASE))
-                    s = s.toUpperCase(Locale.getDefault(Locale.Category.FORMAT));
+                    s = toUpperCaseWithLocale(s, l);
                 sb.append(s);
             }
 
@@ -3351,7 +3355,7 @@
                     trailingZeros(sb, width - len);
                 }
                 if (f.contains(Flags.UPPERCASE))
-                    s = s.toUpperCase(Locale.getDefault(Locale.Category.FORMAT));
+                    s = toUpperCaseWithLocale(s, l);
                 sb.append(s);
             }
 
@@ -3950,7 +3954,7 @@
 
             // justify based on width
             if (f.contains(Flags.UPPERCASE)) {
-                appendJustified(a, sb.toString().toUpperCase(Locale.getDefault(Locale.Category.FORMAT)));
+                appendJustified(a, toUpperCaseWithLocale(sb.toString(), l));
             } else {
                 appendJustified(a, sb);
             }
@@ -4132,8 +4136,7 @@
                 StringBuilder tsb = new StringBuilder();
                 print(tsb, t, DateTime.AM_PM, l);
 
-                sb.append(tsb.toString().toUpperCase(Objects.requireNonNullElse(l,
-                                               Locale.getDefault(Locale.Category.FORMAT))));
+                sb.append(toUpperCaseWithLocale(tsb.toString(), l));
                 break;
             }
             case DateTime.DATE_TIME:    { // 'c' (Sat Nov 04 12:02:33 EST 1999)
@@ -4171,7 +4174,7 @@
             print(sb, t, c, l);
             // justify based on width
             if (f.contains(Flags.UPPERCASE)) {
-                appendJustified(a, sb.toString().toUpperCase(Locale.getDefault(Locale.Category.FORMAT)));
+                appendJustified(a, toUpperCaseWithLocale(sb.toString(), l));
             } else {
                 appendJustified(a, sb);
             }
@@ -4373,8 +4376,7 @@
                     // this may be in wrong place for some locales
                     StringBuilder tsb = new StringBuilder();
                     print(tsb, t, DateTime.AM_PM, l);
-                    sb.append(tsb.toString().toUpperCase(Objects.requireNonNullElse(l,
-                                        Locale.getDefault(Locale.Category.FORMAT))));
+                    sb.append(toUpperCaseWithLocale(tsb.toString(), l));
                     break;
                 }
                 case DateTime.DATE_TIME:    { // 'c' (Sat Nov 04 12:02:33 EST 1999)
--- a/test/jdk/java/util/Formatter/FormatLocale.java	Mon Feb 26 08:30:30 2018 +0800
+++ b/test/jdk/java/util/Formatter/FormatLocale.java	Mon Feb 26 11:16:24 2018 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,9 +23,12 @@
 
 /**
  * @test
- * @bug 8146156 8159548
+ * @bug 8146156 8159548 8060094
  * @modules jdk.localedata
  * @summary test whether uppercasing follows Locale.Category.FORMAT locale.
+ *          Also test whether the uppercasing uses the locale specified to the
+ *          Formatter API.
+ *
  * @run main/othervm FormatLocale
  */
 
@@ -38,7 +41,6 @@
 import java.util.GregorianCalendar;
 import java.util.List;
 import java.util.Locale;
-import java.util.Locale.Category;
 import java.util.TimeZone;
 import java.util.stream.IntStream;
 
@@ -50,40 +52,81 @@
         "%S",
         "%S",
         "%TB",
-        "%G");
+        "%G",
+        "%C");
+
     static final List<Object> src = List.of(
         "Turkish",
         "Turkish",
         LocalDate.of(2016, Month.APRIL, 1),
-        Float.valueOf(100_000_000));
+        Float.valueOf(100_000_000),
+        'i');
+
+    static final List<Locale> defaultLocale = List.of(
+            Locale.ENGLISH,
+            TURKISH,
+            TURKISH,
+            Locale.FRANCE,
+            TURKISH);
+
     static final List<Locale> formatLocale = List.of(
-        Locale.ENGLISH,
-        TURKISH,
-        TURKISH,
-        Locale.FRANCE);
-    static final List<String> expected = List.of(
-        "TURKISH",
-        "TURK\u0130SH",
-        "N\u0130SAN",
-        "1,00000E+08");
+            TURKISH,
+            Locale.ENGLISH,
+            Locale.FRANCE,
+            Locale.ENGLISH,
+            Locale.ENGLISH);
+
+    static final List<String> expectedWithDefaultLocale = List.of(
+            "TURKISH",
+            "TURK\u0130SH",
+            "N\u0130SAN",
+            "1,00000E+08",
+            "\u0130");
+
+    static final List<String> expectedWithFormatLocale = List.of(
+            "TURK\u0130SH",
+            "TURKISH",
+            "AVRIL",
+            "1.00000E+08",
+            "I");
 
     static void formatLocaleTest() {
         StringBuilder sb = new StringBuilder();
 
+        // checks whether upper casing follows Locale.Category.FORMAT locale
         IntStream.range(0, src.size()).forEach(i -> {
             sb.setLength(0);
-            Locale.setDefault(Locale.Category.FORMAT, formatLocale.get(i));
+            Locale.setDefault(Locale.Category.FORMAT, defaultLocale.get(i));
             new Formatter(sb).format(conversions.get(i), src.get(i));
-            if (!sb.toString().equals(expected.get(i))) {
+            if (!sb.toString().equals(expectedWithDefaultLocale.get(i))) {
                 throw new RuntimeException(
-                    "Wrong uppercasing with Formatter.format(" +
-                    "\"" + conversions.get(i) + "\"" +
-                    ") in locale "
-                    + formatLocale.get(i) +
-                    ". Expected: " + expected.get(i) +
-                    " Returned: " + sb.toString());
+                        "Wrong uppercasing while using Formatter.format(" +
+                                "\"" + conversions.get(i) + "\"" +
+                                ") with the default locale: '"
+                                + defaultLocale.get(i) +
+                                "'. Expected: " + expectedWithDefaultLocale.get(i) +
+                                " Returned: " + sb.toString());
             }
         });
+
+        // checks whether upper casing uses the locale set during creation of
+        // Formatter instance, instead of the default locale
+        IntStream.range(0, src.size()).forEach(i -> {
+            sb.setLength(0);
+            Locale.setDefault(Locale.Category.FORMAT, defaultLocale.get(i));
+            new Formatter(sb, formatLocale.get(i)).format(conversions.get(i),
+                    src.get(i));
+            if (!sb.toString().equals(expectedWithFormatLocale.get(i))) {
+                throw new RuntimeException(
+                        "Wrong uppercasing while using Formatter.format(" +
+                                "\"" + conversions.get(i) + "\"" +
+                                ") with the locale specified during instance" +
+                                " creation: '" + formatLocale.get(i) +
+                                "'. Expected: " + expectedWithFormatLocale.get(i) +
+                                " Returned: " + sb.toString());
+            }
+        });
+
     }
 
     static void nullLocaleTest() {