View Javadoc

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