View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 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[] 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 }