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.util.ArrayList;
18  import java.util.HashMap;
19  import java.util.Iterator;
20  import java.util.List;
21  import java.util.Map;
22  
23  import javax.swing.ImageIcon;
24  
25  import com.eviware.soapui.SoapUI;
26  import com.eviware.soapui.config.AttachmentConfig;
27  import com.eviware.soapui.config.CallConfig;
28  import com.eviware.soapui.config.RequestAssertionConfig;
29  import com.eviware.soapui.impl.settings.XmlBeansSettingsImpl;
30  import com.eviware.soapui.impl.wsdl.WsdlInterface;
31  import com.eviware.soapui.impl.wsdl.WsdlOperation;
32  import com.eviware.soapui.impl.wsdl.WsdlRequest;
33  import com.eviware.soapui.impl.wsdl.submit.transports.http.WsdlResponse;
34  import com.eviware.soapui.impl.wsdl.support.assertions.AssertionsSupport;
35  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
36  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
37  import com.eviware.soapui.impl.wsdl.teststeps.assertions.WsdlAssertionRegistry;
38  import com.eviware.soapui.impl.wsdl.teststeps.assertions.WsdlAssertionRegistry.AssertableType;
39  import com.eviware.soapui.model.ModelItem;
40  import com.eviware.soapui.model.iface.Submit;
41  import com.eviware.soapui.model.iface.SubmitContext;
42  import com.eviware.soapui.model.testsuite.Assertable;
43  import com.eviware.soapui.model.testsuite.AssertionsListener;
44  import com.eviware.soapui.model.testsuite.TestAssertion;
45  import com.eviware.soapui.monitor.TestMonitor;
46  import com.eviware.soapui.support.UISupport;
47  
48  /***
49   * WsdlRequest extension that adds WsdlAssertions
50   * 
51   * @author Ole.Matzura
52   */
53  
54  public class WsdlTestRequest extends WsdlRequest implements PropertyChangeListener, Assertable
55  {
56  	public static final String RESPONSE_PROPERTY = WsdlTestRequest.class.getName() + "@response";
57  	public static final String STATUS_PROPERTY = WsdlTestRequest.class.getName() + "@status";
58  
59  	private static ImageIcon validRequestIcon;
60  	private static ImageIcon failedRequestIcon;
61  	private static ImageIcon disabledRequestIcon;
62  	private static ImageIcon unknownRequestIcon;
63  
64  	private AssertionStatus currentStatus;
65  	private final WsdlTestRequestStep testStep;
66  
67  	private AssertionsSupport assertionsSupport;
68  	private WsdlResponseMessageExchange messageExchange;
69  	private final boolean forLoadTest;
70  	private PropertyChangeNotifier notifier;
71  
72  	public WsdlTestRequest( WsdlOperation operation, CallConfig callConfig, WsdlTestRequestStep testStep,
73  				boolean forLoadTest )
74  	{
75  		super( operation, callConfig, forLoadTest );
76  		this.forLoadTest = forLoadTest;
77  
78  		setSettings( new XmlBeansSettingsImpl( this, testStep.getSettings(), callConfig.getSettings() ) );
79  
80  		this.testStep = testStep;
81  
82  		initAssertions();
83  		initIcons();
84  	}
85  
86  	public WsdlTestCase getTestCase()
87  	{
88  		return testStep.getTestCase();
89  	}
90  
91  	protected void initIcons()
92  	{
93  		if( validRequestIcon == null )
94  			validRequestIcon = UISupport.createImageIcon( "/valid_request.gif" );
95  
96  		if( failedRequestIcon == null )
97  			failedRequestIcon = UISupport.createImageIcon( "/invalid_request.gif" );
98  
99  		if( unknownRequestIcon == null )
100 			unknownRequestIcon = UISupport.createImageIcon( "/unknown_request.gif" );
101 
102 		if( disabledRequestIcon == null )
103 			disabledRequestIcon = UISupport.createImageIcon( "/disabled_request.gif" );
104 	}
105 
106 	@Override
107 	protected RequestIconAnimator initIconAnimator()
108 	{
109 		return new TestRequestIconAnimator();
110 	}
111 
112 	private void initAssertions()
113 	{
114 		assertionsSupport = new AssertionsSupport( testStep, getConfig().getAssertionList() );
115 	}
116 
117 	public int getAssertionCount()
118 	{
119 		return assertionsSupport.getAssertionCount();
120 	}
121 
122 	public WsdlMessageAssertion getAssertionAt( int c )
123 	{
124 		return assertionsSupport.getAssertionAt( c );
125 	}
126 
127 	@Override
128 	public void setResponse( WsdlResponse response, SubmitContext context )
129 	{
130 		super.setResponse( response, context );
131 
132 		assertResponse( context );
133 	}
134 
135 	public void assertResponse( SubmitContext context )
136 	{
137 		if( notifier == null )
138 			notifier = new PropertyChangeNotifier();
139 		
140 		messageExchange = new WsdlResponseMessageExchange( this );
141 
142 		// assert!
143 		for( Iterator<WsdlMessageAssertion> iter = assertionsSupport.iterator(); iter.hasNext(); )
144 		{
145 			WsdlMessageAssertion assertion = iter.next();
146 			assertion.assertResponse( messageExchange, context );
147 		}
148 
149 		notifier.notifyChange();
150 	}
151 
152 	private class PropertyChangeNotifier
153 	{
154 		private AssertionStatus oldStatus;
155 		private ImageIcon oldIcon;
156 
157 		public PropertyChangeNotifier()
158 		{
159 			oldStatus = getAssertionStatus();
160 			oldIcon = getIcon();
161 		}
162 
163 		public void notifyChange()
164 		{
165 			AssertionStatus newStatus = getAssertionStatus();
166 			ImageIcon newIcon = getIcon();
167 
168 			if( oldStatus != newStatus )
169 				notifyPropertyChanged( STATUS_PROPERTY, oldStatus, newStatus );
170 
171 			if( oldIcon != newIcon )
172 				notifyPropertyChanged( ICON_PROPERTY, oldIcon, getIcon() );
173 			
174 			oldStatus = newStatus;
175 			oldIcon = newIcon;
176 		}
177 	}
178 
179 	public WsdlMessageAssertion addAssertion( String assertionLabel )
180 	{
181 		PropertyChangeNotifier notifier = new PropertyChangeNotifier();
182 
183 		try
184 		{
185 			RequestAssertionConfig assertionConfig = getConfig().addNewAssertion();
186 			assertionConfig.setType( WsdlAssertionRegistry.getInstance().getAssertionTypeForName( assertionLabel ) );
187 
188 			WsdlMessageAssertion assertion = assertionsSupport.addWsdlAssertion( assertionConfig );
189 			assertionsSupport.fireAssertionAdded( assertion );
190 
191 			if( getResponse() != null )
192 			{
193 				assertion.assertResponse( new WsdlResponseMessageExchange( this ), new WsdlTestRunContext( testStep ) );
194 				notifier.notifyChange();
195 			}
196 
197 			return assertion;
198 		}
199 		catch( Exception e )
200 		{
201 			SoapUI.logError( e );
202 			return null;
203 		}
204 	}
205 
206 	public void removeAssertion( TestAssertion assertion )
207 	{
208 		PropertyChangeNotifier notifier = new PropertyChangeNotifier();
209 
210 		try
211 		{
212 			int ix = assertionsSupport.removeAssertion( ( WsdlMessageAssertion ) assertion );
213 			getConfig().removeAssertion( ix );
214 		}
215 		finally
216 		{
217 			((WsdlMessageAssertion)assertion).release();
218 			notifier.notifyChange();
219 		}
220 	}
221 
222 	public AssertionStatus getAssertionStatus()
223 	{
224 		currentStatus = AssertionStatus.UNKNOWN;
225 
226 		if( messageExchange != null )
227 		{
228 			if( !messageExchange.hasResponse() && !getOperation().isOneWay() )
229 			{
230 				currentStatus = AssertionStatus.FAILED;
231 			}
232 		}
233 		else
234 			return currentStatus;
235 
236 		int cnt = getAssertionCount();
237 		if( cnt == 0 )
238 			return currentStatus;
239 
240 		for( int c = 0; c < cnt; c++ )
241 		{
242 			if( getAssertionAt( c ).getStatus() == AssertionStatus.FAILED )
243 			{
244 				currentStatus = AssertionStatus.FAILED;
245 				break;
246 			}
247 		}
248 
249 		if( currentStatus == AssertionStatus.UNKNOWN )
250 			currentStatus = AssertionStatus.VALID;
251 
252 		return currentStatus;
253 	}
254 
255 	@Override
256 	public ImageIcon getIcon()
257 	{
258 		if( forLoadTest )
259 			return null;
260 
261 		TestMonitor testMonitor = SoapUI.getTestMonitor();
262 		if( testMonitor != null && testMonitor.hasRunningLoadTest( testStep.getTestCase() ) )
263 			return disabledRequestIcon;
264 
265 		ImageIcon icon = getIconAnimator().getIcon();
266 		if( icon == getIconAnimator().getBaseIcon() )
267 		{
268 			AssertionStatus status = getAssertionStatus();
269 			if( status == AssertionStatus.VALID )
270 				return validRequestIcon;
271 			else if( status == AssertionStatus.FAILED )
272 				return failedRequestIcon;
273 			else if( status == AssertionStatus.UNKNOWN )
274 				return unknownRequestIcon;
275 		}
276 
277 		return icon;
278 	}
279 
280 	public void propertyChange( PropertyChangeEvent evt )
281 	{
282 		if( getResponse() == null )
283 			return;
284 
285 		String propertyName = evt.getPropertyName();
286 		if( propertyName.equals( WsdlMessageAssertion.CONFIGURATION_PROPERTY )
287 					|| propertyName.equals( WsdlMessageAssertion.DISABLED_PROPERTY ) )
288 			assertResponse( new WsdlTestRunContext( testStep ) );
289 	}
290 
291 	public void addAssertionsListener( AssertionsListener listener )
292 	{
293 		assertionsSupport.addAssertionsListener( listener );
294 	}
295 
296 	public void removeAssertionsListener( AssertionsListener listener )
297 	{
298 		assertionsSupport.removeAssertionsListener( listener );
299 	}
300 
301 	/***
302 	 * Called when a testrequest is moved in a testcase
303 	 */
304 
305 	@Override
306 	public void updateConfig( CallConfig request )
307 	{
308 		super.updateConfig( request );
309 
310 		assertionsSupport.updateConfig( getConfig().getAssertionList() );
311 
312 		List<AttachmentConfig> attachmentConfigs = getConfig().getAttachmentList();
313 		for( int i = 0; i < attachmentConfigs.size(); i++ )
314 		{
315 			AttachmentConfig config = attachmentConfigs.get( i );
316 			attachments.get( i ).updateConfig( config );
317 		}
318 	}
319 
320 	@Override
321 	public void release()
322 	{
323 		super.release();
324 		assertionsSupport.release();
325 	}
326 
327 	public String getAssertableContent()
328 	{
329 		return getResponse() == null ? null : getResponse().getContentAsString();
330 	}
331 
332 	public WsdlTestRequestStep getTestStep()
333 	{
334 		return testStep;
335 	}
336 
337 	public WsdlInterface getInterface()
338 	{
339 		return getOperation().getInterface();
340 	}
341 
342 	protected class TestRequestIconAnimator extends RequestIconAnimator
343 	{
344 		@Override
345 		public boolean beforeSubmit( Submit submit, SubmitContext context )
346 		{
347 			if( SoapUI.getTestMonitor() != null && SoapUI.getTestMonitor().hasRunningLoadTest( getTestCase() ) )
348 				return true;
349 
350 			return super.beforeSubmit( submit, context );
351 		}
352 
353 		@Override
354 		public void afterSubmit( Submit submit, SubmitContext context )
355 		{
356 			if( submit.getRequest() == getTarget() )
357 				stop();
358 		}
359 	}
360 
361 	public AssertableType getAssertableType()
362 	{
363 		return AssertableType.RESPONSE;
364 	}
365 
366 	public String getInterfaceName()
367 	{
368 		return testStep.getInterfaceName();
369 	}
370 
371 	public String getOperationName()
372 	{
373 		return testStep.getOperationName();
374 	}
375 
376 	public TestAssertion cloneAssertion( TestAssertion source, String name )
377 	{
378 		RequestAssertionConfig conf = getConfig().addNewAssertion();
379 		conf.set( ((WsdlMessageAssertion)source).getConfig() );
380 		conf.setName( name );
381 
382 		WsdlMessageAssertion result = assertionsSupport.addWsdlAssertion( conf );
383 		assertionsSupport.fireAssertionAdded( result );
384 		return result;
385 	}
386 
387 	public WsdlMessageAssertion importAssertion( WsdlMessageAssertion source, boolean overwrite, boolean createCopy )
388 	{
389 		RequestAssertionConfig conf = getConfig().addNewAssertion();
390 		conf.set( source.getConfig() );
391 		if( createCopy && conf.isSetId() )
392 			conf.unsetId();
393 
394 		if( !source.isAllowMultiple() )
395 		{
396 			List<WsdlMessageAssertion> existing = assertionsSupport.getAssertionsOfType( source.getClass() );
397 			if( !existing.isEmpty() && !overwrite )
398 				return null;
399 
400 			while( !existing.isEmpty() )
401 			{
402 				removeAssertion( existing.remove( 0 ) );
403 			}
404 		}
405 
406 		WsdlMessageAssertion result = assertionsSupport.addWsdlAssertion( conf );
407 		assertionsSupport.fireAssertionAdded( result );
408 		return result;
409 	}
410 
411 	public List<TestAssertion> getAssertionList()
412 	{
413 		return new ArrayList<TestAssertion>( assertionsSupport.getAssertionList() );
414 	}
415 
416 	public WsdlMessageAssertion getAssertionByName( String name )
417 	{
418 		return assertionsSupport.getAssertionByName( name );
419 	}
420 
421 	public ModelItem getModelItem()
422 	{
423 		return testStep;
424 	}
425 	
426 	public Map<String,TestAssertion> getAssertions()
427 	{
428 		Map<String,TestAssertion> result = new HashMap<String, TestAssertion>();
429 		
430 		for( TestAssertion assertion : getAssertionList() )
431 			result.put( assertion.getName(), assertion );
432 		
433 		return result;
434 	}
435 }