/*
* soapUI, copyright (C) 2004-2011 eviware.com
*
* soapUI is free software; you can redistribute it and/or modify it under the
* terms of version 2.1 of the GNU Lesser General Public License as published by
* the Free Software Foundation.
*
* soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details at gnu.org.
*/
package com.eviware.soapui.tools;
import java.io.File;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import com.eviware.soapui.DefaultSoapUICore;
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.SoapUICore;
import com.eviware.soapui.SoapUIExtensionClassLoader;
import com.eviware.soapui.SoapUIExtensionClassLoader.SoapUIClassLoaderState;
import com.eviware.soapui.StandaloneSoapUICore;
import com.eviware.soapui.impl.wsdl.WsdlProject;
import com.eviware.soapui.impl.wsdl.support.PathUtils;
import com.eviware.soapui.model.ModelItem;
import com.eviware.soapui.model.project.Project;
import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.UISupport;
public abstract class AbstractSoapUIRunner implements CmdLineRunner
{
private boolean groovyLogInitialized;
private String projectFile;
protected final Logger log = Logger.getLogger( getClass() );
private String settingsFile;
private String soapUISettingsPassword;
private String projectPassword;
private boolean enableUI;
private String outputFolder;
private String[] projectProperties;
public AbstractSoapUIRunner( String title )
{
if( title != null )
System.out.println( title );
SoapUI.setCmdLineRunner( this );
}
protected void initGroovyLog()
{
if( !groovyLogInitialized )
{
Logger logger = Logger.getLogger( "groovy.log" );
ConsoleAppender appender = new ConsoleAppender();
appender.setWriter( new OutputStreamWriter( System.out ) );
appender.setLayout( new PatternLayout( "%d{ABSOLUTE} %-5p [%c{1}] %m%n" ) );
logger.addAppender( appender );
groovyLogInitialized = true;
}
}
public int runFromCommandLine( String[] args )
{
try
{
if( initFromCommandLine( args, true ) )
{
if( run() )
{
return 0;
}
}
}
catch( Throwable e )
{
log.error( e );
SoapUI.logError( e );
}
return -1;
}
public boolean initFromCommandLine( String[] args, boolean printHelp ) throws Exception
{
SoapUIOptions options = initCommandLineOptions();
CommandLineParser parser = new PosixParser();
CommandLine cmd = parser.parse( options, args );
if( options.requiresProject() )
{
args = cmd.getArgs();
if( args.length != 1 )
{
if( printHelp )
{
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp( options.getRunnerName() + " [options] <soapui-project-file>", options );
}
System.err.println( "Missing soapUI project file.." );
return false;
}
setProjectFile( args[0] );
}
return processCommandLine( cmd );
}
/**
* Main method to use for running the configured tests. Call after setting
* properties, etc as desired.
*
* @return true if execution should be blocked
* @throws Exception
* if an error or failure occurs during test execution
*/
public final boolean run() throws Exception
{
if( SoapUI.getSoapUICore() == null )
{
SoapUI.setSoapUICore( createSoapUICore(), true );
SoapUI.initGCTimer();
}
SoapUIClassLoaderState state = SoapUIExtensionClassLoader.ensure();
try
{
return runRunner();
}
finally
{
state.restore();
}
}
protected SoapUICore createSoapUICore()
{
if( enableUI )
{
StandaloneSoapUICore core = new StandaloneSoapUICore( settingsFile );
log.info( "Enabling UI Components" );
core.prepareUI();
UISupport.setMainFrame( null );
return core;
}
else
{
return new DefaultSoapUICore( null, settingsFile, soapUISettingsPassword );
}
}
protected abstract boolean processCommandLine( CommandLine cmd );
protected abstract SoapUIOptions initCommandLineOptions();
protected abstract boolean runRunner() throws Exception;
protected String getCommandLineOptionSubstSpace( CommandLine cmd, String key )
{
return cmd.getOptionValue( key ).replaceAll( "%20", " " );
}
/*
* (non-Javadoc)
*
* @see com.eviware.soapui.tools.CmdLineRunner#getProjectFile()
*/
@Override
public String getProjectFile()
{
return projectFile;
}
/*
* (non-Javadoc)
*
* @see com.eviware.soapui.tools.CmdLineRunner#getSettingsFile()
*/
@Override
public String getSettingsFile()
{
return settingsFile;
}
public void setOutputFolder( String outputFolder )
{
this.outputFolder = outputFolder;
}
/*
* (non-Javadoc)
*
* @see com.eviware.soapui.tools.CmdLineRunner#getOutputFolder()
*/
@Override
public String getOutputFolder()
{
return this.outputFolder;
}
public String getAbsoluteOutputFolder( ModelItem modelItem )
{
String folder = PropertyExpander.expandProperties( modelItem, outputFolder );
if( StringUtils.isNullOrEmpty( folder ) )
{
folder = PathUtils.getExpandedResourceRoot( modelItem );
}
else if( PathUtils.isRelativePath( folder ) )
{
folder = PathUtils.resolveResourcePath( folder, modelItem );
}
return folder;
}
public String getModelItemOutputFolder( ModelItem modelItem )
{
List<ModelItem> chain = new ArrayList<ModelItem>();
ModelItem p = modelItem;
while( !( p instanceof Project ) )
{
chain.add( 0, p );
p = p.getParent();
}
File dir = new File( getAbsoluteOutputFolder( modelItem ) );
dir.mkdir();
for( ModelItem item : chain )
{
dir = new File( dir, StringUtils.createFileName( item.getName(), '-' ) );
dir.mkdir();
}
return dir.getAbsolutePath();
}
protected void ensureOutputFolder( ModelItem modelItem )
{
ensureFolder( getAbsoluteOutputFolder( modelItem ) );
}
public void ensureFolder( String path )
{
if( path == null )
return;
File folder = new File( path );
if( !folder.exists() || !folder.isDirectory() )
folder.mkdirs();
}
/**
* Sets the soapUI project file containing the tests to run
*
* @param projectFile
* the soapUI project file containing the tests to run
*/
public void setProjectFile( String projectFile )
{
this.projectFile = projectFile;
}
/**
* Sets the soapUI settings file containing the tests to run
*
* @param settingsFile
* the soapUI settings file to use
*/
public void setSettingsFile( String settingsFile )
{
this.settingsFile = settingsFile;
}
public void setEnableUI( boolean enableUI )
{
this.enableUI = enableUI;
}
public static class SoapUIOptions extends Options
{
private final String runnerName;
public SoapUIOptions( String runnerName )
{
this.runnerName = runnerName;
}
public String getRunnerName()
{
return runnerName;
}
public boolean requiresProject()
{
return true;
}
}
public String getSoapUISettingsPassword()
{
return soapUISettingsPassword;
}
public void setSoapUISettingsPassword( String soapUISettingsPassword )
{
this.soapUISettingsPassword = soapUISettingsPassword;
}
public void setSystemProperties( String[] optionValues )
{
for( String option : optionValues )
{
int ix = option.indexOf( '=' );
if( ix != -1 )
{
System.setProperty( option.substring( 0, ix ), option.substring( ix + 1 ) );
}
}
}
public void setGlobalProperties( String[] optionValues )
{
for( String option : optionValues )
{
int ix = option.indexOf( '=' );
if( ix != -1 )
{
String name = option.substring( 0, ix );
String value = option.substring( ix + 1 );
log.info( "Setting global property [" + name + "] to [" + value + "]" );
PropertyExpansionUtils.getGlobalProperties().setPropertyValue( name, value );
}
}
}
public void setProjectProperties( String[] projectProperties )
{
this.projectProperties = projectProperties;
}
/*
* (non-Javadoc)
*
* @see com.eviware.soapui.tools.CmdLineRunner#getLog()
*/
@Override
public Logger getLog()
{
return log;
}
/*
* (non-Javadoc)
*
* @see com.eviware.soapui.tools.CmdLineRunner#getProjectProperties()
*/
@Override
public String[] getProjectProperties()
{
return projectProperties;
}
protected void initProjectProperties( WsdlProject project )
{
if( projectProperties != null )
{
for( String option : projectProperties )
{
int ix = option.indexOf( '=' );
if( ix != -1 )
{
String name = option.substring( 0, ix );
String value = option.substring( ix + 1 );
log.info( "Setting project property [" + name + "] to [" + value + "]" );
project.setPropertyValue( name, value );
}
}
}
}
public boolean isEnableUI()
{
return enableUI;
}
public String getProjectPassword()
{
return projectPassword;
}
public void setProjectPassword( String projectPassword )
{
this.projectPassword = projectPassword;
}
}