--- 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() {