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