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