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