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