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 }