8330276: Console methods with explicit Locale
Reviewed-by: joehw, rriggs, jlahoda
This commit is contained in:
parent
8a4315f833
commit
7cff04fc8a
src
java.base/share/classes
jdk.internal.le/share/classes/jdk/internal/org/jline
jdk.jshell/share/classes/jdk/jshell/execution/impl
test/jdk/java/io/Console
@ -62,6 +62,11 @@ import sun.security.action.GetPropertyAction;
|
||||
* on the objects returned by {@link #reader()} and {@link #writer()} may
|
||||
* block in multithreaded scenarios.
|
||||
* <p>
|
||||
* Operations that format strings are locale sensitive, using either the
|
||||
* specified {@code Locale}, or the
|
||||
* {@link Locale##default_locale default format Locale} to produce localized
|
||||
* formatted strings.
|
||||
* <p>
|
||||
* Invoking {@code close()} on the objects returned by the {@link #reader()}
|
||||
* and the {@link #writer()} will not close the underlying stream of those
|
||||
* objects.
|
||||
@ -147,11 +152,12 @@ public sealed class Console implements Flushable permits ProxyingConsole {
|
||||
|
||||
/**
|
||||
* Writes a formatted string to this console's output stream using
|
||||
* the specified format string and arguments.
|
||||
* the specified format string and arguments with the
|
||||
* {@link Locale##default_locale default format locale}.
|
||||
*
|
||||
* @param fmt
|
||||
* A format string as described in <a
|
||||
* href="../util/Formatter.html#syntax">Format string syntax</a>.
|
||||
* @param format
|
||||
* A format string as described in {@link
|
||||
* Formatter##syntax Format string syntax}.
|
||||
*
|
||||
* @param args
|
||||
* Arguments referenced by the format specifiers in the format
|
||||
@ -160,39 +166,75 @@ public sealed class Console implements Flushable permits ProxyingConsole {
|
||||
* variable and may be zero. The maximum number of arguments is
|
||||
* limited by the maximum dimension of a Java array as defined by
|
||||
* <cite>The Java Virtual Machine Specification</cite>.
|
||||
* The behaviour on a
|
||||
* {@code null} argument depends on the <a
|
||||
* href="../util/Formatter.html#syntax">conversion</a>.
|
||||
* The behavior on a
|
||||
* {@code null} argument depends on the {@link
|
||||
* Formatter##syntax conversion}.
|
||||
*
|
||||
* @throws IllegalFormatException
|
||||
* If a format string contains an illegal syntax, a format
|
||||
* specifier that is incompatible with the given arguments,
|
||||
* insufficient arguments given the format string, or other
|
||||
* illegal conditions. For specification of all possible
|
||||
* formatting errors, see the <a
|
||||
* href="../util/Formatter.html#detail">Details</a> section
|
||||
* formatting errors, see the {@link
|
||||
* Formatter##detail Details} section
|
||||
* of the formatter class specification.
|
||||
*
|
||||
* @return This console
|
||||
*/
|
||||
public Console format(String fmt, Object ...args) {
|
||||
public Console format(String format, Object ... args) {
|
||||
throw newUnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a formatted string to this console's output stream using
|
||||
* the specified format string and arguments with the specified
|
||||
* {@code locale}.
|
||||
*
|
||||
* @param locale The {@linkplain Locale locale} to apply during
|
||||
* formatting. If {@code locale} is {@code null} then no localization
|
||||
* is applied.
|
||||
*
|
||||
* @param format
|
||||
* A format string as described in {@link
|
||||
* Formatter##syntax Format string syntax}.
|
||||
*
|
||||
* @param args
|
||||
* Arguments referenced by the format specifiers in the format
|
||||
* string. If there are more arguments than format specifiers, the
|
||||
* extra arguments are ignored. The number of arguments is
|
||||
* variable and may be zero. The maximum number of arguments is
|
||||
* limited by the maximum dimension of a Java array as defined by
|
||||
* <cite>The Java Virtual Machine Specification</cite>.
|
||||
* The behavior on a
|
||||
* {@code null} argument depends on the {@link
|
||||
* Formatter##syntax conversion}.
|
||||
*
|
||||
* @throws IllegalFormatException
|
||||
* If a format string contains an illegal syntax, a format
|
||||
* specifier that is incompatible with the given arguments,
|
||||
* insufficient arguments given the format string, or other
|
||||
* illegal conditions. For specification of all possible
|
||||
* formatting errors, see the {@link
|
||||
* Formatter##detail Details} section
|
||||
* of the formatter class specification.
|
||||
*
|
||||
* @return This console
|
||||
* @since 23
|
||||
*/
|
||||
public Console format(Locale locale, String format, Object ... args) {
|
||||
throw newUnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method to write a formatted string to this console's
|
||||
* output stream using the specified format string and arguments.
|
||||
* output stream using the specified format string and arguments with
|
||||
* the {@link Locale##default_locale default format locale}.
|
||||
*
|
||||
* <p> An invocation of this method of the form
|
||||
* {@code con.printf(format, args)} behaves in exactly the same way
|
||||
* as the invocation of
|
||||
* {@snippet lang=java :
|
||||
* con.format(format, args)
|
||||
* }
|
||||
* @implSpec This is the same as calling {@code format(format, args)}.
|
||||
*
|
||||
* @param format
|
||||
* A format string as described in <a
|
||||
* href="../util/Formatter.html#syntax">Format string syntax</a>.
|
||||
* A format string as described in {@link
|
||||
* Formatter##syntax Format string syntax}.
|
||||
*
|
||||
* @param args
|
||||
* Arguments referenced by the format specifiers in the format
|
||||
@ -201,17 +243,17 @@ public sealed class Console implements Flushable permits ProxyingConsole {
|
||||
* variable and may be zero. The maximum number of arguments is
|
||||
* limited by the maximum dimension of a Java array as defined by
|
||||
* <cite>The Java Virtual Machine Specification</cite>.
|
||||
* The behaviour on a
|
||||
* {@code null} argument depends on the <a
|
||||
* href="../util/Formatter.html#syntax">conversion</a>.
|
||||
* The behavior on a
|
||||
* {@code null} argument depends on the {@link
|
||||
* Formatter##syntax conversion}.
|
||||
*
|
||||
* @throws IllegalFormatException
|
||||
* If a format string contains an illegal syntax, a format
|
||||
* specifier that is incompatible with the given arguments,
|
||||
* insufficient arguments given the format string, or other
|
||||
* illegal conditions. For specification of all possible
|
||||
* formatting errors, see the <a
|
||||
* href="../util/Formatter.html#detail">Details</a> section of the
|
||||
* formatting errors, see the {@link
|
||||
* Formatter##detail Details} section of the
|
||||
* formatter class specification.
|
||||
*
|
||||
* @return This console
|
||||
@ -221,28 +263,76 @@ public sealed class Console implements Flushable permits ProxyingConsole {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a formatted prompt, then reads a single line of text from the
|
||||
* console.
|
||||
* A convenience method to write a formatted string to this console's
|
||||
* output stream using the specified format string and arguments with
|
||||
* the specified {@code locale}.
|
||||
*
|
||||
* @param fmt
|
||||
* A format string as described in <a
|
||||
* href="../util/Formatter.html#syntax">Format string syntax</a>.
|
||||
* @implSpec This is the same as calling
|
||||
* {@code format(locale, format, args)}.
|
||||
*
|
||||
* @param locale The {@linkplain Locale locale} to apply during
|
||||
* formatting. If {@code locale} is {@code null} then no localization
|
||||
* is applied.
|
||||
*
|
||||
* @param format
|
||||
* A format string as described in {@link
|
||||
* Formatter##syntax Format string syntax}.
|
||||
*
|
||||
* @param args
|
||||
* Arguments referenced by the format specifiers in the format
|
||||
* string. If there are more arguments than format specifiers, the
|
||||
* extra arguments are ignored. The maximum number of arguments is
|
||||
* extra arguments are ignored. The number of arguments is
|
||||
* variable and may be zero. The maximum number of arguments is
|
||||
* limited by the maximum dimension of a Java array as defined by
|
||||
* <cite>The Java Virtual Machine Specification</cite>.
|
||||
* The behavior on a
|
||||
* {@code null} argument depends on the {@link
|
||||
* Formatter##syntax conversion}.
|
||||
*
|
||||
* @throws IllegalFormatException
|
||||
* If a format string contains an illegal syntax, a format
|
||||
* specifier that is incompatible with the given arguments,
|
||||
* insufficient arguments given the format string, or other
|
||||
* illegal conditions. For specification of all possible
|
||||
* formatting errors, see the <a
|
||||
* href="../util/Formatter.html#detail">Details</a> section
|
||||
* of the formatter class specification.
|
||||
* formatting errors, see the {@link
|
||||
* Formatter##detail Details} section of the
|
||||
* formatter class specification.
|
||||
*
|
||||
* @return This console
|
||||
* @since 23
|
||||
*/
|
||||
public Console printf(Locale locale, String format, Object ... args) {
|
||||
throw newUnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a formatted prompt using the
|
||||
* {@link Locale##default_locale default format locale}, then reads a
|
||||
* single line of text from the console.
|
||||
*
|
||||
* @param format
|
||||
* A format string as described in {@link
|
||||
* Formatter##syntax Format string syntax}.
|
||||
*
|
||||
* @param args
|
||||
* Arguments referenced by the format specifiers in the format
|
||||
* string. If there are more arguments than format specifiers, the
|
||||
* extra arguments are ignored. The number of arguments is
|
||||
* variable and may be zero. The maximum number of arguments is
|
||||
* limited by the maximum dimension of a Java array as defined by
|
||||
* <cite>The Java Virtual Machine Specification</cite>.
|
||||
* The behavior on a
|
||||
* {@code null} argument depends on the {@link
|
||||
* Formatter##syntax conversion}.
|
||||
*
|
||||
* @throws IllegalFormatException
|
||||
* If a format string contains an illegal syntax, a format
|
||||
* specifier that is incompatible with the given arguments,
|
||||
* insufficient arguments given the format string, or other
|
||||
* illegal conditions. For specification of all possible
|
||||
* formatting errors, see the {@link
|
||||
* Formatter##detail Details} section of the
|
||||
* formatter class specification.
|
||||
*
|
||||
* @throws IOError
|
||||
* If an I/O error occurs.
|
||||
@ -251,7 +341,51 @@ public sealed class Console implements Flushable permits ProxyingConsole {
|
||||
* including any line-termination characters, or {@code null}
|
||||
* if an end of stream has been reached.
|
||||
*/
|
||||
public String readLine(String fmt, Object ... args) {
|
||||
public String readLine(String format, Object ... args) {
|
||||
throw newUnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a formatted prompt using the specified {@code locale}, then
|
||||
* reads a single line of text from the console.
|
||||
*
|
||||
* @param locale The {@linkplain Locale locale} to apply during
|
||||
* formatting. If {@code locale} is {@code null} then no localization
|
||||
* is applied.
|
||||
*
|
||||
* @param format
|
||||
* A format string as described in {@link
|
||||
* Formatter##syntax Format string syntax}.
|
||||
*
|
||||
* @param args
|
||||
* Arguments referenced by the format specifiers in the format
|
||||
* string. If there are more arguments than format specifiers, the
|
||||
* extra arguments are ignored. The number of arguments is
|
||||
* variable and may be zero. The maximum number of arguments is
|
||||
* limited by the maximum dimension of a Java array as defined by
|
||||
* <cite>The Java Virtual Machine Specification</cite>.
|
||||
* The behavior on a
|
||||
* {@code null} argument depends on the {@link
|
||||
* Formatter##syntax conversion}.
|
||||
*
|
||||
* @throws IllegalFormatException
|
||||
* If a format string contains an illegal syntax, a format
|
||||
* specifier that is incompatible with the given arguments,
|
||||
* insufficient arguments given the format string, or other
|
||||
* illegal conditions. For specification of all possible
|
||||
* formatting errors, see the {@link
|
||||
* Formatter##detail Details} section of the
|
||||
* formatter class specification.
|
||||
*
|
||||
* @throws IOError
|
||||
* If an I/O error occurs.
|
||||
*
|
||||
* @return A string containing the line read from the console, not
|
||||
* including any line-termination characters, or {@code null}
|
||||
* if an end of stream has been reached.
|
||||
* @since 23
|
||||
*/
|
||||
public String readLine(Locale locale, String format, Object ... args) {
|
||||
throw newUnsupportedOperationException();
|
||||
}
|
||||
|
||||
@ -270,29 +404,34 @@ public sealed class Console implements Flushable permits ProxyingConsole {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a formatted prompt, then reads a password or passphrase from
|
||||
* the console with echoing disabled.
|
||||
* Provides a formatted prompt using the
|
||||
* {@link Locale##default_locale default format locale}, then reads a
|
||||
* password or passphrase from the console with echoing disabled.
|
||||
*
|
||||
* @param fmt
|
||||
* A format string as described in <a
|
||||
* href="../util/Formatter.html#syntax">Format string syntax</a>
|
||||
* @param format
|
||||
* A format string as described in {@link
|
||||
* Formatter##syntax Format string syntax}
|
||||
* for the prompt text.
|
||||
*
|
||||
* @param args
|
||||
* Arguments referenced by the format specifiers in the format
|
||||
* string. If there are more arguments than format specifiers, the
|
||||
* extra arguments are ignored. The maximum number of arguments is
|
||||
* extra arguments are ignored. The number of arguments is
|
||||
* variable and may be zero. The maximum number of arguments is
|
||||
* limited by the maximum dimension of a Java array as defined by
|
||||
* <cite>The Java Virtual Machine Specification</cite>.
|
||||
* The behavior on a
|
||||
* {@code null} argument depends on the {@link
|
||||
* Formatter##syntax conversion}.
|
||||
*
|
||||
* @throws IllegalFormatException
|
||||
* If a format string contains an illegal syntax, a format
|
||||
* specifier that is incompatible with the given arguments,
|
||||
* insufficient arguments given the format string, or other
|
||||
* illegal conditions. For specification of all possible
|
||||
* formatting errors, see the <a
|
||||
* href="../util/Formatter.html#detail">Details</a>
|
||||
* section of the formatter class specification.
|
||||
* formatting errors, see the {@link
|
||||
* Formatter##detail Details} section of the
|
||||
* formatter class specification.
|
||||
*
|
||||
* @throws IOError
|
||||
* If an I/O error occurs.
|
||||
@ -301,7 +440,52 @@ public sealed class Console implements Flushable permits ProxyingConsole {
|
||||
* from the console, not including any line-termination characters,
|
||||
* or {@code null} if an end of stream has been reached.
|
||||
*/
|
||||
public char[] readPassword(String fmt, Object ... args) {
|
||||
public char[] readPassword(String format, Object ... args) {
|
||||
throw newUnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a formatted prompt using the specified {@code locale}, then
|
||||
* reads a password or passphrase from the console with echoing disabled.
|
||||
*
|
||||
* @param locale The {@linkplain Locale locale} to apply during
|
||||
* formatting. If {@code locale} is {@code null} then no localization
|
||||
* is applied.
|
||||
*
|
||||
* @param format
|
||||
* A format string as described in {@link
|
||||
* Formatter##syntax Format string syntax}
|
||||
* for the prompt text.
|
||||
*
|
||||
* @param args
|
||||
* Arguments referenced by the format specifiers in the format
|
||||
* string. If there are more arguments than format specifiers, the
|
||||
* extra arguments are ignored. The number of arguments is
|
||||
* variable and may be zero. The maximum number of arguments is
|
||||
* limited by the maximum dimension of a Java array as defined by
|
||||
* <cite>The Java Virtual Machine Specification</cite>.
|
||||
* The behavior on a
|
||||
* {@code null} argument depends on the {@link
|
||||
* Formatter##syntax conversion}.
|
||||
*
|
||||
* @throws IllegalFormatException
|
||||
* If a format string contains an illegal syntax, a format
|
||||
* specifier that is incompatible with the given arguments,
|
||||
* insufficient arguments given the format string, or other
|
||||
* illegal conditions. For specification of all possible
|
||||
* formatting errors, see the {@link
|
||||
* Formatter##detail Details} section of the
|
||||
* formatter class specification.
|
||||
*
|
||||
* @throws IOError
|
||||
* If an I/O error occurs.
|
||||
*
|
||||
* @return A character array containing the password or passphrase read
|
||||
* from the console, not including any line-termination characters,
|
||||
* or {@code null} if an end of stream has been reached.
|
||||
* @since 23
|
||||
*/
|
||||
public char[] readPassword(Locale locale, String format, Object ... args) {
|
||||
throw newUnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, 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
|
||||
@ -26,6 +26,8 @@
|
||||
package java.io;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Locale;
|
||||
|
||||
import jdk.internal.io.JdkConsole;
|
||||
|
||||
/**
|
||||
@ -83,9 +85,17 @@ final class ProxyingConsole extends Console {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Console format(String fmt, Object ... args) {
|
||||
public Console format(String format, Object ... args) {
|
||||
return format(Locale.getDefault(Locale.Category.FORMAT), format, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Console format(Locale locale, String format, Object ... args) {
|
||||
synchronized (writeLock) {
|
||||
delegate.format(fmt, args);
|
||||
delegate.format(locale, format, args);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -95,8 +105,16 @@ final class ProxyingConsole extends Console {
|
||||
*/
|
||||
@Override
|
||||
public Console printf(String format, Object ... args) {
|
||||
return printf(Locale.getDefault(Locale.Category.FORMAT), format, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Console printf(Locale locale, String format, Object ... args) {
|
||||
synchronized (writeLock) {
|
||||
delegate.printf(format, args);
|
||||
delegate.format(locale, format, args);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -105,10 +123,18 @@ final class ProxyingConsole extends Console {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String readLine(String fmt, Object ... args) {
|
||||
public String readLine(String format, Object ... args) {
|
||||
return readLine(Locale.getDefault(Locale.Category.FORMAT), format, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String readLine(Locale locale, String format, Object ... args) {
|
||||
synchronized (writeLock) {
|
||||
synchronized (readLock) {
|
||||
return delegate.readLine(fmt, args);
|
||||
return delegate.readLine(locale, format, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,10 +153,18 @@ final class ProxyingConsole extends Console {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public char[] readPassword(String fmt, Object ... args) {
|
||||
public char[] readPassword(String format, Object ... args) {
|
||||
return readPassword(Locale.getDefault(Locale.Category.FORMAT), format, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public char[] readPassword(Locale locale, String format, Object ... args) {
|
||||
synchronized (writeLock) {
|
||||
synchronized (readLock) {
|
||||
return delegate.readPassword(fmt, args);
|
||||
return delegate.readPassword(locale, format, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, 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
|
||||
@ -27,6 +27,7 @@ package jdk.internal.io;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Delegate interface for custom Console implementations.
|
||||
@ -37,11 +38,10 @@ import java.nio.charset.Charset;
|
||||
public interface JdkConsole {
|
||||
PrintWriter writer();
|
||||
Reader reader();
|
||||
JdkConsole format(String fmt, Object ... args);
|
||||
JdkConsole printf(String format, Object ... args);
|
||||
String readLine(String fmt, Object ... args);
|
||||
JdkConsole format(Locale locale, String format, Object ... args);
|
||||
String readLine(Locale locale, String format, Object ... args);
|
||||
String readLine();
|
||||
char[] readPassword(String fmt, Object ... args);
|
||||
char[] readPassword(Locale locale, String format, Object ... args);
|
||||
char[] readPassword();
|
||||
void flush();
|
||||
Charset charset();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, 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
|
||||
@ -36,6 +36,7 @@ import java.io.Writer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.Formatter;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
@ -57,23 +58,18 @@ public final class JdkConsoleImpl implements JdkConsole {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdkConsole format(String fmt, Object ... args) {
|
||||
formatter.format(fmt, args).flush();
|
||||
public JdkConsole format(Locale locale, String format, Object ... args) {
|
||||
formatter.format(locale, format, args).flush();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdkConsole printf(String format, Object ... args) {
|
||||
return format(format, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readLine(String fmt, Object ... args) {
|
||||
public String readLine(Locale locale, String format, Object ... args) {
|
||||
String line = null;
|
||||
synchronized (writeLock) {
|
||||
synchronized(readLock) {
|
||||
if (!fmt.isEmpty())
|
||||
pw.format(fmt, args);
|
||||
if (!format.isEmpty())
|
||||
pw.format(locale, format, args);
|
||||
try {
|
||||
char[] ca = readline(false);
|
||||
if (ca != null)
|
||||
@ -88,11 +84,11 @@ public final class JdkConsoleImpl implements JdkConsole {
|
||||
|
||||
@Override
|
||||
public String readLine() {
|
||||
return readLine("");
|
||||
return readLine(Locale.getDefault(Locale.Category.FORMAT), "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] readPassword(String fmt, Object ... args) {
|
||||
public char[] readPassword(Locale locale, String format, Object ... args) {
|
||||
char[] passwd = null;
|
||||
synchronized (writeLock) {
|
||||
synchronized(readLock) {
|
||||
@ -104,8 +100,8 @@ public final class JdkConsoleImpl implements JdkConsole {
|
||||
}
|
||||
IOError ioe = null;
|
||||
try {
|
||||
if (!fmt.isEmpty())
|
||||
pw.format(fmt, args);
|
||||
if (!format.isEmpty())
|
||||
pw.format(locale, format, args);
|
||||
passwd = readline(true);
|
||||
} catch (IOException x) {
|
||||
ioe = new IOError(x);
|
||||
@ -164,7 +160,7 @@ public final class JdkConsoleImpl implements JdkConsole {
|
||||
|
||||
@Override
|
||||
public char[] readPassword() {
|
||||
return readPassword("");
|
||||
return readPassword(Locale.getDefault(Locale.Category.FORMAT), "");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -30,6 +30,7 @@ import java.io.PrintWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Locale;
|
||||
|
||||
import jdk.internal.io.JdkConsole;
|
||||
import jdk.internal.io.JdkConsoleProvider;
|
||||
@ -84,21 +85,16 @@ public class JdkConsoleProviderImpl implements JdkConsoleProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdkConsole format(String fmt, Object ... args) {
|
||||
writer().format(fmt, args).flush();
|
||||
public JdkConsole format(Locale locale, String format, Object ... args) {
|
||||
writer().format(locale, format, args).flush();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdkConsole printf(String format, Object ... args) {
|
||||
return format(format, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readLine(String fmt, Object ... args) {
|
||||
public String readLine(Locale locale, String format, Object ... args) {
|
||||
try {
|
||||
initJLineIfNeeded();
|
||||
return jline.readLine(fmt.formatted(args).replace("%", "%%"));
|
||||
return jline.readLine(String.format(locale, format, args).replace("%", "%%"));
|
||||
} catch (EndOfFileException eofe) {
|
||||
return null;
|
||||
}
|
||||
@ -106,14 +102,14 @@ public class JdkConsoleProviderImpl implements JdkConsoleProvider {
|
||||
|
||||
@Override
|
||||
public String readLine() {
|
||||
return readLine("");
|
||||
return readLine(Locale.getDefault(Locale.Category.FORMAT), "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] readPassword(String fmt, Object ... args) {
|
||||
public char[] readPassword(Locale locale, String format, Object ... args) {
|
||||
try {
|
||||
initJLineIfNeeded();
|
||||
return jline.readLine(fmt.formatted(args).replace("%", "%%"), '\0')
|
||||
return jline.readLine(String.format(locale, format, args).replace("%", "%%"), '\0')
|
||||
.toCharArray();
|
||||
} catch (EndOfFileException eofe) {
|
||||
return null;
|
||||
@ -124,7 +120,7 @@ public class JdkConsoleProviderImpl implements JdkConsoleProvider {
|
||||
|
||||
@Override
|
||||
public char[] readPassword() {
|
||||
return readPassword("");
|
||||
return readPassword(Locale.getDefault(Locale.Category.FORMAT), "");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -76,7 +76,9 @@ public class Display {
|
||||
|
||||
public void resize(int rows, int columns) {
|
||||
if (rows == 0 || columns == 0) {
|
||||
columns = 1;
|
||||
// OpenJDK patch. Original code assigned 1 to columns, which ended up
|
||||
// appending " \b" to the prompt in certain cases.
|
||||
columns = Integer.MAX_VALUE - 1;
|
||||
rows = 1;
|
||||
}
|
||||
if (this.rows != rows || this.columns != columns) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2024, 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
|
||||
@ -34,6 +34,8 @@ import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
import jdk.internal.io.JdkConsole;
|
||||
import jdk.internal.io.JdkConsoleProvider;
|
||||
import jdk.jshell.JShellConsole;
|
||||
@ -193,8 +195,8 @@ public class ConsoleImpl {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public JdkConsole format(String fmt, Object... args) {
|
||||
writer().format(fmt, args).flush();
|
||||
public JdkConsole format(Locale locale, String format, Object... args) {
|
||||
writer().format(locale, format, args).flush();
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -202,19 +204,11 @@ public class ConsoleImpl {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public JdkConsole printf(String format, Object... args) {
|
||||
return format(format, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String readLine(String fmt, Object... args) {
|
||||
public String readLine(Locale locale, String format, Object... args) {
|
||||
try {
|
||||
return sendAndReceive(() -> {
|
||||
remoteInput.write(Task.READ_LINE.ordinal());
|
||||
String prompt = fmt.formatted(args);
|
||||
String prompt = String.format(locale, format, args);
|
||||
char[] chars = prompt.toCharArray();
|
||||
sendChars(chars, 0, chars.length);
|
||||
char[] line = readChars();
|
||||
@ -230,18 +224,18 @@ public class ConsoleImpl {
|
||||
*/
|
||||
@Override
|
||||
public String readLine() {
|
||||
return readLine("");
|
||||
return readLine(Locale.getDefault(Locale.Category.FORMAT), "");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public char[] readPassword(String fmt, Object... args) {
|
||||
public char[] readPassword(Locale locale, String format, Object... args) {
|
||||
try {
|
||||
return sendAndReceive(() -> {
|
||||
remoteInput.write(Task.READ_PASSWORD.ordinal());
|
||||
String prompt = fmt.formatted(args);
|
||||
String prompt = String.format(locale, format, args);
|
||||
char[] chars = prompt.toCharArray();
|
||||
sendChars(chars, 0, chars.length);
|
||||
return readChars();
|
||||
@ -256,7 +250,7 @@ public class ConsoleImpl {
|
||||
*/
|
||||
@Override
|
||||
public char[] readPassword() {
|
||||
return readPassword("");
|
||||
return readPassword(Locale.getDefault(Locale.Category.FORMAT), "");
|
||||
}
|
||||
|
||||
/**
|
||||
|
107
test/jdk/java/io/Console/LocaleTest.java
Normal file
107
test/jdk/java/io/Console/LocaleTest.java
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2024, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8330276
|
||||
* @summary Tests Console methods that have Locale as an argument
|
||||
* @library /test/lib
|
||||
* @modules jdk.internal.le jdk.localedata
|
||||
*/
|
||||
public class LocaleTest {
|
||||
private static Calendar TODAY = new GregorianCalendar(2024, Calendar.APRIL, 22);
|
||||
private static String FORMAT = "%1$tY-%1$tB-%1$te %1$tA";
|
||||
// We want to limit the expected strings within US-ASCII charset, as
|
||||
// the native encoding is determined as such, which is used by
|
||||
// the `Process` class under jtreg environment.
|
||||
private static List<String> EXPECTED = List.of(
|
||||
String.format(Locale.UK, FORMAT, TODAY),
|
||||
String.format(Locale.FRANCE, FORMAT, TODAY),
|
||||
String.format(Locale.GERMANY, FORMAT, TODAY),
|
||||
String.format(Locale.of("es"), FORMAT, TODAY),
|
||||
String.format((Locale)null, FORMAT, TODAY),
|
||||
String.format((Locale)null, FORMAT, TODAY),
|
||||
String.format((Locale)null, FORMAT, TODAY),
|
||||
String.format((Locale)null, FORMAT, TODAY)
|
||||
);
|
||||
|
||||
public static void main(String... args) throws Throwable {
|
||||
if (args.length == 0) {
|
||||
// no arg will launch the child process that actually perform tests
|
||||
var pb = ProcessTools.createTestJavaProcessBuilder(
|
||||
"LocaleTest", "dummy");
|
||||
var input = new File(System.getProperty("test.src", "."), "input.txt");
|
||||
pb.redirectInput(input);
|
||||
var oa = ProcessTools.executeProcess(pb);
|
||||
if (oa.getExitValue() == -1) {
|
||||
System.out.println("System.console() returns null. Ignoring the test.");
|
||||
} else {
|
||||
var output = oa.asLines();
|
||||
var resultText =
|
||||
"""
|
||||
Actual output: %s
|
||||
Expected output: %s
|
||||
""".formatted(output, EXPECTED);
|
||||
if (!output.equals(EXPECTED)) {
|
||||
throw new RuntimeException("Standard out had unexpected strings:\n" + resultText);
|
||||
} else {
|
||||
oa.shouldHaveExitValue(0);
|
||||
System.out.println("Formatting with explicit Locale succeeded.\n" + resultText);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var con = System.console();
|
||||
if (con != null) {
|
||||
// tests these additional methods that take a Locale
|
||||
con.format(Locale.UK, FORMAT, TODAY);
|
||||
con.printf("\n");
|
||||
con.printf(Locale.FRANCE, FORMAT, TODAY);
|
||||
con.printf("\n");
|
||||
con.readLine(Locale.GERMANY, FORMAT, TODAY);
|
||||
con.printf("\n");
|
||||
con.readPassword(Locale.of("es"), FORMAT, TODAY);
|
||||
con.printf("\n");
|
||||
|
||||
// tests null locale
|
||||
con.format((Locale)null, FORMAT, TODAY);
|
||||
con.printf("\n");
|
||||
con.printf((Locale)null, FORMAT, TODAY);
|
||||
con.printf("\n");
|
||||
con.readLine((Locale)null, FORMAT, TODAY);
|
||||
con.printf("\n");
|
||||
con.readPassword((Locale)null, FORMAT, TODAY);
|
||||
} else {
|
||||
// Exit with -1
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user