001    package org.crsh.shell.impl.command;
002    
003    import org.crsh.keyboard.KeyHandler;
004    import org.crsh.shell.ErrorKind;
005    import org.crsh.shell.ShellProcessContext;
006    import org.crsh.shell.ShellResponse;
007    import org.crsh.shell.impl.command.spi.CommandException;
008    import org.crsh.shell.impl.command.spi.CommandInvoker;
009    import org.crsh.util.Utils;
010    
011    /**
012    * @author Julien Viet
013    */
014    class 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    }