/** * */ package vnet.sms.common.shell.clamshellsshsrv.internal; import static org.apache.commons.lang.Validate.notNull; import java.io.FilterOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.sshd.server.Command; import org.apache.sshd.server.Environment; import org.apache.sshd.server.ExitCallback; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import vnet.sms.common.shell.clamshellspring.ClamshellLauncher; /** * @author obergner * */ public class ClamshellLauncherCommand implements Command { static final class Factory implements org.apache.sshd.common.Factory<Command> { private final ClamshellLauncher.Factory clamshellLauncherFactory; Factory(final ClamshellLauncher.Factory clamshellLauncherFactory) { this.clamshellLauncherFactory = clamshellLauncherFactory; } @Override public Command create() { return new ClamshellLauncherCommand( this.clamshellLauncherFactory.newLauncher()); } } private final Logger log = LoggerFactory.getLogger(getClass()); private final ClamshellLauncher clamshellLauncher; private InputStream input; private OutputStream output; private ExitCallback exitCallback; /** * @param clamshellLauncher */ ClamshellLauncherCommand(final ClamshellLauncher clamshellLauncher) { notNull(clamshellLauncher, "Argument 'clamshellLauncher' must not be null"); this.clamshellLauncher = clamshellLauncher; } /** * @see org.apache.sshd.server.Command#setInputStream(java.io.InputStream) */ @Override public void setInputStream(final InputStream in) { this.input = in; } /** * @see org.apache.sshd.server.Command#setOutputStream(java.io.OutputStream) */ @Override public void setOutputStream(final OutputStream out) { this.output = new LfToCrLfFilterOutputStream(out); } /** * @see org.apache.sshd.server.Command#setErrorStream(java.io.OutputStream) */ @Override public void setErrorStream(final OutputStream err) { // Ignored for now } /** * @see org.apache.sshd.server.Command#setExitCallback(org.apache.sshd.server.ExitCallback) */ @Override public void setExitCallback(final ExitCallback callback) { this.exitCallback = callback; } /** * @see org.apache.sshd.server.Command#start(org.apache.sshd.server.Environment) */ @Override public void start(final Environment env) throws IOException { this.log.info("Launching new Clamshell ..."); this.clamshellLauncher.launch(this.input, this.output); this.log.info("New Clamshell launched"); } /** * @see org.apache.sshd.server.Command#destroy() */ @Override public void destroy() { this.exitCallback.onExit(0); this.log.info("Clamshell has been terminated"); } private final class LfToCrLfFilterOutputStream extends FilterOutputStream { private boolean lastWasCr; public LfToCrLfFilterOutputStream(final OutputStream out) { super(out); } @Override public void write(final int b) throws IOException { if (!this.lastWasCr && (b == '\n')) { this.out.write('\r'); this.out.write('\n'); } else { this.out.write(b); } this.lastWasCr = b == '\r'; } } }