Skip to content

Commit

Permalink
8308591: JLine as the default Console provider
Browse files Browse the repository at this point in the history
Reviewed-by: alanb
  • Loading branch information
naotoj committed Jul 20, 2023
1 parent b772e67 commit bae2247
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 15 deletions.
19 changes: 18 additions & 1 deletion src/java.base/share/classes/java/io/Console.java
Original file line number Diff line number Diff line change
Expand Up @@ -344,16 +344,33 @@ public Charset charset() {
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();
Expand Down
34 changes: 25 additions & 9 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, 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
Expand Down Expand Up @@ -34,24 +34,30 @@
*/
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);
}

/**
* {@inheritDoc}
*/
@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;
}

Expand All @@ -60,6 +66,16 @@ public PrintWriter writer() {
*/
@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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
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, 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
Expand Down Expand Up @@ -91,6 +91,7 @@ public JdkConsole printf(String format, Object ... args) {
@Override
public String readLine(String fmt, Object ... args) {
try {
initJLineIfNeeded();
return jline.readLine(fmt.formatted(args));
} catch (EndOfFileException eofe) {
return null;
Expand All @@ -105,6 +106,7 @@ public String readLine() {
@Override
public char[] readPassword(String fmt, Object ... args) {
try {
initJLineIfNeeded();
return jline.readLine(fmt.formatted(args), '\0').toCharArray();
} catch (EndOfFileException eofe) {
return null;
Expand All @@ -126,12 +128,24 @@ public Charset charset() {
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;
}
}
}
}
}
}
2 changes: 1 addition & 1 deletion test/jdk/java/io/Console/ModuleSelectionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

1 comment on commit bae2247

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

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

Please sign in to comment.