001package org.crsh.shell.impl.command;
002
003import org.crsh.keyboard.KeyHandler;
004import org.crsh.shell.ErrorKind;
005import org.crsh.shell.ShellProcessContext;
006import org.crsh.shell.ShellResponse;
007import org.crsh.shell.impl.command.spi.CommandException;
008import org.crsh.shell.impl.command.spi.CommandInvoker;
009import org.crsh.util.Utils;
010
011/**
012* @author Julien Viet
013*/
014class CRaSHCommandProcess extends CRaSHProcess {
015
016  /** . */
017  private final CRaSHSession session;
018
019  /** . */
020  private final CommandInvoker<Void, ?> command;
021
022  public CRaSHCommandProcess(CRaSHSession session, String request, CommandInvoker<Void, ?> command) {
023    super(session, request);
024
025    //
026    this.session = session;
027    this.command = command;
028  }
029
030  @Override
031  public KeyHandler getKeyHandler() {
032    return command.getKeyHandler();
033  }
034
035  @Override
036  ShellResponse doInvoke(final ShellProcessContext context) throws InterruptedException {
037    CRaSHProcessContext invocationContext = new CRaSHProcessContext(session, context);
038    try {
039      command.invoke(invocationContext);
040      return ShellResponse.ok();
041    }
042    catch (CommandException e) {
043      return build(e);
044    } catch (Throwable t) {
045      return build(t);
046    } finally {
047      Utils.close(invocationContext);
048    }
049  }
050
051  private ShellResponse.Error build(Throwable throwable) {
052    ErrorKind errorType;
053    if (throwable instanceof CommandException) {
054      CommandException ce = (CommandException)throwable;
055      errorType = ce.getErrorKind();
056      Throwable cause = throwable.getCause();
057      if (cause != null) {
058        throwable = cause;
059      }
060    } else {
061      errorType = ErrorKind.INTERNAL;
062    }
063    String result;
064    String msg = throwable.getMessage();
065    if (throwable instanceof CommandException) {
066      if (msg == null) {
067        result = request + ": failed";
068      } else {
069        result = request + ": " + msg;
070      }
071      return ShellResponse.error(errorType, result, throwable);
072    } else {
073      if (msg == null) {
074        msg = throwable.getClass().getSimpleName();
075      }
076      if (throwable instanceof RuntimeException) {
077        result = request + ": exception: " + msg;
078      } else if (throwable instanceof Exception) {
079        result = request + ": exception: " + msg;
080      } else if (throwable instanceof Error) {
081        result = request + ": error: " + msg;
082      } else {
083        result = request + ": unexpected throwable: " + msg;
084      }
085      return ShellResponse.error(errorType, result, throwable);
086    }
087  }
088}