Skip to content

Commit 7d87821

Browse files
committed
ConsoleService: add API for stdout/stderr output
Now, interested parties can add themselves as OutputListeners, and they will receive notification when output occurs to stdout and stderr. One cool thing is that the notifications are limited to output produced by threads _of this SciJava Context_. This is achieved via the new ThreadService#getThreadContext(Thread) method, which checks the calling thread to see whether its Context matches this one. Actually, this commit does not _quite_ finish adding working support for this feature. One more piece is needed -- see the next commit.
1 parent 7be6e92 commit 7d87821

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

src/main/java/org/scijava/console/ConsoleService.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
* Interface for service that manages interaction with the console.
4141
* <p>
4242
* In particular, this is the service that defines how command line arguments
43-
* are handled.
43+
* are handled. It also provides an extension mechanism for {@code stdout} and
44+
* {@code stderr} logging.
4445
* </p>
4546
*
4647
* @author Curtis Rueden
@@ -55,4 +56,13 @@ public interface ConsoleService extends
5556
*/
5657
void processArgs(String... args);
5758

59+
/** Adds a listener for output sent to {@code stdout} or {@code stderr}. */
60+
void addOutputListener(OutputListener l);
61+
62+
/** Removes a listener for output sent to {@code stdout} or {@code stderr}. */
63+
void removeOutputListener(OutputListener l);
64+
65+
/** Notifies listeners of output sent to {@code stdout} or {@code stderr}. */
66+
void notifyListeners(OutputEvent event);
67+
5868
}

src/main/java/org/scijava/console/DefaultConsoleService.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232
package org.scijava.console;
3333

34+
import java.io.PrintStream;
35+
import java.util.ArrayList;
3436
import java.util.LinkedList;
3537

3638
import org.scijava.log.LogService;
@@ -53,6 +55,11 @@ public class DefaultConsoleService extends
5355
@Parameter
5456
private LogService log;
5557

58+
private MultiPrintStream sysout, syserr;
59+
60+
/** List of listeners for {@code stdout} and {@code stderr} output. */
61+
private ArrayList<OutputListener> listeners;
62+
5663
// -- ConsoleService methods --
5764

5865
@Override
@@ -76,6 +83,32 @@ public void processArgs(final String... args) {
7683
}
7784
}
7885

86+
@Override
87+
public void addOutputListener(final OutputListener l) {
88+
if (listeners == null) initListeners();
89+
synchronized (listeners) {
90+
listeners.add(l);
91+
}
92+
}
93+
94+
@Override
95+
public void removeOutputListener(final OutputListener l) {
96+
if (listeners == null) initListeners();
97+
synchronized (listeners) {
98+
listeners.remove(l);
99+
}
100+
}
101+
102+
@Override
103+
public void notifyListeners(final OutputEvent event) {
104+
if (listeners == null) initListeners();
105+
synchronized (listeners) {
106+
for (final OutputListener l : listeners) {
107+
l.outputOccurred(event);
108+
}
109+
}
110+
}
111+
79112
// -- PTService methods --
80113

81114
@Override
@@ -91,4 +124,25 @@ public Class<LinkedList<String>> getType() {
91124
return (Class) LinkedList.class;
92125
}
93126

127+
// -- Helper methods - lazy initialization --
128+
129+
/** Initializes {@link #listeners} and related data structures. */
130+
private synchronized void initListeners() {
131+
if (listeners != null) return; // already initialized
132+
133+
sysout = multiPrintStream(System.out);
134+
if (System.out != sysout) System.setOut(sysout);
135+
syserr = multiPrintStream(System.err);
136+
if (System.err != syserr) System.setErr(syserr);
137+
138+
listeners = new ArrayList<OutputListener>();
139+
}
140+
141+
// -- Helper methods --
142+
143+
private MultiPrintStream multiPrintStream(final PrintStream ps) {
144+
if (ps instanceof MultiPrintStream) return (MultiPrintStream) ps;
145+
return new MultiPrintStream(ps);
146+
}
147+
94148
}

0 commit comments

Comments
 (0)