Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8330276: Console methods with explicit Locale #18923

Closed
272 changes: 228 additions & 44 deletions src/java.base/share/classes/java/io/Console.java

Large diffs are not rendered by default.

50 changes: 42 additions & 8 deletions src/java.base/share/classes/java/io/ProxyingConsole.java
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -26,6 +26,8 @@
package java.io;

import java.nio.charset.Charset;
import java.util.Locale;

import jdk.internal.io.JdkConsole;

/**
Expand Down Expand Up @@ -83,9 +85,17 @@ public Reader reader() {
* {@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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the number of calls to Locale.getDefault(Locale.Category.FORMAT) it might be worthwhile to cache that in the Proxying Console or in the JdkConsoleImpl.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially, I thought about it but did not cache it here because it is cached in the Locale class, and the call returns the cached value.

}

/**
* {@inheritDoc}
*/
@Override
public Console format(Locale locale, String format, Object ... args) {
synchronized (writeLock) {
delegate.format(fmt, args);
delegate.format(locale, format, args);
}
return this;
}
Expand All @@ -95,8 +105,16 @@ public Console format(String fmt, Object ... args) {
*/
@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;
}
Expand All @@ -105,10 +123,18 @@ public Console printf(String format, Object ... args) {
* {@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);
}
}
}
Expand All @@ -127,10 +153,18 @@ public String readLine() {
* {@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);
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/java.base/share/classes/jdk/internal/io/JdkConsole.java
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -27,6 +27,7 @@
import java.io.PrintWriter;
import java.io.Reader;
import java.nio.charset.Charset;
import java.util.Locale;

/**
* Delegate interface for custom Console implementations.
Expand All @@ -37,11 +38,10 @@
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();
Expand Down
28 changes: 12 additions & 16 deletions src/java.base/share/classes/jdk/internal/io/JdkConsoleImpl.java
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -36,6 +36,7 @@
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;
Expand All @@ -57,23 +58,18 @@ public Reader reader() {
}

@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)
Expand All @@ -88,11 +84,11 @@ public String readLine(String fmt, Object ... args) {

@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) {
Expand All @@ -104,8 +100,8 @@ public char[] readPassword(String fmt, Object ... args) {
}
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);
Expand Down Expand Up @@ -164,7 +160,7 @@ public void run() {

@Override
public char[] readPassword() {
return readPassword("");
return readPassword(Locale.getDefault(Locale.Category.FORMAT), "");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
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;
Expand Down Expand Up @@ -84,36 +85,31 @@ public Reader reader() {
}

@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;
}
}

@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;
Expand All @@ -124,7 +120,7 @@ public char[] readPassword(String fmt, Object ... args) {

@Override
public char[] readPassword() {
return readPassword("");
return readPassword(Locale.getDefault(Locale.Category.FORMAT), "");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ public void setDelayLineWrap(boolean v) {

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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -34,6 +34,8 @@
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;
Expand Down Expand Up @@ -193,28 +195,20 @@ public void close() throws IOException {
* {@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;
}

/**
* {@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();
Expand All @@ -230,18 +224,18 @@ public String readLine(String fmt, Object... args) {
*/
@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();
Expand All @@ -256,7 +250,7 @@ public char[] readPassword(String fmt, Object... args) {
*/
@Override
public char[] readPassword() {
return readPassword("");
return readPassword(Locale.getDefault(Locale.Category.FORMAT), "");
}

/**
Expand Down
Loading