View Javadoc

1   /*
2    *  soapui, copyright (C) 2005 Ole Matzura / 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.lang.reflect.Constructor;
18  import java.util.ArrayList;
19  import java.util.HashMap;
20  import java.util.Iterator;
21  import java.util.List;
22  import java.util.Map;
23  
24  import javax.swing.ImageIcon;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  
29  import com.eviware.soapui.SoapUI;
30  import com.eviware.soapui.config.CallConfig;
31  import com.eviware.soapui.config.RequestAssertionConfig;
32  import com.eviware.soapui.impl.wsdl.WsdlOperation;
33  import com.eviware.soapui.impl.wsdl.WsdlRequest;
34  import com.eviware.soapui.impl.wsdl.actions.request.DeleteRequestAction;
35  import com.eviware.soapui.impl.wsdl.actions.request.RenameRequestAction;
36  import com.eviware.soapui.impl.wsdl.panels.request.WsdlTestRequestPanelBuilder;
37  import com.eviware.soapui.impl.wsdl.teststeps.WsdlAssertion.AssertionStatus;
38  import com.eviware.soapui.impl.wsdl.teststeps.actions.AddAssertionAction;
39  import com.eviware.soapui.impl.wsdl.teststeps.assertions.SchemaComplianceAssertion;
40  import com.eviware.soapui.impl.wsdl.teststeps.assertions.SimpleContainsAssertion;
41  import com.eviware.soapui.impl.wsdl.teststeps.assertions.SimpleNotContainsAssertion;
42  import com.eviware.soapui.impl.wsdl.teststeps.assertions.SoapFaultAssertion;
43  import com.eviware.soapui.impl.wsdl.teststeps.assertions.XPathContainsAssertion;
44  import com.eviware.soapui.model.PanelBuilder;
45  import com.eviware.soapui.model.testsuite.TestCase;
46  
47  /***
48   * WsdlRequest extension that adds WsdlAssertions
49   * 
50   * @author Ole.Matzura
51   */
52  
53  public class WsdlTestRequest extends WsdlRequest implements PropertyChangeListener
54  {
55     public static final String RESPONSE_PROPERTY = WsdlTestRequest.class.getName() + "@response";
56     public static final String STATUS_PROPERTY = WsdlTestRequest.class.getName() + "@status";
57     
58     private List<WsdlAssertion> assertions = new ArrayList<WsdlAssertion>();
59     private Map<String,Class<? extends WsdlAssertion> > availableAssertions = new HashMap<String,Class<? extends WsdlAssertion> >();
60     private final static Log log = LogFactory.getLog( WsdlTestRequest.class );
61     private ImageIcon validRequestIcon;
62     private ImageIcon failedRequestIcon;
63     private ImageIcon unknownRequestIcon;
64     private WsdlAssertion.AssertionStatus currentStatus;
65     private final WsdlTestRequestStep testStep;
66     private List<WsdlTestRequestListener> testRequestListeners = new ArrayList<WsdlTestRequestListener>();
67     
68     public WsdlTestRequest( WsdlOperation operation, CallConfig callConfig, WsdlTestRequestStep testStep )
69     {
70        super( operation, callConfig );
71        this.testStep = testStep;
72        
73        initAssertions();
74     }
75     
76     protected PanelBuilder initPanelBuilder()
77     {
78        return new WsdlTestRequestPanelBuilder( this );
79     }
80     
81     public TestCase getTestCase()
82     {
83        return testStep.getTestCase();
84     }
85  
86     public WsdlTestRequestStep getRequestStep()
87     {
88        return testStep;
89     }
90     
91     protected void initIcons()
92     {
93        super.initIcons();
94        
95        validRequestIcon = SoapUI.createImageIcon("/valid_request.gif");
96        failedRequestIcon = SoapUI.createImageIcon("/invalid_request.gif");
97        unknownRequestIcon = SoapUI.createImageIcon("/unknown_request.gif");
98     }
99     
100    protected void initActions()
101    {
102       addAction( new RenameRequestAction( this ));
103       addAction( new DeleteRequestAction( this ));
104       addAction( new AddAssertionAction( this ));
105    }
106 
107    private void initAssertions()
108    {
109       availableAssertions.put( "Schema Compliance", SchemaComplianceAssertion.class );
110       availableAssertions.put( "Simple Contains", SimpleContainsAssertion.class );
111       availableAssertions.put( "Simple NotContains", SimpleNotContainsAssertion.class );
112       availableAssertions.put( "XPath Match", XPathContainsAssertion.class );
113       availableAssertions.put( "SOAP Fault Assertion", SoapFaultAssertion.class );
114       
115       RequestAssertionConfig[] assertionConfigs = getConfig().getAssertionArray();
116       for (int i = 0; i < assertionConfigs.length; i++)
117       {
118          RequestAssertionConfig config = assertionConfigs[i];
119          String type = config.getType();
120          
121          if( availableAssertions.containsKey( type ))
122          {
123             addWsdlAssertion(config, type);
124          }
125       }
126    }
127 
128 	private WsdlAssertion addWsdlAssertion(RequestAssertionConfig config, String type) 
129 	{
130 		try
131 		{
132 		   Class<? extends WsdlAssertion> clazz = availableAssertions.get(type);
133 		   Constructor<? extends WsdlAssertion> ctor = clazz.getConstructor(new Class[] { RequestAssertionConfig.class, WsdlTestRequest.class });
134 
135 		   WsdlAssertion assertion = (WsdlAssertion) ctor.newInstance( config, this );
136 		   assertions.add(assertion);
137 		   assertion.addPropertyChangeListener( this);
138 		   
139 		   return assertion;
140 		}
141 		catch (Exception e)
142 		{
143 		   e.printStackTrace();
144 		   return null;
145 		}
146 	}
147    
148    public int getAssertionCount()
149    {
150       return assertions.size();
151    }
152 
153    public WsdlAssertion getAssertionAt(int c)
154    {
155       return assertions.get( c );
156    }
157 
158    public void setResponse(String response)
159    {
160       super.setResponse( response );
161       
162       assertRequest();
163    }
164 
165    private void assertRequest() 
166    {
167    	PropertyChangeNotifier notifier = new PropertyChangeNotifier();
168       
169       // assert!
170       for (Iterator<WsdlAssertion> iter = assertions.iterator(); iter.hasNext();)
171       {
172          iter.next().assertResponse( this );
173       }
174 
175       notifier.notifyChange();
176    }
177    
178    private class PropertyChangeNotifier
179    {
180 	   private AssertionStatus oldStatus;
181 	   private ImageIcon oldIcon;
182 
183 	   public PropertyChangeNotifier()
184 	   {
185 		   oldStatus = getAssertionStatus();
186 		   oldIcon = getIcon();
187 	   }
188 	   
189 	   public void notifyChange()
190 	   {
191 		   AssertionStatus newStatus = getAssertionStatus();
192 	      ImageIcon newIcon = getIcon();
193 	      
194 	      if( oldStatus != newStatus )
195 	         notifyPropertyChanged( STATUS_PROPERTY, oldStatus, newStatus );
196 	      
197 	      if( oldIcon != newIcon )
198 	         notifyPropertyChanged( ICON_PROPERTY, oldIcon, getIcon() );
199 	   }
200    }
201 
202    public String[] getAvailableAssertions()
203    {
204       return availableAssertions.keySet().toArray( new String[availableAssertions.size()] );
205    }
206 
207    public WsdlAssertion addAssertion(String assertionName)
208    {
209       if( !availableAssertions.containsKey( assertionName )) return null;
210       PropertyChangeNotifier notifier = new PropertyChangeNotifier();
211     
212       RequestAssertionConfig assertionConfig = getConfig().addNewAssertion();
213       assertionConfig.setType( assertionName );
214       
215       try
216       {
217       	WsdlAssertion assertion = addWsdlAssertion( assertionConfig, assertionName );
218       	notifyAssertionAdded( assertion );
219       	
220          if( getResponseContent() != null )
221          {
222             assertion.assertResponse( this );
223             notifier.notifyChange();
224          }
225          
226          return assertion;
227       }
228       catch (Exception e)
229       {
230          e.printStackTrace();
231          return null;
232       }
233    }
234 
235    private void notifyAssertionAdded(WsdlAssertion assertion)
236 	{
237    	WsdlTestRequestListener [] listeners = testRequestListeners.toArray( 
238    			new WsdlTestRequestListener[testRequestListeners.size()] );
239    	
240    	for( int c = 0; c < listeners.length; c++ )
241    	{
242    		listeners[c].assertionAdded( assertion );
243    	}
244 	}
245 
246    private void notifyAssertionRemoved( WsdlAssertion assertion)
247 	{
248    	WsdlTestRequestListener [] listeners = testRequestListeners.toArray( 
249    			new WsdlTestRequestListener[testRequestListeners.size()] );
250    	
251    	for( int c = 0; c < listeners.length; c++ )
252    	{
253    		listeners[c].assertionRemoved( assertion );
254    	}
255 	}
256 
257    
258 	public void removeAssertion(WsdlAssertion assertion)
259    {
260       int ix = assertions.indexOf( assertion );
261       if( ix == -1 ) 
262       {
263       	throw new RuntimeException( "assertion [" + assertion.getName() + "] not available " +
264       			"in test request [" + getName() + "]" );
265       }
266       
267       PropertyChangeNotifier notifier = new PropertyChangeNotifier();
268       
269       assertion.removePropertyChangeListener( this );
270       notifyAssertionRemoved( assertion );
271       
272       assertions.remove( ix );
273       getConfig().removeAssertion( ix );
274       
275       notifier.notifyChange();
276    }
277 
278    public AssertionStatus getAssertionStatus()
279    {
280       currentStatus = AssertionStatus.NONE;
281 
282       int c = getAssertionCount();
283       if( c == 0 ) return currentStatus;
284       
285       currentStatus = AssertionStatus.VALID;
286       
287       for( c = 0; c < getAssertionCount(); c++ )
288       {
289          AssertionStatus status = getAssertionAt( c ).getStatus();
290          if( status == AssertionStatus.FAILED )
291          {
292             currentStatus = AssertionStatus.FAILED;
293             break;
294          }
295          else if( status == AssertionStatus.UNKNOWN )
296          {
297             currentStatus = AssertionStatus.UNKNOWN;
298             break;
299          }
300       }
301       
302       return currentStatus;
303    }
304 
305    public ImageIcon getIcon()
306    {
307    	ImageIcon icon = getIconManager().getIcon();
308       if( icon == getIconManager().getRequestIcon() )
309       {
310          AssertionStatus status = getAssertionStatus();
311          if( status == AssertionStatus.VALID ) return validRequestIcon; 
312          else if( status == AssertionStatus.FAILED ) return failedRequestIcon; 
313          else if( status == AssertionStatus.UNKNOWN ) return unknownRequestIcon; 
314       }
315       
316       return icon;
317    }
318 
319    public void propertyChange(PropertyChangeEvent evt)
320    {
321 	  if( evt.getPropertyName().equals( WsdlAssertion.CONFIGURATION_PROPERTY ))
322 		  assertRequest();
323    }
324 
325    public void addWsdlTestRequestListener( WsdlTestRequestListener listener )
326    {
327    	testRequestListeners.add( listener );
328    }
329    
330    public void removeWsdlTestRequestListener( WsdlTestRequestListener listener )
331    {
332    	testRequestListeners.remove( listener );
333    }
334    
335    public interface WsdlTestRequestListener
336    {
337    	public void assertionAdded( WsdlAssertion assertion );
338    	
339    	public void assertionRemoved( WsdlAssertion assertion );
340    }
341 
342 	public void updateConfig(CallConfig request)
343 	{
344 		super.updateConfig(request);
345 		
346 		RequestAssertionConfig[] assertionConfigs = getConfig().getAssertionArray();
347       for (int i = 0; i < assertionConfigs.length; i++)
348       {
349          RequestAssertionConfig config = assertionConfigs[i];
350          assertions.get( i ).updateConfig( config );
351       }
352 	}
353 
354 	
355 }