~ubuntu-branches/ubuntu/trusty/eclipse-linuxtools/trusty

« back to all changes in this revision

Viewing changes to systemtap/org.eclipse.linuxtools.systemtap.ui.structures/src/org/eclipse/linuxtools/systemtap/ui/structures/runnable/Command.java

  • Committer: Package Import Robot
  • Author(s): Jakub Adam
  • Date: 2012-06-29 12:07:30 UTC
  • Revision ID: package-import@ubuntu.com-20120629120730-bfri1xys1i71dpn6
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************************************************
 
2
 * Copyright (c) 2006 IBM Corporation.
 
3
 * All rights reserved. This program and the accompanying materials
 
4
 * are made available under the terms of the Eclipse Public License v1.0
 
5
 * which accompanies this distribution, and is available at
 
6
 * http://www.eclipse.org/legal/epl-v10.html
 
7
 *
 
8
 * Contributors:
 
9
 *     IBM Corporation - Jeff Briggs, Henry Hughes, Ryan Morse
 
10
 *******************************************************************************/
 
11
 
 
12
package org.eclipse.linuxtools.systemtap.ui.structures.runnable;
 
13
 
 
14
import java.io.IOException;
 
15
import java.io.PrintWriter;
 
16
import java.util.ArrayList;
 
17
 
 
18
import org.eclipse.linuxtools.internal.systemtap.ui.structures.Localization;
 
19
import org.eclipse.linuxtools.systemtap.ui.structures.IPasswordPrompt;
 
20
import org.eclipse.linuxtools.systemtap.ui.structures.listeners.IGobblerListener;
 
21
 
 
22
 
 
23
 
 
24
/**
 
25
 * A class to spawn a separate thread to run a <code>Process</code>.
 
26
 * @author Ryan Morse
 
27
 */
 
28
public class Command implements Runnable {
 
29
        /*
 
30
         * Bug in the exec command prevents using a single string.  Forced
 
31
         * to use a workaround in order to run commands with spaces.
 
32
         * 
 
33
         * http://bugs.sun.com/bugdatabase/view_bug.do;:WuuT?bug_id=4365120
 
34
         * http://bugs.sun.com/bugdatabase/view_bug.do;:WuuT?bug_id=4109888
 
35
         */
 
36
 
 
37
        /**
 
38
         * Spawns the new thread that this class will run in.  From the Runnable
 
39
         * interface spawning the new thread automatically calls the run() method.
 
40
         * This must be called by the implementing class in order to start the
 
41
         * StreamGobbler.
 
42
         * @param cmd The entire command to run
 
43
         * @param envVars List of all environment variables to use
 
44
         * @param prompt The password promt for allowing the user to enter their password.
 
45
         * @param monitorDelay The time in MS to wait between checking whether the <code>Process</code> has finished.
 
46
         */
 
47
        public Command(String[] cmd, String[] envVars, IPasswordPrompt prompt, int monitorDelay) {
 
48
                this.cmd = cmd;
 
49
                this.envVars = envVars;
 
50
                this.prompt = prompt;
 
51
                this.monitorDelay = monitorDelay;
 
52
        }
 
53
        
 
54
        /**
 
55
         * Spawns the new thread that this class will run in.  From the Runnable
 
56
         * interface spawning the new thread automatically calls the run() method.
 
57
         * This must be called by the implementing class in order to start the
 
58
         * StreamGobbler.
 
59
         * @param cmd The entire command to run
 
60
         * @param envVars List of all environment variables to use
 
61
         * @param prompt The password promt for allowing the user to enter their password.
 
62
         */
 
63
        public Command(String[] cmd, String[] envVars, IPasswordPrompt prompt) {
 
64
                this(cmd, envVars, prompt, 100);
 
65
        }
 
66
        
 
67
        /**
 
68
         * Starts the <code>Thread</code> that the new <code>Process</code> will run in.
 
69
         * This must be called in order to get the process to start running.
 
70
         */
 
71
        public void start() {
 
72
                if(init()) {
 
73
                        Thread t = new Thread(this, cmd[0]);
 
74
                        t.start();
 
75
                } else {
 
76
                        stop();
 
77
                        returnVal = Integer.MIN_VALUE;
 
78
                }
 
79
        }
 
80
        
 
81
        /**
 
82
         * Starts up the process that will execute the provided command and registers
 
83
         * the <code>StreamGobblers</code> with their respective streams.
 
84
         */
 
85
        protected boolean init() {
 
86
                try {
 
87
                        process = Runtime.getRuntime().exec(cmd, envVars);
 
88
        
 
89
                        errorGobbler = new StreamGobbler(process.getErrorStream());            
 
90
                        inputGobbler = new StreamGobbler(process.getInputStream());
 
91
                        
 
92
                        int i;
 
93
                        for(i=0; i<inputListeners.size(); i++)
 
94
                                inputGobbler.addDataListener(inputListeners.get(i));
 
95
                        for(i=0; i<errorListeners.size(); i++)
 
96
                                errorGobbler.addDataListener(errorListeners.get(i));
 
97
                        return true;
 
98
                } catch(IOException ioe) {}
 
99
                return false;
 
100
        }
 
101
        
 
102
        /**
 
103
         * This method handles checking the status of the running <code>Process</code>. It
 
104
         * is called when the new Thread is created, and thus should never be called by
 
105
         * any implementing program. To run call the <code>start</code> method.
 
106
         */
 
107
        public void run() {
 
108
                errorGobbler.start();
 
109
                inputGobbler.start();
 
110
                
 
111
                try {
 
112
                        while(!stopped) {
 
113
                                try {
 
114
                                        if(null != errorGobbler && errorGobbler.readLine().endsWith(Localization.getString("Command.Password"))) {
 
115
                                                PrintWriter writer = new PrintWriter(process.getOutputStream(), true);
 
116
                                                writer.println(prompt.getPassword());
 
117
                                        }
 
118
                                        
 
119
                                        returnVal = process.exitValue();        //Dont care what the value is, just whether it throws an exception
 
120
                                        stop(); //Above line will throw an exception if not finished
 
121
                                } catch(IllegalThreadStateException itse) {}
 
122
                                
 
123
                                if(0 < monitorDelay)
 
124
                                        Thread.sleep(monitorDelay);
 
125
                        }
 
126
                } catch(InterruptedException ie) {
 
127
                } catch(NullPointerException npe) {}
 
128
        }
 
129
        
 
130
        /**
 
131
         * Stops the process from running and stops the <code>StreamGobblers</code> from monitering
 
132
         * the dead process.
 
133
         */
 
134
        public synchronized void stop() {
 
135
                if(!stopped) {
 
136
                        stopped = true;
 
137
                        if(null != errorGobbler)
 
138
                                errorGobbler.stop();
 
139
                        if(null != inputGobbler)
 
140
                                inputGobbler.stop();
 
141
                        if(null != process)
 
142
                                process.destroy();
 
143
                }
 
144
        }
 
145
        
 
146
        /**
 
147
         * Method to check whether or not the process in running.
 
148
         * @return The execution status.
 
149
         */
 
150
        public boolean isRunning() {
 
151
                return !stopped;
 
152
        }
 
153
        
 
154
        /**
 
155
         * Method to check if this class has already been disposed.
 
156
         * @return Status of the class.
 
157
         */
 
158
        public boolean isDisposed() {
 
159
                return disposed;
 
160
        }
 
161
        
 
162
        /**
 
163
         * The return value of the process. 
 
164
         * 2^231-1 if the process is still running.
 
165
         * -2^231 if there was an error creating the process
 
166
         * @return The return value generated from running the provided command.
 
167
         */
 
168
        public int getReturnValue() {
 
169
                return returnVal;
 
170
        }
 
171
 
 
172
        /**
 
173
         * Registers the provided <code>IGobblerListener</code> with the InputStream
 
174
         * @param listener A listener to monitor the InputStream from the Process
 
175
         */
 
176
        public void addInputStreamListener(IGobblerListener listener) {
 
177
                if(null != inputGobbler)
 
178
                        inputGobbler.addDataListener(listener);
 
179
                else
 
180
                        inputListeners.add(listener);
 
181
        }
 
182
        
 
183
        /**
 
184
         * Registers the provided <code>IGobblerListener</code> with the ErrorStream
 
185
         * @param listener A listener to monitor the ErrorStream from the Process
 
186
         */
 
187
        public void addErrorStreamListener(IGobblerListener listener) {
 
188
                if(null != errorGobbler)
 
189
                        errorGobbler.addDataListener(listener);
 
190
                else
 
191
                        errorListeners.add(listener);
 
192
        }
 
193
        
 
194
        /**
 
195
         * Returns the list of everything that is listening the the InputStream
 
196
         * @return List of all <code>IGobblerListeners</code> that are monitoring the stream.
 
197
         */
 
198
        
 
199
        public ArrayList<IGobblerListener> getInputStreamListeners() {
 
200
                if(null != inputGobbler)
 
201
                        return inputListeners;
 
202
                else {
 
203
                        ArrayList<IGobblerListener> dataListeners = inputGobbler.getDataListeners();
 
204
                        return dataListeners;
 
205
                }
 
206
        }
 
207
        
 
208
        /**
 
209
         * Returns the list of everything that is listening the the ErrorStream
 
210
         * @return List of all <code>IGobblerListeners</code> that are monitoring the stream.
 
211
         */
 
212
        
 
213
        public ArrayList<IGobblerListener> getErrorStreamListeners() {
 
214
                if(null != errorGobbler)
 
215
                        return errorListeners;
 
216
                else
 
217
                        return errorGobbler.getDataListeners();
 
218
        }
 
219
        
 
220
        /**
 
221
         * Removes the provided listener from those monitoring the InputStream.
 
222
         * @param listener An </code>IGobblerListener</code> that is monitoring the stream.
 
223
         */
 
224
        public void removeInputStreamListener(IGobblerListener listener) {
 
225
                if(null != inputGobbler)
 
226
                        inputGobbler.removeDataListener(listener);
 
227
                else
 
228
                        inputListeners.remove(listener);
 
229
        }
 
230
        
 
231
        /**
 
232
         * Removes the provided listener from those monitoring the ErrorStream.
 
233
         * @param listener An </code>IGobblerListener</code> that is monitoring the stream.
 
234
         */
 
235
        public void removeErrorStreamListener(IGobblerListener listener) {
 
236
                if(null != errorGobbler)
 
237
                        errorGobbler.removeDataListener(listener);
 
238
                else
 
239
                        errorListeners.remove(listener);
 
240
        }
 
241
        
 
242
        /**
 
243
         * Disposes of all internal components of this class. Nothing in the class should be
 
244
         * referenced after this is called.
 
245
         */
 
246
        public void dispose() {
 
247
                if(!disposed) {
 
248
                        stop();
 
249
                        disposed = true;
 
250
                        inputListeners = null;
 
251
                        errorListeners = null;
 
252
 
 
253
                        if(null != inputGobbler)
 
254
                                inputGobbler.dispose();
 
255
                        inputGobbler = null;
 
256
                        
 
257
                        if(null != errorGobbler)
 
258
                                errorGobbler.dispose();
 
259
                        errorGobbler = null;
 
260
                }
 
261
        }
 
262
        
 
263
        private boolean stopped = false;
 
264
        private boolean disposed = false;
 
265
        private StreamGobbler inputGobbler = null;
 
266
        private StreamGobbler errorGobbler = null;
 
267
        private ArrayList<IGobblerListener> inputListeners = new ArrayList<IGobblerListener>(); //Only used to allow adding listeners before creating the StreamGobbler
 
268
        private ArrayList<IGobblerListener> errorListeners = new ArrayList<IGobblerListener>(); //Only used to allow adding listeners before creating the StreamGobbler
 
269
        private int returnVal = Integer.MAX_VALUE;
 
270
 
 
271
        private String[] cmd;
 
272
        private String[] envVars;
 
273
        private IPasswordPrompt prompt;
 
274
        private int monitorDelay;
 
275
        protected Process process;
 
276
        
 
277
        public static final int ERROR_STREAM = 0;
 
278
        public static final int INPUT_STREAM = 1;
 
279
}
 
 
b'\\ No newline at end of file'