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