8308591: JLine as the default Console provider
Reviewed-by: alanb
This commit is contained in:
parent
b772e67e29
commit
bae2247938
@ -344,16 +344,33 @@ public sealed class Console implements Flushable permits ProxyingConsole {
|
||||
throw newUnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return {@code true} if the {@code Console} instance is a terminal}
|
||||
* <p>
|
||||
* This method returns {@code true} if the console device, associated with the current
|
||||
* Java virtual machine, is a terminal, typically an interactive command line
|
||||
* connected to a keyboard and display.
|
||||
*
|
||||
* @implNote The default implementation returns the value equivalent to calling
|
||||
* {@code isatty(stdin/stdout)} on POSIX platforms, or whether standard in/out file
|
||||
* descriptors are character devices or not on Windows.
|
||||
*
|
||||
* @since 22
|
||||
*/
|
||||
public boolean isTerminal() {
|
||||
return istty;
|
||||
}
|
||||
|
||||
private static UnsupportedOperationException newUnsupportedOperationException() {
|
||||
return new UnsupportedOperationException(
|
||||
"Console class itself does not provide implementation");
|
||||
}
|
||||
|
||||
private static native String encoding();
|
||||
private static final boolean istty = istty();
|
||||
static final Charset CHARSET;
|
||||
static {
|
||||
Charset cs = null;
|
||||
boolean istty = istty();
|
||||
|
||||
if (istty) {
|
||||
String csname = encoding();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2023, 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,17 +34,13 @@ import jdk.internal.io.JdkConsole;
|
||||
*/
|
||||
final class ProxyingConsole extends Console {
|
||||
private final JdkConsole delegate;
|
||||
private final Object readLock;
|
||||
private final Object writeLock;
|
||||
private final Reader reader;
|
||||
private final PrintWriter printWriter;
|
||||
private final Object readLock = new Object();
|
||||
private final Object writeLock = new Object();
|
||||
private volatile Reader reader;
|
||||
private volatile PrintWriter printWriter;
|
||||
|
||||
ProxyingConsole(JdkConsole delegate) {
|
||||
this.delegate = delegate;
|
||||
readLock = new Object();
|
||||
writeLock = new Object();
|
||||
reader = new WrappingReader(delegate.reader(), readLock);
|
||||
printWriter = new WrappingWriter(delegate.writer(), writeLock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,6 +48,16 @@ final class ProxyingConsole extends Console {
|
||||
*/
|
||||
@Override
|
||||
public PrintWriter writer() {
|
||||
PrintWriter printWriter = this.printWriter;
|
||||
if (printWriter == null) {
|
||||
synchronized (this) {
|
||||
printWriter = this.printWriter;
|
||||
if (printWriter == null) {
|
||||
printWriter = new WrappingWriter(delegate.writer(), writeLock);
|
||||
this.printWriter = printWriter;
|
||||
}
|
||||
}
|
||||
}
|
||||
return printWriter;
|
||||
}
|
||||
|
||||
@ -60,6 +66,16 @@ final class ProxyingConsole extends Console {
|
||||
*/
|
||||
@Override
|
||||
public Reader reader() {
|
||||
Reader reader = this.reader;
|
||||
if (reader == null) {
|
||||
synchronized (this) {
|
||||
reader = this.reader;
|
||||
if (reader == null) {
|
||||
reader = new WrappingReader(delegate.reader(), readLock);
|
||||
this.reader = reader;
|
||||
}
|
||||
}
|
||||
}
|
||||
return reader;
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ public interface JdkConsoleProvider {
|
||||
/**
|
||||
* The module name of the JdkConsole default provider.
|
||||
*/
|
||||
String DEFAULT_PROVIDER_MODULE_NAME = "java.base";
|
||||
String DEFAULT_PROVIDER_MODULE_NAME = "jdk.internal.le";
|
||||
|
||||
/**
|
||||
* {@return the Console instance, or {@code null} if not available}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2023, 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
|
||||
@ -91,6 +91,7 @@ public class JdkConsoleProviderImpl implements JdkConsoleProvider {
|
||||
@Override
|
||||
public String readLine(String fmt, Object ... args) {
|
||||
try {
|
||||
initJLineIfNeeded();
|
||||
return jline.readLine(fmt.formatted(args));
|
||||
} catch (EndOfFileException eofe) {
|
||||
return null;
|
||||
@ -105,6 +106,7 @@ public class JdkConsoleProviderImpl implements JdkConsoleProvider {
|
||||
@Override
|
||||
public char[] readPassword(String fmt, Object ... args) {
|
||||
try {
|
||||
initJLineIfNeeded();
|
||||
return jline.readLine(fmt.formatted(args), '\0').toCharArray();
|
||||
} catch (EndOfFileException eofe) {
|
||||
return null;
|
||||
@ -126,12 +128,24 @@ public class JdkConsoleProviderImpl implements JdkConsoleProvider {
|
||||
return terminal.encoding();
|
||||
}
|
||||
|
||||
private final LineReader jline;
|
||||
private final Terminal terminal;
|
||||
private volatile LineReader jline;
|
||||
|
||||
public JdkConsoleImpl(Terminal terminal) {
|
||||
this.terminal = terminal;
|
||||
this.jline = LineReaderBuilder.builder().terminal(terminal).build();
|
||||
}
|
||||
|
||||
private void initJLineIfNeeded() {
|
||||
LineReader jline = this.jline;
|
||||
if (jline == null) {
|
||||
synchronized (this) {
|
||||
jline = this.jline;
|
||||
if (jline == null) {
|
||||
jline = LineReaderBuilder.builder().terminal(terminal).build();
|
||||
this.jline = jline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
* @summary Tests System.console() returns correct Console (or null) from the expected
|
||||
* module.
|
||||
* @modules java.base/java.io:+open
|
||||
* @run main/othervm ModuleSelectionTest java.base
|
||||
* @run main/othervm ModuleSelectionTest jdk.internal.le
|
||||
* @run main/othervm -Djdk.console=jdk.internal.le ModuleSelectionTest jdk.internal.le
|
||||
* @run main/othervm -Djdk.console=java.base ModuleSelectionTest java.base
|
||||
* @run main/othervm --limit-modules java.base ModuleSelectionTest java.base
|
||||
|
Loading…
Reference in New Issue
Block a user