View Javadoc

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