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.teststeps;
    14
    15  import java.beans.PropertyChangeEvent;
    16  import java.beans.PropertyChangeListener;
    17  import java.beans.PropertyChangeSupport;
    18  import java.util.ArrayList;
    19  import java.util.List;
    20
    21  import org.apache.log4j.Logger;
    22  import org.apache.xmlbeans.XmlBoolean;
    23  import org.apache.xmlbeans.XmlObject;
    24
    25  import com.eviware.soapui.config.GotoConditionConfig;
    26  import com.eviware.soapui.config.GotoConditionTypeConfig;
    27  import com.eviware.soapui.config.GotoStepConfig;
    28  import com.eviware.soapui.config.TestStepConfig;
    29  import com.eviware.soapui.impl.wsdl.submit.filters.PropertyExpansionRequestFilter;
    30  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
    31  import com.eviware.soapui.model.iface.SubmitContext;
    32  import com.eviware.soapui.model.testsuite.TestRunContext;
    33  import com.eviware.soapui.model.testsuite.TestRunner;
    34  import com.eviware.soapui.model.testsuite.TestStep;
    35  import com.eviware.soapui.model.testsuite.TestStepResult;
    36  import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus;
    37  import com.eviware.soapui.support.UISupport;
    38
    39  /***
    40   * TestStep that moves execution to another step based on the contents of a XML Property
    41   *
    42   * @author ole.matzura
    43   */
    44
    45  public class WsdlGotoTestStep extends WsdlTestStep
    46  {
    47  	private GotoStepConfig gotoStepConfig;
    48  	private List<GotoCondition> conditions = new ArrayList<GotoCondition>();
    49  	private boolean canceled;
    50
    51  	private final static Logger log = Logger.getLogger( WsdlGotoTestStep.class );
    52
    53  	public WsdlGotoTestStep(WsdlTestCase testCase, TestStepConfig config, boolean forLoadTest)
    54  	{
    55  		super(testCase, config, true, forLoadTest);
    56
    57  		if( !forLoadTest )
    58  		{
    59  			setIcon( UISupport.createImageIcon("/goto.gif"));
    60  		}
    61  	}
    62
    63  	public void postInit( TestStepConfig config )
    64  	{
    65  		if( config.getConfig() == null )
    66  		{
    67  			gotoStepConfig = (GotoStepConfig) config.addNewConfig().changeType( GotoStepConfig.type );
    68  		}
    69  		else
    70  		{
    71  			gotoStepConfig = (GotoStepConfig) config.getConfig().changeType(GotoStepConfig.type);
    72  			for( int c = 0; c < gotoStepConfig.sizeOfConditionArray(); c++ )
    73  			{
    74  				conditions.add( new GotoCondition( gotoStepConfig.getConditionArray( c )));
    75  			}
    76  		}
    77  	}
    78
    79  	public void resetConfigOnMove(TestStepConfig config)
    80  	{
    81  		super.resetConfigOnMove( config );
    82
    83  		gotoStepConfig = (GotoStepConfig) config.getConfig().changeType(GotoStepConfig.type);
    84  		for( int c = 0; c < gotoStepConfig.sizeOfConditionArray(); c++ )
    85  		{
    86  			conditions.get( c ).setConfig( gotoStepConfig.getConditionArray( c ));
    87  		}
    88  	}
    89
    90  	public TestStepResult run(TestRunner runner, TestRunContext context)
    91  	{
    92  		WsdlTestStepResult result = new WsdlTestStepResult( this );
    93  		canceled = false;
    94
    95  		result.startTimer();
    96
    97  		WsdlTestRequestStep previousStep = (WsdlTestRequestStep) getTestCase().findPreviousStepOfType(
    98  				this, WsdlTestRequestStep.class );
    99
    100 		if( previousStep == null )
    101 		{
    102 			result.stopTimer();
    103 			result.addMessage( "Failed to find previous request step from [" + getName() + "]" );
    104 			result.setStatus( TestStepStatus.FAILED );
    105 			return result;
    106 		}
    107
    108 		GotoCondition target = runConditions( previousStep, context );
    109 		if( target == null )
    110 		{
    111 			result.addMessage( "Missing matching condition, moving on." );
    112 		}
    113 		else
    114 		{
    115 			String targetStepName = target.getTargetStep();
    116 			result.addMessage( "Matched condition [" + targetStepName + "], transferring to [" + targetStepName + "]" );
    117 			runner.gotoStep( runner.getTestCase().getTestStepIndexByName( targetStepName ) );
    118 		}
    119
    120 		result.stopTimer();
    121 		result.setStatus( TestStepStatus.OK );
    122 		return result;
    123 	}
    124
    125 	public GotoCondition runConditions(WsdlTestRequestStep previousStep, SubmitContext context)
    126 	{
    127 		for( GotoCondition condition : conditions )
    128 		{
    129 			if( canceled )
    130 				break;
    131
    132 			try
    133 			{
    134 				if( condition.evaluate( previousStep, context ))
    135 				{
    136 					return condition;
    137 				}
    138 			}
    139 			catch (Exception e)
    140 			{
    141 				log.error( "Error making condition " + condition.getName() + "; " + e );
    142 			}
    143 		}
    144
    145 		return null;
    146 	}
    147
    148 	public boolean cancel()
    149 	{
    150 		canceled = true;
    151 		return canceled;
    152 	}
    153
    154 	public int getConditionCount()
    155 	{
    156 		return conditions.size();
    157 	}
    158
    159 	public GotoCondition getConditionAt( int index )
    160 	{
    161 		return conditions.get( index );
    162 	}
    163
    164 	public GotoCondition addCondition( String name )
    165 	{
    166 		GotoCondition condition = new GotoCondition( gotoStepConfig.addNewCondition());
    167 		condition.setName( name );
    168 		condition.setType( GotoConditionTypeConfig.XPATH.toString() );
    169 		conditions.add( condition );
    170 		return condition;
    171 	}
    172
    173 	public void removeConditionAt( int index )
    174 	{
    175 		conditions.remove( index );
    176 		gotoStepConfig.removeCondition( index );
    177 	}
    178
    179 	public void release()
    180 	{
    181 		super.release();
    182
    183 		for( GotoCondition condition : conditions )
    184 		{
    185 			condition.release();
    186 		}
    187 	}
    188
    189 	public class GotoCondition implements PropertyChangeListener
    190 	{
    191 		public final static String TARGET_STEP_PROPERTY = "target_step";
    192
    193 		private GotoConditionConfig conditionConfig;
    194 		private TestStep currentStep;
    195 		private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport( this );
    196
    197 		public GotoCondition(GotoConditionConfig conditionConfig)
    198 		{
    199 			this.conditionConfig = conditionConfig;
    200 			initListeners();
    201 		}
    202
    203 		public void addPropertyChangeListener( String propertyName, PropertyChangeListener listener )
    204 		{
    205 			propertyChangeSupport.addPropertyChangeListener( propertyName, listener );
    206 		}
    207
    208 		public void addPropertyChangeListener( PropertyChangeListener listener )
    209 		{
    210 			propertyChangeSupport.addPropertyChangeListener( listener );
    211 		}
    212
    213 		public void removePropertyChangeListener( String propertyName, PropertyChangeListener listener )
    214 		{
    215 			propertyChangeSupport.removePropertyChangeListener( propertyName, listener );
    216 		}
    217
    218 		public void removePropertyChangeListener( PropertyChangeListener listener )
    219 		{
    220 			propertyChangeSupport.removePropertyChangeListener( listener );
    221 		}
    222
    223 		private void initListeners()
    224 		{
    225 			release();
    226
    227 			if( getTargetStep() != null )
    228 			{
    229 				int index = getTestCase().getTestStepIndexByName( getTargetStep() );
    230 				if( index != -1 )
    231 				{
    232 					currentStep = getTestCase().getTestStepAt( index );
    233 					currentStep.addPropertyChangeListener( TestStep.NAME_PROPERTY, this );
    234 				}
    235 			}
    236 		}
    237
    238 		public void release()
    239 		{
    240 			if( currentStep != null )
    241 				currentStep.removePropertyChangeListener( this );
    242 		}
    243
    244 		public boolean evaluate(WsdlTestRequestStep previousStep, SubmitContext context) throws Exception
    245 		{
    246 			if( getExpression() == null || getExpression().trim().length() == 0 )
    247 				throw new Exception( "Missing expression in condition [" + getName() + "]" );
    248
    249 			if( getTargetStep() == null || getTargetStep().trim().length() == 0 )
    250 				throw new Exception( "Missing target step in condition [" + getName() + "]" );
    251
    252 			if( getType().equals( GotoConditionTypeConfig.XPATH.toString() ))
    253 			{
    254 				XmlObject xmlObject = XmlObject.Factory.parse( previousStep.getTestRequest().getResponse().getContentAsString());
    255
    256 				String expression = PropertyExpansionRequestFilter.expandProperties( context, getExpression() );
    257 				XmlObject[] selectPath = xmlObject.selectPath( expression );
    258 				if( selectPath.length == 1 && selectPath[0] instanceof XmlBoolean )
    259 				{
    260 					if( ((XmlBoolean)selectPath[0]).getBooleanValue() )
    261 					{
    262 						return true;
    263 					}
    264 				}
    265 			}
    266 			else
    267 			{
    268 				log.error( "Unkown condition type: " + getType() );
    269 			}
    270
    271 			return false;
    272 		}
    273
    274 		protected void setConfig(GotoConditionConfig conditionConfig)
    275 		{
    276 			this.conditionConfig = conditionConfig;
    277 		}
    278
    279 		public String getType()
    280 		{
    281 			return conditionConfig.getType();
    282 		}
    283
    284 		public String getName()
    285 		{
    286 			return conditionConfig.getName();
    287 		}
    288
    289 		public String getExpression()
    290 		{
    291 			return conditionConfig.getExpression();
    292 		}
    293
    294 		public String getTargetStep()
    295 		{
    296 			return conditionConfig.getTargetStep();
    297 		}
    298
    299 		public void setType( String type )
    300 		{
    301 			conditionConfig.setType( type );
    302 		}
    303
    304 		public void setName( String name )
    305 		{
    306 			conditionConfig.setName( name );
    307 		}
    308
    309 		public void setExpression( String expression )
    310 		{
    311 			conditionConfig.setExpression( expression );
    312 		}
    313
    314 		public void setTargetStep( String targetStep )
    315 		{
    316 			String oldStep = getTargetStep();
    317 			conditionConfig.setTargetStep( targetStep );
    318 			initListeners();
    319 			propertyChangeSupport.firePropertyChange( TARGET_STEP_PROPERTY, oldStep, targetStep );
    320 		}
    321
    322 		public void propertyChange(PropertyChangeEvent evt)
    323 		{
    324 			conditionConfig.setTargetStep( evt.getNewValue().toString() );
    325 			propertyChangeSupport.firePropertyChange( TARGET_STEP_PROPERTY, evt.getOldValue(), evt.getNewValue() );
    326 		}
    327 	}
    328 }