tmf: Bug 460842: Introduce tmf remote plug-ins and feature
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.remote.core / src / org / eclipse / tracecompass / tmf / remote / core / shell / CommandShell.java
1 /**********************************************************************
2 * Copyright (c) 2012, 2015 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Patrick Tasse - Initial API and implementation
11 * Bernd Hufmann - Updated using Executor Framework
12 * Markus Schorn - Bug 448058: Use org.eclipse.remote in favor of RSE
13 * Bernd Hufmann - Update to org.eclipse.remote API 2.0
14 **********************************************************************/
15 package org.eclipse.tracecompass.tmf.remote.core.shell;
16
17 import java.io.IOException;
18 import java.util.List;
19 import java.util.concurrent.Callable;
20 import java.util.concurrent.ExecutorService;
21 import java.util.concurrent.Executors;
22 import java.util.concurrent.FutureTask;
23 import java.util.concurrent.TimeUnit;
24 import java.util.concurrent.TimeoutException;
25
26 import org.eclipse.core.commands.ExecutionException;
27 import org.eclipse.core.runtime.IProgressMonitor;
28 import org.eclipse.core.runtime.OperationCanceledException;
29 import org.eclipse.remote.core.IRemoteConnection;
30 import org.eclipse.remote.core.IRemoteProcess;
31 import org.eclipse.remote.core.IRemoteProcessService;
32 import org.eclipse.tracecompass.internal.tmf.remote.core.messages.Messages;
33 import org.eclipse.tracecompass.internal.tmf.remote.core.preferences.TmfRemotePreferences;
34
35 /**
36 * <p>
37 * Implementation of remote command execution using IRemoteConnection.
38 * </p>
39 *
40 * @author Patrick Tasse
41 * @author Bernd Hufmann
42 */
43 public class CommandShell implements ICommandShell {
44
45 // ------------------------------------------------------------------------
46 // Attributes
47 // ------------------------------------------------------------------------
48 private IRemoteConnection fConnection = null;
49 private final ExecutorService fExecutor = Executors.newFixedThreadPool(1);
50
51 // ------------------------------------------------------------------------
52 // Constructors
53 // ------------------------------------------------------------------------
54
55 /**
56 * Create a new command shell
57 *
58 * @param connection the remote connection for this shell
59 */
60 public CommandShell(IRemoteConnection connection) {
61 fConnection = connection;
62 }
63
64 // ------------------------------------------------------------------------
65 // Operations
66 // ------------------------------------------------------------------------
67
68 @Override
69 public void connect() throws ExecutionException {
70 }
71
72 @Override
73 public void disconnect() {
74 fExecutor.shutdown();
75 }
76
77 @Override
78 public ICommandResult executeCommand(final List<String> command, final IProgressMonitor monitor) throws ExecutionException {
79 if (fConnection.isOpen()) {
80 FutureTask<CommandResult> future = new FutureTask<>(new Callable<CommandResult>() {
81 @Override
82 public CommandResult call() throws IOException, InterruptedException {
83 if (monitor == null || !monitor.isCanceled()) {
84 IRemoteProcess process = fConnection.getService(IRemoteProcessService.class).getProcessBuilder(command).start();
85 InputReader stdout = new InputReader(process.getInputStream());
86 InputReader stderr = new InputReader(process.getErrorStream());
87
88 try {
89 stdout.waitFor(monitor);
90 stderr.waitFor(monitor);
91 if (monitor == null || !monitor.isCanceled()) {
92 return createResult(process.waitFor(), stdout.toString(), stderr.toString());
93 }
94 } catch (OperationCanceledException e) {
95 } catch (InterruptedException e) {
96 return new CommandResult(1, new String[0], new String[] {e.getMessage()});
97 } finally {
98 stdout.stop();
99 stderr.stop();
100 process.destroy();
101 }
102 }
103 return new CommandResult(1, new String[0], new String[] {"cancelled"}); //$NON-NLS-1$
104 }
105 });
106
107 fExecutor.execute(future);
108
109 try {
110 return future.get(TmfRemotePreferences.getCommandTimeout(), TimeUnit.SECONDS);
111 } catch (java.util.concurrent.ExecutionException ex) {
112 throw new ExecutionException(Messages.TraceControl_ExecutionFailure, ex);
113 } catch (InterruptedException ex) {
114 throw new ExecutionException(Messages.TraceControl_ExecutionCancelled, ex);
115 } catch (TimeoutException ex) {
116 throw new ExecutionException(Messages.TraceControl_ExecutionTimeout, ex);
117 } finally {
118 future.cancel(true);
119 }
120 }
121 throw new ExecutionException(Messages.TraceControl_ShellNotConnected, null);
122 }
123
124 // ------------------------------------------------------------------------
125 // Helper methods
126 // ------------------------------------------------------------------------
127
128 private static CommandResult createResult(int origResult, String origStdout, String origStderr) {
129 final int result;
130 final String stdout, stderr;
131 result = origResult;
132 stdout = origStdout;
133 stderr = origStderr;
134 String[] output = splitLines(stdout);
135 String[] error = splitLines(stderr);
136 return new CommandResult(result, output, error);
137 }
138
139 private static String[] splitLines(String output) {
140 if (output == null) {
141 return null;
142 }
143 return output.split("\\r?\\n"); //$NON-NLS-1$
144 }
145
146 }
This page took 0.034937 seconds and 5 git commands to generate.