From 1c3ab6a2898659de612a8cd6be8bcf4bd923ce56 Mon Sep 17 00:00:00 2001 From: Adam Murdoch Date: Sat, 8 Sep 2012 08:44:53 +1000 Subject: [PATCH] Extracted superclass for Terminals implementations, and fixed thread-safety. --- .../platform/internal/AbstractTerminals.java | 28 +++++++++++++++++++ .../platform/internal/TerminfoTerminals.java | 21 +++----------- .../platform/internal/WindowsTerminals.java | 22 +++------------ 3 files changed, 36 insertions(+), 35 deletions(-) create mode 100644 src/main/java/net/rubygrapefruit/platform/internal/AbstractTerminals.java diff --git a/src/main/java/net/rubygrapefruit/platform/internal/AbstractTerminals.java b/src/main/java/net/rubygrapefruit/platform/internal/AbstractTerminals.java new file mode 100644 index 0000000..01fce60 --- /dev/null +++ b/src/main/java/net/rubygrapefruit/platform/internal/AbstractTerminals.java @@ -0,0 +1,28 @@ +package net.rubygrapefruit.platform.internal; + +import net.rubygrapefruit.platform.Terminal; +import net.rubygrapefruit.platform.Terminals; + +public abstract class AbstractTerminals implements Terminals { + private static Output currentlyOpen; + private static AbstractTerminal current; + + public Terminal getTerminal(Output output) { + synchronized (AbstractTerminals.class) { + if (currentlyOpen != null && currentlyOpen != output) { + throw new UnsupportedOperationException("Currently only one output can be used as a terminal."); + } + + if (current == null) { + AbstractTerminal terminal = createTerminal(output); + terminal.init(); + currentlyOpen = output; + current = terminal; + } + + return current; + } + } + + protected abstract AbstractTerminal createTerminal(Output output); +} diff --git a/src/main/java/net/rubygrapefruit/platform/internal/TerminfoTerminals.java b/src/main/java/net/rubygrapefruit/platform/internal/TerminfoTerminals.java index 552cd49..856a319 100755 --- a/src/main/java/net/rubygrapefruit/platform/internal/TerminfoTerminals.java +++ b/src/main/java/net/rubygrapefruit/platform/internal/TerminfoTerminals.java @@ -1,27 +1,14 @@ package net.rubygrapefruit.platform.internal; -import net.rubygrapefruit.platform.Terminal; -import net.rubygrapefruit.platform.Terminals; import net.rubygrapefruit.platform.internal.jni.PosixTerminalFunctions; -public class TerminfoTerminals implements Terminals { - private static Output currentlyOpen; - private static TerminfoTerminal current; - +public class TerminfoTerminals extends AbstractTerminals { public boolean isTerminal(Output output) { return PosixTerminalFunctions.isatty(output.ordinal()); } - public Terminal getTerminal(Output output) { - if (currentlyOpen != null && currentlyOpen != output) { - throw new UnsupportedOperationException("Currently only one output can be used as a terminal."); - } - if (current == null) { - current = new TerminfoTerminal(output); - current.init(); - } - - currentlyOpen = output; - return current; + @Override + protected AbstractTerminal createTerminal(Output output) { + return new TerminfoTerminal(output); } } diff --git a/src/main/java/net/rubygrapefruit/platform/internal/WindowsTerminals.java b/src/main/java/net/rubygrapefruit/platform/internal/WindowsTerminals.java index 49be350..20c8cfd 100755 --- a/src/main/java/net/rubygrapefruit/platform/internal/WindowsTerminals.java +++ b/src/main/java/net/rubygrapefruit/platform/internal/WindowsTerminals.java @@ -1,14 +1,9 @@ package net.rubygrapefruit.platform.internal; import net.rubygrapefruit.platform.NativeException; -import net.rubygrapefruit.platform.Terminal; -import net.rubygrapefruit.platform.Terminals; import net.rubygrapefruit.platform.internal.jni.WindowsConsoleFunctions; -public class WindowsTerminals implements Terminals { - private static Output currentlyOpen; - private static WindowsTerminal current; - +public class WindowsTerminals extends AbstractTerminals { public boolean isTerminal(Output output) { FunctionResult result = new FunctionResult(); boolean console = WindowsConsoleFunctions.isConsole(output.ordinal(), result); @@ -19,17 +14,8 @@ public class WindowsTerminals implements Terminals { return console; } - public Terminal getTerminal(Output output) { - if (currentlyOpen !=null && currentlyOpen != output) { - throw new UnsupportedOperationException("Currently only one output can be used as a terminal."); - } - - if (current == null) { - current = new WindowsTerminal(output); - current.init(); - } - - currentlyOpen = output; - return current; + @Override + protected AbstractTerminal createTerminal(Output output) { + return new WindowsTerminal(output); } }