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.tools;
14  
15  import java.io.File;
16  import java.io.OutputStreamWriter;
17  import java.util.ArrayList;
18  import java.util.List;
19  
20  import org.apache.commons.cli.CommandLine;
21  import org.apache.commons.cli.CommandLineParser;
22  import org.apache.commons.cli.HelpFormatter;
23  import org.apache.commons.cli.Options;
24  import org.apache.commons.cli.PosixParser;
25  import org.apache.log4j.ConsoleAppender;
26  import org.apache.log4j.Logger;
27  import org.apache.log4j.PatternLayout;
28  
29  import com.eviware.soapui.DefaultSoapUICore;
30  import com.eviware.soapui.SoapUI;
31  import com.eviware.soapui.SoapUICore;
32  import com.eviware.soapui.SoapUIExtensionClassLoader;
33  import com.eviware.soapui.SoapUIExtensionClassLoader.SoapUIClassLoaderState;
34  import com.eviware.soapui.StandaloneSoapUICore;
35  import com.eviware.soapui.impl.wsdl.WsdlProject;
36  import com.eviware.soapui.impl.wsdl.support.PathUtils;
37  import com.eviware.soapui.model.ModelItem;
38  import com.eviware.soapui.model.project.Project;
39  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
40  import com.eviware.soapui.support.StringUtils;
41  import com.eviware.soapui.support.UISupport;
42  
43  public abstract class AbstractSoapUIRunner implements CmdLineRunner
44  {
45  	private boolean groovyLogInitialized;
46  	private String projectFile;
47  	protected final Logger log = Logger.getLogger( getClass() );
48  	private String settingsFile;
49  	private String soapUISettingsPassword;
50  
51  	private boolean enableUI;
52  	private String outputFolder;
53  	private String[] projectProperties;
54  
55  	public AbstractSoapUIRunner( String title )
56  	{
57  		if( title != null )
58  			System.out.println( title );
59  
60  		SoapUI.setCmdLineRunner( this );
61  	}
62  
63  	protected void initGroovyLog()
64  	{
65  		if( !groovyLogInitialized )
66  		{
67  			Logger logger = Logger.getLogger( "groovy.log" );
68  
69  			ConsoleAppender appender = new ConsoleAppender();
70  			appender.setWriter( new OutputStreamWriter( System.out ) );
71  			appender.setLayout( new PatternLayout( "%d{ABSOLUTE} %-5p [%c{1}] %m%n" ) );
72  			logger.addAppender( appender );
73  
74  			groovyLogInitialized = true;
75  		}
76  	}
77  
78  	public int runFromCommandLine( String[] args )
79  	{
80  		try
81  		{
82  			if( initFromCommandLine( args, true ) )
83  			{
84  				if( run() )
85  				{
86  					return 0;
87  				}
88  			}
89  		}
90  		catch( Throwable e )
91  		{
92  			log.error( e );
93  			SoapUI.logError( e );
94  		}
95  
96  		return -1;
97  	}
98  
99  	public boolean initFromCommandLine( String[] args, boolean printHelp ) throws Exception
100 	{
101 		SoapUIOptions options = initCommandLineOptions();
102 
103 		CommandLineParser parser = new PosixParser();
104 		CommandLine cmd = parser.parse( options, args );
105 
106 		if( options.requiresProject() )
107 		{
108 			args = cmd.getArgs();
109 
110 			if( args.length != 1 )
111 			{
112 				if( printHelp )
113 				{
114 					HelpFormatter formatter = new HelpFormatter();
115 					formatter.printHelp( options.getRunnerName() + " [options] <soapui-project-file>", options );
116 				}
117 
118 				System.err.println( "Missing soapUI project file.." );
119 				return false;
120 			}
121 
122 			setProjectFile( args[0] );
123 		}
124 
125 		return processCommandLine( cmd );
126 	}
127 
128 	/***
129 	 * Main method to use for running the configured tests. Call after setting
130 	 * properties, etc as desired.
131 	 * 
132 	 * @return true if execution should be blocked
133 	 * @throws Exception
134 	 *            if an error or failure occurs during test execution
135 	 */
136 
137 	public final boolean run() throws Exception
138 	{
139 		if( SoapUI.getSoapUICore() == null )
140 		{
141 			SoapUI.setSoapUICore( createSoapUICore(), true );
142 			SoapUI.initGCTimer();
143 		}
144 
145 		SoapUIClassLoaderState state = SoapUIExtensionClassLoader.ensure();
146 
147 		try
148 		{
149 			return runRunner();
150 		}
151 		finally
152 		{
153 			state.restore();
154 		}
155 	}
156 
157 	protected SoapUICore createSoapUICore()
158 	{
159 		if( enableUI )
160 		{
161 			StandaloneSoapUICore core = new StandaloneSoapUICore( settingsFile );
162 			log.info( "Enabling UI Components" );
163 			core.prepareUI();
164 			UISupport.setMainFrame( null );
165 			return core;
166 		}
167 		else
168 		{
169 			return new DefaultSoapUICore( null, settingsFile, soapUISettingsPassword );
170 		}
171 	}
172 
173 	protected abstract boolean processCommandLine( CommandLine cmd );
174 
175 	protected abstract SoapUIOptions initCommandLineOptions();
176 
177 	protected abstract boolean runRunner() throws Exception;
178 
179 	protected String getCommandLineOptionSubstSpace( CommandLine cmd, String key )
180 	{
181 		return cmd.getOptionValue( key ).replaceAll( "%20", " " );
182 	}
183 
184 	/* (non-Javadoc)
185 	 * @see com.eviware.soapui.tools.CmdLineRunner#getProjectFile()
186 	 */
187 	@Override
188 	public String getProjectFile()
189 	{
190 		return projectFile;
191 	}
192 
193 	/* (non-Javadoc)
194 	 * @see com.eviware.soapui.tools.CmdLineRunner#getSettingsFile()
195 	 */
196 	@Override
197 	public String getSettingsFile()
198 	{
199 		return settingsFile;
200 	}
201 
202 	public void setOutputFolder( String outputFolder )
203 	{
204 		this.outputFolder = outputFolder;
205 	}
206 
207 	/* (non-Javadoc)
208 	 * @see com.eviware.soapui.tools.CmdLineRunner#getOutputFolder()
209 	 */
210 	@Override
211 	public String getOutputFolder()
212 	{
213 		return this.outputFolder;
214 	}
215 
216 	public String getAbsoluteOutputFolder( ModelItem modelItem )
217 	{
218 		String folder = outputFolder;
219 
220 		if( StringUtils.isNullOrEmpty( folder ) )
221 		{
222 			folder = PathUtils.getExpandedResourceRoot( modelItem );
223 		}
224 		else if( PathUtils.isRelativePath( folder ) )
225 		{
226 			folder = PathUtils.resolveResourcePath( folder, modelItem );
227 		}
228 
229 		return folder;
230 	}
231 
232 	public String getModelItemOutputFolder( ModelItem modelItem )
233 	{
234 		List<ModelItem> chain = new ArrayList<ModelItem>();
235 		ModelItem p = modelItem;
236 
237 		while( !( p instanceof Project ) )
238 		{
239 			chain.add( 0, p );
240 			p = p.getParent();
241 		}
242 
243 		File dir = new File( getAbsoluteOutputFolder( modelItem ) );
244 		dir.mkdir();
245 
246 		for( ModelItem item : chain )
247 		{
248 			dir = new File( dir, StringUtils.createFileName( item.getName(), '-' ) );
249 			dir.mkdir();
250 		}
251 
252 		return dir.getAbsolutePath();
253 	}
254 
255 	protected void ensureOutputFolder( ModelItem modelItem )
256 	{
257 		ensureFolder( getAbsoluteOutputFolder( modelItem ) );
258 	}
259 
260 	public void ensureFolder( String path )
261 	{
262 		if( path == null )
263 			return;
264 
265 		File folder = new File( path );
266 		if( !folder.exists() || !folder.isDirectory() )
267 			folder.mkdirs();
268 	}
269 
270 	/***
271 	 * Sets the soapUI project file containing the tests to run
272 	 * 
273 	 * @param projectFile
274 	 *           the soapUI project file containing the tests to run
275 	 */
276 
277 	public void setProjectFile( String projectFile )
278 	{
279 		this.projectFile = projectFile;
280 	}
281 
282 	/***
283 	 * Sets the soapUI settings file containing the tests to run
284 	 * 
285 	 * @param settingsFile
286 	 *           the soapUI settings file to use
287 	 */
288 
289 	public void setSettingsFile( String settingsFile )
290 	{
291 		this.settingsFile = settingsFile;
292 	}
293 
294 	public void setEnableUI( boolean enableUI )
295 	{
296 		this.enableUI = enableUI;
297 	}
298 
299 	public static class SoapUIOptions extends Options
300 	{
301 		private final String runnerName;
302 
303 		public SoapUIOptions( String runnerName )
304 		{
305 			this.runnerName = runnerName;
306 		}
307 
308 		public String getRunnerName()
309 		{
310 			return runnerName;
311 		}
312 
313 		public boolean requiresProject()
314 		{
315 			return true;
316 		}
317 	}
318 
319 	public String getSoapUISettingsPassword()
320 	{
321 		return soapUISettingsPassword;
322 	}
323 
324 	public void setSoapUISettingsPassword( String soapUISettingsPassword )
325 	{
326 		this.soapUISettingsPassword = soapUISettingsPassword;
327 	}
328 
329 	public void setSystemProperties( String[] optionValues )
330 	{
331 		for( String option : optionValues )
332 		{
333 			int ix = option.indexOf( '=' );
334 			if( ix != -1 )
335 			{
336 				System.setProperty( option.substring( 0, ix ), option.substring( ix + 1 ) );
337 			}
338 		}
339 	}
340 
341 	public void setGlobalProperties( String[] optionValues )
342 	{
343 		for( String option : optionValues )
344 		{
345 			int ix = option.indexOf( '=' );
346 			if( ix != -1 )
347 			{
348 				String name = option.substring( 0, ix );
349 				String value = option.substring( ix + 1 );
350 				log.info( "Setting global property [" + name + "] to [" + value + "]" );
351 				PropertyExpansionUtils.getGlobalProperties().setPropertyValue( name, value );
352 			}
353 		}
354 	}
355 
356 	public void setProjectProperties( String[] projectProperties )
357 	{
358 		this.projectProperties = projectProperties;
359 	}
360 
361 	/* (non-Javadoc)
362 	 * @see com.eviware.soapui.tools.CmdLineRunner#getLog()
363 	 */
364 	@Override
365 	public Logger getLog()
366 	{
367 		return log;
368 	}
369 
370 	/* (non-Javadoc)
371 	 * @see com.eviware.soapui.tools.CmdLineRunner#getProjectProperties()
372 	 */
373 	@Override
374 	public String[] getProjectProperties()
375 	{
376 		return projectProperties;
377 	}
378 
379 	protected void initProjectProperties( WsdlProject project )
380 	{
381 		if( projectProperties != null )
382 		{
383 			for( String option : projectProperties )
384 			{
385 				int ix = option.indexOf( '=' );
386 				if( ix != -1 )
387 				{
388 					String name = option.substring( 0, ix );
389 					String value = option.substring( ix + 1 );
390 					log.info( "Setting project property [" + name + "] to [" + value + "]" );
391 					project.setPropertyValue( name, value );
392 				}
393 			}
394 		}
395 	}
396 
397 	public boolean isEnableUI()
398 	{
399 		return enableUI;
400 	}
401 }