View Javadoc

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