001    package org.crsh.shell.impl.command;
002    
003    import org.crsh.command.ScriptException;
004    import org.crsh.console.KeyHandler;
005    import org.crsh.shell.ErrorType;
006    import org.crsh.shell.ShellProcessContext;
007    import org.crsh.shell.ShellResponse;
008    import org.crsh.shell.impl.command.spi.CommandInvoker;
009    import org.crsh.util.Utils;
010    
011    import java.lang.reflect.UndeclaredThrowableException;
012    
013    /**
014    * @author Julien Viet
015    */
016    class 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    }