package bndtools.launch.bnd;
import java.io.IOException;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.IStreamListener;
import org.eclipse.debug.core.model.IStreamMonitor;
import org.eclipse.debug.core.model.IStreamsProxy2;
import aQute.bnd.build.ProjectLauncher;
import aQute.bnd.build.RunSession;
public class BndStreamsProxy implements IStreamsProxy2 {
final ProjectLauncher projectLauncher;
final RunSession session;
Job job;
StreamMonitor stdout;
StreamMonitor stderr;
public BndStreamsProxy(ProjectLauncher pl, RunSession session) {
this.projectLauncher = pl;
this.session = session;
try {
session.stdout(stdout = new StreamMonitor());
session.stderr(stderr = new StreamMonitor());
} catch (Exception e) {
e.printStackTrace();
// ignore
}
}
class StreamMonitor implements IStreamMonitor, Appendable {
final StringBuffer sb = new StringBuffer();
final ConcurrentHashMap<IStreamListener,Integer> listeners = new ConcurrentHashMap<IStreamListener,Integer>();
@Override
public void addListener(IStreamListener listener) {
listeners.put(listener, 0);
}
@Override
public void removeListener(IStreamListener listener) {
listeners.remove(listener);
}
@Override
public String getContents() {
return sb.toString();
}
@Override
public Appendable append(char ch) throws IOException {
sb.append(ch);
trigger();
return this;
}
@Override
public Appendable append(CharSequence text) throws IOException {
sb.append(text);
trigger();
return this;
}
@Override
public Appendable append(CharSequence text, int start, int length) throws IOException {
sb.append(text, start, length);
trigger();
return this;
}
public void flush() {
for (Entry<IStreamListener,Integer> listener : listeners.entrySet()) {
int start = listener.getValue();
int end = sb.length();
listener.setValue(end);
listener.getKey().streamAppended(sb.substring(start, end), this);
}
}
}
synchronized void trigger() {
if (job == null) {
job = new Job("Stream trigger") {
@Override
protected IStatus run(IProgressMonitor arg0) {
flush();
return Status.OK_STATUS;
}
};
}
job.schedule(200);
}
void flush() {
job = null;
if (stdout != null) {
stdout.flush();
stderr.flush();
}
}
@Override
public IStreamMonitor getErrorStreamMonitor() {
return stderr;
}
@Override
public IStreamMonitor getOutputStreamMonitor() {
return stdout;
}
@Override
public void write(String input) throws IOException {
try {
session.stdin(input);
} catch (Exception e) {
// ignore
}
}
@Override
public void closeInputStream() throws IOException {
// ignore
}
public void close() {
stdout = null;
stderr = null;
}
}