View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2008 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
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 [] builders, String name, ModelItem modelItem)
53  	{
54  		this( builders, name, modelItem, null);
55  	}
56  
57  	public ProcessToolRunner(ProcessBuilder builder, String name, ModelItem modelItem) {
58  		this( new ProcessBuilder[] {builder}, name, modelItem, null);
59  	}
60  
61  	public ProcessBuilder [] getBuilders()
62  	{
63  		return builders;
64  	}
65  	
66  	public Process getProcess()
67  	{
68  		return process;
69  	}
70  
71  	public boolean isRunning()
72  	{
73  		return running;
74  	}
75  	
76  	public void cancel()
77  	{
78  		getProcess().destroy();
79  		try
80  		{
81  			getProcess().waitFor();
82  		}
83  		catch( InterruptedException e )
84  		{
85  			e.printStackTrace();
86  		}
87  		
88  		running = false;
89  	}
90  
91  	public void run()
92  	{
93  		try
94  		{
95  			int exitCode = -1;
96  			
97  			beforeRun( context );
98  			
99  			for( int c = 0; c < builders.length; c++ )
100 			{
101 				beforeProcess( process, context );
102 
103 				logRunInfo( builders[c] );
104 				process = builders[c].start();
105 				if( c == 0 )
106 					context.setStatus( RunnerContext.RunnerStatus.RUNNING );
107 				
108 				running = true;
109 				
110 				InputStream in = process.getInputStream();
111 				InputStream err = process.getErrorStream();
112 				
113 				exitCode = -1;
114 				
115 				while( exitCode == -1 && running )
116 				{
117 					try 
118 					{
119 						exitCode = process.exitValue();
120 						break;
121 					} 
122 					catch (IllegalThreadStateException e) 
123 					{
124 					}
125 					finally
126 					{
127 						while( in.available() > 0  )
128 						{
129 							byte [] data = new byte[in.available()];
130 							in.read( data );
131 	
132 							context.log( new String( data ) );
133 						}
134 						
135 						while( err.available() > 0  )
136 						{
137 							byte [] data = new byte[err.available()];
138 							err.read( data );
139 	
140 							context.logError( new String( data ) );
141 						}
142 					}
143 					
144 					Thread.sleep( 25 );
145 				}
146 				
147 				afterProcess( process, context );
148 			}
149 			
150          context.setStatus( RunnerContext.RunnerStatus.FINISHED );
151          
152          if( running )
153 			{
154 				running = false;
155 				afterRun( exitCode, context );
156 			}
157 		}
158 		catch (Exception ex)
159 		{
160 			context.setStatus( RunnerContext.RunnerStatus.ERROR );
161 			UISupport.showErrorMessage( ex );
162 			running = false;
163 			afterRun( -1, context );
164 		}
165       finally
166       {
167          context.disposeContext();
168       }
169 	}
170 
171 	protected void beforeRun(RunnerContext context)
172 	{
173 	}
174 
175 	protected void beforeProcess(Process process2, RunnerContext context)
176 	{
177 	}
178 
179 	protected void afterProcess(Process process2, RunnerContext context)
180 	{
181 	}
182 
183 	protected void afterRun(int exitCode, RunnerContext context)
184 	{
185 		if (exitCode == 0)
186 			UISupport.showInfoMessage("Execution finished successfully", context.getTitle() );
187 		else
188 			UISupport.showInfoMessage("Execution finished with errorCode " + exitCode
189 					+ ",\r\nplease check log for error messages", context.getTitle());
190 	}
191 
192 	private void logRunInfo(ProcessBuilder builder)
193 	{
194 		context.log( "directory: " + builder.directory().getAbsolutePath() + "\r\n" );
195 		context.log( "command: " + args + "\r\n" );
196 	}
197 
198 	public void setContext(RunnerContext context)
199 	{
200 		this.context = context;
201 	}
202 
203 	public ModelItem getModelItem()
204 	{
205 		return modelItem;
206 	}
207 
208 	public String getName()
209 	{
210 		return name;
211 	}
212 
213 	public boolean canCancel()
214 	{
215 		return canCancel;
216 	}
217 
218 	public boolean showLog()
219 	{
220 		return showLog;
221 	}
222 
223 	public void setCanCancel(boolean canCancel )
224 	{
225 		this.canCancel = canCancel;
226 	}
227 
228 	public void setShowLog(boolean showLog)
229 	{
230 		this.showLog = showLog;
231 	}
232 
233 	public String getDescription()
234 	{
235 		return null;
236 	}
237 }