1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.actions.iface.tools.support;
14
15 import java.io.InputStream;
16
17 import com.eviware.soapui.model.ModelItem;
18 import com.eviware.soapui.support.UISupport;
19
20 /***
21 * ToolRunner for running command-line processes
22 *
23 * @author ole.matzura
24 */
25
26 public class ProcessToolRunner implements ToolRunner
27 {
28
29 private final ProcessBuilder[] builders;
30 private boolean running;
31 private Process process;
32 private RunnerContext context;
33 private final String name;
34 private final ModelItem modelItem;
35 private boolean canCancel = true;
36 private boolean showLog = true;
37 private ArgumentBuilder args;
38
39 public ProcessToolRunner( ProcessBuilder builder, String name, ModelItem modelItem, ArgumentBuilder args )
40 {
41 this( new ProcessBuilder[] { builder }, name, modelItem, args );
42 }
43
44 public ProcessToolRunner( ProcessBuilder[] builders, String name, ModelItem modelItem, ArgumentBuilder args )
45 {
46 this.builders = builders;
47 this.name = name;
48 this.modelItem = modelItem;
49 this.args = args;
50 }
51
52 public ProcessToolRunner( ProcessBuilder[] processBuilders, String s, ModelItem modelItem )
53 {
54 this( processBuilders, s, modelItem, null );
55 }
56
57 public ProcessToolRunner( ProcessBuilder builder, String s, ModelItem modelItem )
58 {
59 this( builder, s, modelItem, null );
60 }
61
62 public ProcessBuilder[] getBuilders()
63 {
64 return builders;
65 }
66
67 public Process getProcess()
68 {
69 return process;
70 }
71
72 public boolean isRunning()
73 {
74 return running;
75 }
76
77 public void cancel()
78 {
79 getProcess().destroy();
80 try
81 {
82 getProcess().waitFor();
83 }
84 catch( InterruptedException e )
85 {
86 e.printStackTrace();
87 }
88
89 running = false;
90 }
91
92 public void run()
93 {
94 try
95 {
96 int exitCode = -1;
97
98 beforeRun( context );
99
100 for( int c = 0; c < builders.length; c++ )
101 {
102 beforeProcess( builders[c], context );
103
104 logRunInfo( builders[c] );
105 process = builders[c].start();
106 if( c == 0 )
107 context.setStatus( RunnerContext.RunnerStatus.RUNNING );
108
109 running = true;
110
111 InputStream in = process.getInputStream();
112 InputStream err = process.getErrorStream();
113
114 exitCode = -1;
115
116 while( exitCode == -1 && running )
117 {
118 try
119 {
120 exitCode = process.exitValue();
121 break;
122 }
123 catch( IllegalThreadStateException e )
124 {
125 }
126 finally
127 {
128 while( in.available() > 0 )
129 {
130 byte[] data = new byte[in.available()];
131 in.read( data );
132
133 context.log( new String( data ) );
134 }
135
136 while( err.available() > 0 )
137 {
138 byte[] data = new byte[err.available()];
139 err.read( data );
140
141 context.logError( new String( data ) );
142 }
143 }
144
145 Thread.sleep( 25 );
146 }
147
148 afterProcess( process, context );
149 }
150
151 context.setStatus( RunnerContext.RunnerStatus.FINISHED );
152
153 if( running )
154 {
155 running = false;
156 afterRun( exitCode, context );
157 }
158 }
159 catch( Exception ex )
160 {
161 context.setStatus( RunnerContext.RunnerStatus.ERROR );
162 UISupport.showErrorMessage( ex );
163 running = false;
164 afterRun( -1, context );
165 }
166 finally
167 {
168 context.disposeContext();
169 }
170 }
171
172 protected void beforeRun( RunnerContext context )
173 {
174 }
175
176 protected void beforeProcess( ProcessBuilder processBuilder, RunnerContext context )
177 {
178 }
179
180 protected void afterProcess( Process process2, RunnerContext context )
181 {
182 }
183
184 protected void afterRun( int exitCode, RunnerContext context )
185 {
186 if( exitCode == 0 )
187 UISupport.showInfoMessage( "Execution finished successfully", context.getTitle() );
188 else
189 UISupport.showInfoMessage( "Execution finished with errorCode " + exitCode
190 + ",\r\nplease check log for error messages", context.getTitle() );
191 }
192
193 private void logRunInfo( ProcessBuilder builder )
194 {
195 context.log( "directory: " + builder.directory().getAbsolutePath() + "\r\n" );
196 context.log( "command: " + ( args == null ? builder.command() : args ) + "\r\n" );
197 }
198
199 public void setContext( RunnerContext context )
200 {
201 this.context = context;
202 }
203
204 public ModelItem getModelItem()
205 {
206 return modelItem;
207 }
208
209 public String getName()
210 {
211 return name;
212 }
213
214 public boolean canCancel()
215 {
216 return canCancel;
217 }
218
219 public boolean showLog()
220 {
221 return showLog;
222 }
223
224 public void setCanCancel( boolean canCancel )
225 {
226 this.canCancel = canCancel;
227 }
228
229 public void setShowLog( boolean showLog )
230 {
231 this.showLog = showLog;
232 }
233
234 public String getDescription()
235 {
236 return null;
237 }
238 }