package aQute.remote.plugin; import java.io.InputStream; import java.io.InputStreamReader; import aQute.bnd.util.dto.DTO; import aQute.remote.api.Agent; import aQute.remote.api.Event; import aQute.remote.api.Supervisor; import aQute.remote.util.AgentSupervisor; /** * This is the supervisor on the bnd launcher side. It provides the SHA * repository for the agent and handles the redirection. It also handles the * events. */ public class LauncherSupervisor extends AgentSupervisor<Supervisor,Agent> implements Supervisor { private Appendable stdout; private Appendable stderr; private Thread stdin; private int shell = -100; // always invalid so we update it static class Info extends DTO { public String sha; public long lastModified; } @Override public void event(Event e) throws Exception { switch (e.type) { case exit : exit(e.code); break; default : break; } } @Override public boolean stdout(String out) throws Exception { if (stdout != null) { stdout.append(out); return true; } return false; } @Override public boolean stderr(String out) throws Exception { if (stderr != null) { stderr.append(out); return true; } return false; } public void setStdout(Appendable out) throws Exception { this.stdout = out; } public void setStderr(Appendable err) throws Exception { this.stderr = err; } public void setStdin(final InputStream in) throws Exception { final InputStreamReader isr = new InputStreamReader(in); this.stdin = new Thread("stdin") { @Override public void run() { StringBuilder sb = new StringBuilder(); while (!isInterrupted()) try { if (isr.ready()) { int read = isr.read(); if (read >= 0) { sb.append((char) read); } else return; } else { if (sb.length() == 0) sleep(100); else { getAgent().stdin(sb.toString()); sb.setLength(0); } } } catch (Exception e) { e.printStackTrace(); } } }; this.stdin.start(); } public void setStreams(Appendable out, Appendable err) throws Exception { setStdout(out); setStderr(err); getAgent().redirect(shell); } public void connect(String host, int port) throws Exception { super.connect(Agent.class, this, host, port); } /** * The shell port to use. * <ul> * <li><0 – Attach to a local Gogo CommandSession * <li>0 – Use the standard console * <li>else – Open a stream to that port * </ul> * * @param shellPort */ public void setShell(int shellPort) { this.shell = shellPort; } public int getExitCode() { return exitCode; } public void abort() throws Exception { if (isOpen()) { getAgent().abort(); } } public void redirect(int shell) throws Exception { if (this.shell != shell && isOpen()) { getAgent().redirect(shell); this.shell = shell; } } }