You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2015/10/25 19:35:46 UTC
incubator-groovy git commit: GROOVY-4888 - groovy console script
execution output appears in all output windows (closes #160)
Repository: incubator-groovy
Updated Branches:
refs/heads/master 0a1d8b469 -> 5c556c06c
GROOVY-4888 - groovy console script execution output appears in all output windows (closes #160)
Project: http://git-wip-us.apache.org/repos/asf/incubator-groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-groovy/commit/5c556c06
Tree: http://git-wip-us.apache.org/repos/asf/incubator-groovy/tree/5c556c06
Diff: http://git-wip-us.apache.org/repos/asf/incubator-groovy/diff/5c556c06
Branch: refs/heads/master
Commit: 5c556c06ca2f5be367415a66f6af4e6dd531767f
Parents: 0a1d8b4
Author: John Wagenleitner <jo...@gmail.com>
Authored: Sat Oct 24 23:30:34 2015 -0700
Committer: pascalschumacher <pa...@gmx.net>
Committed: Sun Oct 25 19:28:02 2015 +0100
----------------------------------------------------------------------
.../src/main/groovy/groovy/ui/Console.groovy | 44 ++++++++++++----
.../groovy/ui/SystemOutputInterceptor.java | 39 ++++++++++++--
.../groovy/swing/SwingBuilderConsoleTest.groovy | 53 ++++++++++++++++++++
3 files changed, 121 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/5c556c06/subprojects/groovy-console/src/main/groovy/groovy/ui/Console.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-console/src/main/groovy/groovy/ui/Console.groovy b/subprojects/groovy-console/src/main/groovy/groovy/ui/Console.groovy
index 6324bef..0746803 100644
--- a/subprojects/groovy-console/src/main/groovy/groovy/ui/Console.groovy
+++ b/subprojects/groovy-console/src/main/groovy/groovy/ui/Console.groovy
@@ -887,42 +887,64 @@ class Console implements CaretListener, HyperlinkListener, ComponentListener, Fo
updateFontSize(inputArea.font.size + 2)
}
- static boolean notifySystemOut(String str) {
+ static boolean notifySystemOut(int consoleId, String str) {
if (!captureStdOut) {
// Output as normal
return true
}
+ Closure doAppend = {
+ Console console = findConsoleById(consoleId)
+ if (console) {
+ console.appendOutputLines(str, console.outputStyle)
+ } else {
+ consoleControllers.each {it.appendOutputLines(str, it.outputStyle)}
+ }
+ }
+
// Put onto GUI
if (EventQueue.isDispatchThread()) {
- consoleControllers.each {it.appendOutputLines(str, it.outputStyle)}
+ doAppend.call()
}
else {
- SwingUtilities.invokeLater {
- consoleControllers.each {it.appendOutputLines(str, it.outputStyle)}
- }
+ SwingUtilities.invokeLater doAppend
}
return false
}
- static boolean notifySystemErr(String str) {
+ static boolean notifySystemErr(int consoleId, String str) {
if (!captureStdErr) {
// Output as normal
return true
}
+ Closure doAppend = {
+ Console console = findConsoleById(consoleId)
+ if (console) {
+ console.appendStacktrace(str)
+ } else {
+ consoleControllers.each {it.appendStacktrace(str)}
+ }
+ }
+
// Put onto GUI
if (EventQueue.isDispatchThread()) {
- consoleControllers.each {it.appendStacktrace(str)}
+ doAppend.call()
}
else {
- SwingUtilities.invokeLater {
- consoleControllers.each {it.appendStacktrace(str)}
- }
+ SwingUtilities.invokeLater doAppend
}
return false
}
+ int getConsoleId() {
+ return System.identityHashCode(this)
+ }
+
+ private static Console findConsoleById(int consoleId) {
+ return consoleControllers.find { it.consoleId == consoleId }
+ }
+
// actually run the script
void runScript(EventObject evt = null) {
@@ -1003,6 +1025,7 @@ class Console implements CaretListener, HyperlinkListener, ComponentListener, Fo
// Run in a thread outside of EDT, this method is usually called inside the EDT
runThread = Thread.start {
try {
+ systemOutInterceptor.setConsoleId(this.getConsoleId())
SwingUtilities.invokeLater { showExecutingMessage() }
String name = scriptFile?.name ?: (DEFAULT_SCRIPT_NAME_START + scriptNameCounter++)
if(beforeExecution) {
@@ -1037,6 +1060,7 @@ class Console implements CaretListener, HyperlinkListener, ComponentListener, Fo
runThread = null
scriptRunning = false
interruptAction.enabled = false
+ systemOutInterceptor.removeConsoleId()
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/5c556c06/subprojects/groovy-console/src/main/groovy/groovy/ui/SystemOutputInterceptor.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-console/src/main/groovy/groovy/ui/SystemOutputInterceptor.java b/subprojects/groovy-console/src/main/groovy/groovy/ui/SystemOutputInterceptor.java
index 0df242b..7f47d8e 100644
--- a/subprojects/groovy-console/src/main/groovy/groovy/ui/SystemOutputInterceptor.java
+++ b/subprojects/groovy-console/src/main/groovy/groovy/ui/SystemOutputInterceptor.java
@@ -32,10 +32,18 @@ public class SystemOutputInterceptor extends FilterOutputStream {
private Closure callback;
private boolean output;
+ private static final ThreadLocal<Integer> consoleId = new ThreadLocal<Integer>() {
+ @Override
+ protected Integer initialValue() {
+ return Integer.valueOf(0);
+ }
+ };
+
/**
* Constructor
*
- * @param callback accepts a string to be sent to std out and returns a Boolean.
+ * @param callback accepts the id of the target Console instance and a
+ * string to be sent to std out and returns a Boolean.
* If the return value is true, output will be sent to
* System.out, otherwise it will not.
*/
@@ -46,7 +54,8 @@ public class SystemOutputInterceptor extends FilterOutputStream {
/**
* Constructor
*
- * @param callback accepts a string to be sent to std out and returns a Boolean.
+ * @param callback accepts the id of the target Console instance and a
+ * string to be sent to std out and returns a Boolean.
* If the return value is true, output will be sent to
* System.out/System.err, otherwise it will not.
* @param output flag that tells whether System.out needs capturing ot System.err
@@ -84,10 +93,10 @@ public class SystemOutputInterceptor extends FilterOutputStream {
}
/**
- * Intercepts output - moret common case of byte[]
+ * Intercepts output - more common case of byte[]
*/
public void write(byte[] b, int off, int len) throws IOException {
- Boolean result = (Boolean) callback.call(new String(b, off, len));
+ Boolean result = (Boolean) callback.call(consoleId.get().intValue(), new String(b, off, len));
if (result) {
out.write(b, off, len);
}
@@ -97,9 +106,29 @@ public class SystemOutputInterceptor extends FilterOutputStream {
* Intercepts output - single characters
*/
public void write(int b) throws IOException {
- Boolean result = (Boolean) callback.call(String.valueOf((char) b));
+ Boolean result = (Boolean) callback.call(consoleId.get().intValue(), String.valueOf((char) b));
if (result) {
out.write(b);
}
}
+
+ /**
+ * Threads executing a script should call this method at the start of execution
+ * in order to set the id of the console that is hosting the thread of execution. This
+ * should be called prior to any output that is generated. The consoleId will
+ * be passed to the callback.
+ *
+ * @param consoleId id of the Console instance executing the script
+ */
+ public void setConsoleId(int consoleId) {
+ this.consoleId.set(Integer.valueOf(consoleId));
+ }
+
+ /**
+ * Threads executing a script should call this method after
+ * execution completes in order to unregister the consoleId.
+ */
+ public void removeConsoleId() {
+ this.consoleId.remove();
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/5c556c06/subprojects/groovy-console/src/test/groovy/groovy/swing/SwingBuilderConsoleTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-console/src/test/groovy/groovy/swing/SwingBuilderConsoleTest.groovy b/subprojects/groovy-console/src/test/groovy/groovy/swing/SwingBuilderConsoleTest.groovy
index 7705409..9aca8a4 100644
--- a/subprojects/groovy-console/src/test/groovy/groovy/swing/SwingBuilderConsoleTest.groovy
+++ b/subprojects/groovy-console/src/test/groovy/groovy/swing/SwingBuilderConsoleTest.groovy
@@ -512,4 +512,57 @@ class SwingBuilderConsoleTest extends GroovySwingTestCase {
}
}
+ void testSystemOutputAndErrorRedirectedToCorrectConsole() {
+ testInEDT {
+ SwingUtilities.metaClass.static.invokeLater = { Runnable runnable ->
+ runnable.run()
+ }
+ Thread.metaClass.static.start = { Runnable runnable ->
+ runnable.run()
+ }
+
+ Console.prefs = testPreferences
+
+ try {
+ def swing = new SwingBuilder()
+ final Console console = new Console()
+ swing.controller = console
+ swing.build(new ConsoleActions())
+ console.run()
+ console.fileNewWindow()
+ final Console console2 = Console.consoleControllers.last()
+
+ console.showScriptInOutput = false
+ console2.showScriptInOutput = false
+
+ def doc = console.outputArea.document
+ def doc2 = console2.outputArea.document
+
+ assert console.consoleId != console2.consoleId
+
+ console.inputArea.text = 'println "test1"'
+ console.runScript()
+
+ assert 'test1' == doc.getText(0, doc.length).trim()
+ assert '' == doc2.getText(0, doc2.length).trim()
+
+ console2.inputArea.text = 'println "test2"'
+ console2.runScript()
+
+ assert 'test1' == doc.getText(0, doc.length).trim()
+ assert 'test2' == doc2.getText(0, doc2.length).trim()
+
+ console2.inputArea.text = 'System.err.println "error2"'
+ console2.runScript()
+
+ assert 'test1' == doc.getText(0, doc.length).trim()
+ assert doc2.getText(0, doc2.length) ==~ /(?s)(test2)[^\w].*(error2).*/
+ } finally {
+ GroovySystem.metaClassRegistry.removeMetaClass(Thread)
+ GroovySystem.metaClassRegistry.removeMetaClass(SwingUtilities)
+ GroovySystem.metaClassRegistry.removeMetaClass(Preferences)
+ }
+ }
+ }
+
}