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