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.panels.teststeps;
14  
15  import java.awt.BorderLayout;
16  import java.awt.Component;
17  import java.awt.Toolkit;
18  import java.awt.event.MouseAdapter;
19  import java.awt.event.MouseEvent;
20  import java.beans.PropertyChangeEvent;
21  import java.beans.PropertyChangeListener;
22  import java.util.ArrayList;
23  import java.util.List;
24  
25  import javax.swing.AbstractListModel;
26  import javax.swing.JLabel;
27  import javax.swing.JList;
28  import javax.swing.JPanel;
29  import javax.swing.JPopupMenu;
30  import javax.swing.JScrollPane;
31  import javax.swing.ListCellRenderer;
32  import javax.swing.SwingUtilities;
33  import javax.swing.event.PopupMenuEvent;
34  import javax.swing.event.PopupMenuListener;
35  
36  import com.eviware.soapui.impl.wsdl.panels.support.assertions.Assertable;
37  import com.eviware.soapui.impl.wsdl.panels.support.assertions.AssertionsListener;
38  import com.eviware.soapui.impl.wsdl.teststeps.WsdlMessageAssertion;
39  import com.eviware.soapui.impl.wsdl.teststeps.actions.AddAssertionAction;
40  import com.eviware.soapui.impl.wsdl.teststeps.assertions.AssertionError;
41  import com.eviware.soapui.support.action.ActionSupport;
42  
43  public class AssertionsPanel extends JPanel
44  {
45  	private AssertionListModel assertionListModel;
46  	private JList assertionList;
47  	private JPopupMenu assertionListPopup;
48  	private final Assertable assertable;
49  
50  	public AssertionsPanel( Assertable assertable )
51  	{
52  		super( new BorderLayout() );
53  		this.assertable = assertable;
54  		
55        assertionListModel = new AssertionListModel();
56        assertionList = new JList( assertionListModel );
57        assertionList.setToolTipText( "Assertions for this request" );
58        assertionList.setCellRenderer( new AssertionCellRenderer() );
59        
60        assertionListPopup = new JPopupMenu();
61        assertionListPopup.add( new AddAssertionAction( assertable ));
62        
63        assertionListPopup.addPopupMenuListener( new PopupMenuListener(){
64  
65           public void popupMenuWillBecomeVisible(PopupMenuEvent e)
66           {
67              while( assertionListPopup.getComponentCount() > 1 ) 
68                 assertionListPopup.remove( 1 );
69              
70              if( assertionListModel.getSize() == 0 ) return;
71              int ix = assertionList.getSelectedIndex();
72              if( ix == -1 ) return;
73              
74              WsdlMessageAssertion assertion = assertionListModel.getAssertionAt( ix );
75              ActionSupport.addActions( assertion.getActions(), assertionListPopup );
76           }
77  
78           public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
79           {
80           }
81  
82           public void popupMenuCanceled(PopupMenuEvent e)
83           {
84           }});
85        
86        assertionList.setComponentPopupMenu( assertionListPopup );
87        
88        assertionList.addMouseListener( new MouseAdapter() {
89  
90  			public void mouseClicked(MouseEvent e)
91           {
92              if( e.getClickCount() < 2 ) return;
93  
94              int ix = assertionList.getSelectedIndex();
95              if( ix == -1 ) return;
96              
97              Object obj = assertionList.getModel().getElementAt( ix );
98              if( obj instanceof WsdlMessageAssertion )
99              {
100 	            WsdlMessageAssertion assertion = (WsdlMessageAssertion) obj;
101 	            if( assertion.isConfigurable() )
102 	               assertion.configure();
103 	            
104 	            return;
105             }
106             
107    		   if( obj instanceof AssertionError )
108    		   {
109    		   	AssertionError error = (AssertionError) obj;
110    		   	if( error.getLineNumber() >= 0 )
111    		   	{
112    		   		selectError(error);
113    		   	}
114    		   	else Toolkit.getDefaultToolkit().beep();
115    		   }
116    		   else Toolkit.getDefaultToolkit().beep();
117          }});
118       
119       add( new JScrollPane( assertionList ), BorderLayout.CENTER );
120    }
121 	
122 	public void setEnabled( boolean enabled )
123 	{
124 		assertionList.setEnabled( enabled );
125 	}
126 
127    protected void selectError(AssertionError error)
128 	{
129 	}
130    
131 	private static class AssertionCellRenderer extends JLabel implements ListCellRenderer 
132    {
133       public Component getListCellRendererComponent(
134         JList list,
135         Object value,           
136         int index,               
137         boolean isSelected,      
138         boolean cellHasFocus)    
139       {
140       	if( value instanceof WsdlMessageAssertion )
141       	{
142       		WsdlMessageAssertion assertion = (WsdlMessageAssertion) value;
143       		setText( assertion.getName() + " - " + assertion.getStatus().toString() );
144             setIcon( assertion.getIcon() );
145       	}
146       	else if( value instanceof AssertionError )
147       	{
148             AssertionError assertion = (AssertionError) value;
149             setText( " -> " + assertion.toString() );
150             setIcon( null );
151       	}
152       	else if( value instanceof String )
153       	{
154       		setText( value.toString() );
155       	}
156       	
157           if (isSelected) 
158           {
159              setBackground(list.getSelectionBackground());
160              setForeground(list.getSelectionForeground());
161           }
162           else 
163           {
164              setBackground(list.getBackground());
165              setForeground(list.getForeground());
166           }
167           
168           setEnabled(list.isEnabled());
169           setFont(list.getFont());
170           setOpaque(true);
171           
172           return this;
173       }
174   }
175    
176    private class AssertionListModel extends AbstractListModel implements PropertyChangeListener, 
177        AssertionsListener
178    {
179    	private List<Object> items = new ArrayList<Object>();
180    	
181       public AssertionListModel()
182       {
183       	init();
184       }
185       
186       public int getSize()
187       {
188       	return items.size();
189       }
190 
191       public Object getElementAt(int index)
192       {
193       	return index >= items.size() ? null : items.get( index );
194       }
195 
196       public WsdlMessageAssertion getAssertionAt( int index )
197       {
198       	Object object = items.get( index );
199       	while( object instanceof AssertionError && index > 0 )
200       	{
201       		object = items.get( --index );
202       	}
203       	
204       	return (WsdlMessageAssertion) object;
205       }
206       
207       public void refresh()
208       {
209       	synchronized( this )
210 			{
211 				release();
212 	      	init();
213 	         fireContentsChanged( this, 0, getSize()-1 );
214 			}
215       }
216 
217 		private void init()
218 		{
219       	assertable.addAssertionsListener( this );
220 			
221          for( int c = 0; c < assertable.getAssertionCount(); c++ )
222          {
223          	WsdlMessageAssertion assertion = assertable.getAssertionAt( c );
224          	addAssertion(assertion);
225          }
226 		}
227 		
228 		public void release()
229 		{
230          items.clear();
231 
232          for( int c = 0; c < assertable.getAssertionCount(); c++ )
233          {
234          	WsdlMessageAssertion assertion = assertable.getAssertionAt( c );
235          	assertion.removePropertyChangeListener( this );
236          }
237          
238          assertable.removeAssertionsListener( this );
239 		}
240 
241 		public synchronized void propertyChange(PropertyChangeEvent evt)
242 		{
243 			if( SwingUtilities.isEventDispatchThread() )
244 				refresh();
245 			else SwingUtilities.invokeLater( new Runnable() {
246 
247 				public void run()
248 				{
249 					refresh();
250 				}} );			
251 		}
252 
253 		public void assertionAdded(WsdlMessageAssertion assertion)
254 		{
255 			synchronized( this )
256 			{
257 				int sz = getSize();
258 				addAssertion(assertion);
259       	
260 				fireIntervalAdded( this, sz, items.size()-1 );
261 			}
262 		}
263 
264 		private void addAssertion(WsdlMessageAssertion assertion)
265 		{
266 			assertion.addPropertyChangeListener( this );
267       	items.add( assertion );
268       	
269       	AssertionError[] errors = assertion.getErrors();
270       	if( errors != null)
271       	{
272       		for( int i = 0; i < errors.length; i++ )
273       		items.add( errors[i] );
274       	}
275 		}
276 
277 		public void assertionRemoved(WsdlMessageAssertion assertion)
278 		{
279 			synchronized( this )
280 			{
281 				int ix = items.indexOf( assertion );
282 				if( ix == -1 ) return;
283 	
284 				assertion.removePropertyChangeListener( this );
285 				items.remove( ix );
286 				fireIntervalRemoved( this, ix, ix );
287 				
288 				// remove associated errors
289 				while( ix < items.size() && items.get( ix ) instanceof AssertionError )
290 				{
291 					items.remove( ix );
292 					fireIntervalRemoved( this, ix, ix );
293 				}
294 			}
295 		}
296    }
297 
298 	public void release()
299 	{
300 		assertionListModel.release();
301 	}
302 }