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.ActionEvent;
    19  import java.awt.event.KeyAdapter;
    20  import java.awt.event.KeyEvent;
    21  import java.awt.event.MouseAdapter;
    22  import java.awt.event.MouseEvent;
    23  import java.beans.PropertyChangeEvent;
    24  import java.beans.PropertyChangeListener;
    25  import java.util.ArrayList;
    26  import java.util.List;
    27
    28  import javax.swing.AbstractAction;
    29  import javax.swing.AbstractListModel;
    30  import javax.swing.Action;
    31  import javax.swing.JComponent;
    32  import javax.swing.JLabel;
    33  import javax.swing.JList;
    34  import javax.swing.JPanel;
    35  import javax.swing.JPopupMenu;
    36  import javax.swing.JScrollPane;
    37  import javax.swing.ListCellRenderer;
    38  import javax.swing.SwingUtilities;
    39  import javax.swing.event.ListSelectionEvent;
    40  import javax.swing.event.ListSelectionListener;
    41  import javax.swing.event.PopupMenuEvent;
    42  import javax.swing.event.PopupMenuListener;
    43
    44  import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
    45  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
    46  import com.eviware.soapui.impl.wsdl.support.assertions.Assertable;
    47  import com.eviware.soapui.impl.wsdl.support.assertions.AssertionsListener;
    48  import com.eviware.soapui.impl.wsdl.teststeps.WsdlMessageAssertion;
    49  import com.eviware.soapui.impl.wsdl.teststeps.actions.AddAssertionAction;
    50  import com.eviware.soapui.impl.wsdl.teststeps.assertions.AssertionError;
    51  import com.eviware.soapui.support.UISupport;
    52  import com.eviware.soapui.support.action.swing.ActionList;
    53  import com.eviware.soapui.support.action.swing.ActionListBuilder;
    54  import com.eviware.soapui.support.action.swing.ActionSupport;
    55  import com.eviware.soapui.support.components.JXToolBar;
    56
    57  /***
    58   * Seperate panel for holding/managing assertions
    59   *
    60   * @author ole.matzura
    61   */
    62
    63  public class AssertionsPanel extends JPanel
    64  {
    65  	private AssertionListModel assertionListModel;
    66  	private JList assertionList;
    67  	private JPopupMenu assertionListPopup;
    68  	private final Assertable assertable;
    69  	private AddAssertionAction addAssertionAction;
    70  	private ConfigureAssertionAction configureAssertionAction;
    71  	private RemoveAssertionAction removeAssertionAction;
    72
    73  	public AssertionsPanel( Assertable assertable )
    74  	{
    75  		super( new BorderLayout() );
    76  		this.assertable = assertable;
    77
    78        assertionListModel = new AssertionListModel();
    79        assertionList = new JList( assertionListModel );
    80        assertionList.setToolTipText( "Assertions for this request" );
    81        assertionList.setCellRenderer( new AssertionCellRenderer() );
    82
    83        assertionListPopup = new JPopupMenu();
    84        addAssertionAction = new AddAssertionAction( assertable );
    85  		assertionListPopup.add( addAssertionAction);
    86
    87        assertionListPopup.addPopupMenuListener( new PopupMenuListener(){
    88
    89           public void popupMenuWillBecomeVisible(PopupMenuEvent e)
    90           {
    91              while( assertionListPopup.getComponentCount() > 1 )
    92                 assertionListPopup.remove( 1 );
    93
    94              int ix = assertionList.getSelectedIndex();
    95              if( ix == -1 )
    96              {
    97              	assertionListPopup.addSeparator();
    98              	assertionListPopup.add( new ShowOnlineHelpAction( HelpUrls.RESPONSE_ASSERTIONS_HELP_URL ) );
    99              	return;
    100             }
    101
    102             WsdlMessageAssertion assertion = assertionListModel.getAssertionAt( ix );
    103             ActionSupport.addActions(
    104             			ActionListBuilder.buildActions( assertion ), assertionListPopup );
    105          }
    106
    107          public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
    108          {
    109          }
    110
    111          public void popupMenuCanceled(PopupMenuEvent e)
    112          {
    113          }});
    114
    115       assertionList.setComponentPopupMenu( assertionListPopup );
    116
    117       assertionList.addMouseListener( new MouseAdapter() {
    118
    119 			public void mouseClicked(MouseEvent e)
    120          {
    121             if( e.getClickCount() < 2 ) return;
    122
    123             int ix = assertionList.getSelectedIndex();
    124             if( ix == -1 ) return;
    125
    126             Object obj = assertionList.getModel().getElementAt( ix );
    127             if( obj instanceof WsdlMessageAssertion )
    128             {
    129 	            WsdlMessageAssertion assertion = (WsdlMessageAssertion) obj;
    130 	            if( assertion.isConfigurable() )
    131 	               assertion.configure();
    132
    133 	            return;
    134             }
    135
    136    		   if( obj instanceof AssertionError )
    137    		   {
    138    		   	AssertionError error = (AssertionError) obj;
    139    		   	if( error.getLineNumber() >= 0 )
    140    		   	{
    141    		   		selectError(error);
    142    		   	}
    143    		   	else Toolkit.getDefaultToolkit().beep();
    144    		   }
    145    		   else Toolkit.getDefaultToolkit().beep();
    146          }});
    147
    148       assertionList.addKeyListener( new KeyAdapter()
    149       {
    150       	public void keyPressed(KeyEvent e)
    151    		{
    152       		int ix = assertionList.getSelectedIndex();
    153             if( ix == -1 ) return;
    154
    155             WsdlMessageAssertion assertion = assertionListModel.getAssertionAt( ix );
    156             if( e.getKeyChar() == KeyEvent.VK_ENTER )
    157             {
    158 	            if( assertion.isConfigurable() )
    159 	               assertion.configure();
    160             }
    161             else
    162             {
    163 					ActionList actions = ActionListBuilder.buildActions( assertion );
    164 					if( actions != null )
    165 					{
    166 						actions.dispatchKeyEvent( e );
    167 					}
    168             }
    169    		}
    170       } );
    171
    172       add( new JScrollPane( assertionList ), BorderLayout.CENTER );
    173       add( buildToolbar(), BorderLayout.NORTH );
    174    }
    175
    176 	private JComponent buildToolbar()
    177 	{
    178 		configureAssertionAction = new ConfigureAssertionAction();
    179 		removeAssertionAction = new RemoveAssertionAction();
    180
    181 		JXToolBar toolbar = UISupport.createToolbar();
    182 		addToolbarButtons( toolbar );
    183
    184 		toolbar.addGlue();
    185 		toolbar.add( new ShowOnlineHelpAction( HelpUrls.REQUEST_ASSERTIONS_HELP_URL ));
    186
    187 		assertionList.addListSelectionListener( new ListSelectionListener() {
    188
    189 			public void valueChanged( ListSelectionEvent e )
    190 			{
    191 				int ix = assertionList.getSelectedIndex();
    192
    193 				configureAssertionAction.setEnabled( ix >= 0 );
    194 				removeAssertionAction.setEnabled( ix >= 0 );
    195
    196             if( ix == -1 ) return;
    197             configureAssertionAction.setEnabled( assertionListModel.getAssertionAt( ix ).isConfigurable() );
    198 			}} );
    199
    200 		return toolbar;
    201 	}
    202
    203 	protected void addToolbarButtons( JXToolBar toolbar )
    204 	{
    205 		toolbar.addFixed( UISupport.createToolbarButton( addAssertionAction ));
    206 		toolbar.addFixed( UISupport.createToolbarButton( configureAssertionAction ));
    207 		toolbar.addFixed( UISupport.createToolbarButton( removeAssertionAction ));
    208 	}
    209
    210 	public void setEnabled( boolean enabled )
    211 	{
    212 		assertionList.setEnabled( enabled );
    213 	}
    214
    215    protected void selectError(AssertionError error)
    216 	{
    217 	}
    218
    219 	private static class AssertionCellRenderer extends JLabel implements ListCellRenderer
    220    {
    221       public Component getListCellRendererComponent(
    222         JList list,
    223         Object value,
    224         int index,
    225         boolean isSelected,
    226         boolean cellHasFocus)
    227       {
    228       	if( value instanceof WsdlMessageAssertion )
    229       	{
    230       		WsdlMessageAssertion assertion = (WsdlMessageAssertion) value;
    231       		setText( assertion.getName() + " - " + assertion.getStatus().toString() );
    232             setIcon( assertion.getIcon() );
    233       	}
    234       	else if( value instanceof AssertionError )
    235       	{
    236             AssertionError assertion = (AssertionError) value;
    237             setText( " -> " + assertion.toString() );
    238             setIcon( null );
    239       	}
    240       	else if( value instanceof String )
    241       	{
    242       		setText( value.toString() );
    243       	}
    244
    245           if (isSelected)
    246           {
    247              setBackground(list.getSelectionBackground());
    248              setForeground(list.getSelectionForeground());
    249           }
    250           else
    251           {
    252              setBackground(list.getBackground());
    253              setForeground(list.getForeground());
    254           }
    255
    256           setEnabled(list.isEnabled());
    257           setFont(list.getFont());
    258           setOpaque(true);
    259
    260           return this;
    261       }
    262   }
    263
    264    private class AssertionListModel extends AbstractListModel implements PropertyChangeListener,
    265        AssertionsListener
    266    {
    267    	private List<Object> items = new ArrayList<Object>();
    268
    269       public AssertionListModel()
    270       {
    271       	init();
    272       }
    273
    274       public int getSize()
    275       {
    276       	return items.size();
    277       }
    278
    279       public Object getElementAt(int index)
    280       {
    281       	return index >= items.size() ? null : items.get( index );
    282       }
    283
    284       public WsdlMessageAssertion getAssertionAt( int index )
    285       {
    286       	Object object = items.get( index );
    287       	while( object instanceof AssertionError && index > 0 )
    288       	{
    289       		object = items.get( --index );
    290       	}
    291
    292       	return (WsdlMessageAssertion) object;
    293       }
    294
    295       public void refresh()
    296       {
    297       	synchronized( this )
    298 			{
    299 				release();
    300 	      	init();
    301 	         fireContentsChanged( this, 0, getSize()-1 );
    302 			}
    303       }
    304
    305 		private void init()
    306 		{
    307       	assertable.addAssertionsListener( this );
    308
    309          for( int c = 0; c < assertable.getAssertionCount(); c++ )
    310          {
    311          	WsdlMessageAssertion assertion = assertable.getAssertionAt( c );
    312          	addAssertion(assertion);
    313          }
    314 		}
    315
    316 		public void release()
    317 		{
    318          items.clear();
    319
    320          for( int c = 0; c < assertable.getAssertionCount(); c++ )
    321          {
    322          	WsdlMessageAssertion assertion = assertable.getAssertionAt( c );
    323          	assertion.removePropertyChangeListener( this );
    324          }
    325
    326          assertable.removeAssertionsListener( this );
    327 		}
    328
    329 		public synchronized void propertyChange(PropertyChangeEvent evt)
    330 		{
    331 			if( SwingUtilities.isEventDispatchThread() )
    332 				refresh();
    333 			else SwingUtilities.invokeLater( new Runnable() {
    334
    335 				public void run()
    336 				{
    337 					refresh();
    338 				}} );
    339 		}
    340
    341 		public void assertionAdded(WsdlMessageAssertion assertion)
    342 		{
    343 			synchronized( this )
    344 			{
    345 				int sz = getSize();
    346 				addAssertion(assertion);
    347
    348 				fireIntervalAdded( this, sz, items.size()-1 );
    349 			}
    350 		}
    351
    352 		private void addAssertion(WsdlMessageAssertion assertion)
    353 		{
    354 			assertion.addPropertyChangeListener( this );
    355       	items.add( assertion );
    356
    357       	AssertionError[] errors = assertion.getErrors();
    358       	if( errors != null)
    359       	{
    360       		for( int i = 0; i < errors.length; i++ )
    361       		items.add( errors[i] );
    362       	}
    363 		}
    364
    365 		public void assertionRemoved(WsdlMessageAssertion assertion)
    366 		{
    367 			synchronized( this )
    368 			{
    369 				int ix = items.indexOf( assertion );
    370 				if( ix == -1 ) return;
    371
    372 				assertion.removePropertyChangeListener( this );
    373 				items.remove( ix );
    374 				fireIntervalRemoved( this, ix, ix );
    375
    376 				// remove associated errors
    377 				while( ix < items.size() && items.get( ix ) instanceof AssertionError )
    378 				{
    379 					items.remove( ix );
    380 					fireIntervalRemoved( this, ix, ix );
    381 				}
    382 			}
    383 		}
    384    }
    385
    386 	public void release()
    387 	{
    388 		assertionListModel.release();
    389 	}
    390
    391 	public class ConfigureAssertionAction extends AbstractAction
    392    {
    393       ConfigureAssertionAction()
    394       {
    395       	super( "Configure" );
    396       	putValue( Action.SHORT_DESCRIPTION, "Configures the selection assertion" );
    397       	putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/options.gif" ));
    398       	setEnabled( false );
    399       }
    400
    401       public void actionPerformed( ActionEvent e )
    402       {
    403       	int ix = assertionList.getSelectedIndex();
    404          if( ix == -1 ) return;
    405
    406          WsdlMessageAssertion assertion = assertionListModel.getAssertionAt( ix );
    407          if( assertion.isConfigurable() )
    408          {
    409             assertion.configure();
    410          }
    411 		   else Toolkit.getDefaultToolkit().beep();
    412       }
    413    }
    414
    415    public class RemoveAssertionAction extends AbstractAction
    416    {
    417       public RemoveAssertionAction()
    418       {
    419       	super( "Remove Assertion" );
    420       	putValue( Action.SHORT_DESCRIPTION, "Removes the selected assertion from this LoadTest" );
    421       	putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/remove_assertion.gif" ));
    422       	setEnabled( false );
    423       }
    424
    425       public void actionPerformed( ActionEvent e )
    426       {
    427       	int ix = assertionList.getSelectedIndex();
    428          if( ix == -1 ) return;
    429
    430          WsdlMessageAssertion assertion = assertionListModel.getAssertionAt( ix );
    431          if( UISupport.confirm( "Remove assertion [" + assertion.getName() + "]", "Remove Assertion"))
    432          {
    433          	assertable.removeAssertion( assertion );
    434          }
    435       }
    436    }
    437 }