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