1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.monitor;
14
15 import java.awt.BorderLayout;
16 import java.awt.Dimension;
17 import java.awt.event.ActionEvent;
18 import java.awt.event.ActionListener;
19 import java.awt.event.ItemEvent;
20 import java.awt.event.ItemListener;
21 import java.net.MalformedURLException;
22 import java.net.URL;
23 import java.text.DateFormat;
24 import java.text.SimpleDateFormat;
25 import java.util.Collection;
26 import java.util.Date;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.Stack;
32
33 import javax.servlet.ServletRequest;
34 import javax.servlet.ServletResponse;
35 import javax.swing.AbstractAction;
36 import javax.swing.BorderFactory;
37 import javax.swing.DefaultComboBoxModel;
38 import javax.swing.JButton;
39 import javax.swing.JComboBox;
40 import javax.swing.JComponent;
41 import javax.swing.JLabel;
42 import javax.swing.JPanel;
43 import javax.swing.JProgressBar;
44 import javax.swing.JScrollPane;
45 import javax.swing.JToggleButton;
46 import javax.swing.ListSelectionModel;
47 import javax.swing.event.ListSelectionEvent;
48 import javax.swing.event.ListSelectionListener;
49 import javax.swing.table.AbstractTableModel;
50
51 import org.apache.commons.collections.list.TreeList;
52 import org.apache.commons.httpclient.HostConfiguration;
53 import org.apache.commons.httpclient.HttpMethod;
54 import org.jdesktop.swingx.JXTable;
55 import org.jdesktop.swingx.decorator.Filter;
56 import org.jdesktop.swingx.decorator.FilterPipeline;
57 import org.jdesktop.swingx.decorator.PatternFilter;
58
59 import com.eviware.soapui.SoapUI;
60 import com.eviware.soapui.impl.support.AbstractInterface;
61 import com.eviware.soapui.impl.wsdl.WsdlInterface;
62 import com.eviware.soapui.impl.wsdl.WsdlProject;
63 import com.eviware.soapui.impl.wsdl.WsdlRequest;
64 import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
65 import com.eviware.soapui.impl.wsdl.actions.monitor.SoapMonitorAction;
66 import com.eviware.soapui.impl.wsdl.actions.monitor.SoapMonitorAction.LaunchForm;
67 import com.eviware.soapui.impl.wsdl.mock.WsdlMockOperation;
68 import com.eviware.soapui.impl.wsdl.mock.WsdlMockResponse;
69 import com.eviware.soapui.impl.wsdl.mock.WsdlMockService;
70 import com.eviware.soapui.impl.wsdl.support.HelpUrls;
71 import com.eviware.soapui.impl.wsdl.support.MessageExchangeModelItem;
72 import com.eviware.soapui.impl.wsdl.support.MessageExchangeRequestMessageEditor;
73 import com.eviware.soapui.impl.wsdl.support.MessageExchangeResponseMessageEditor;
74 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
75 import com.eviware.soapui.impl.wsdl.teststeps.HttpTestRequest;
76 import com.eviware.soapui.impl.wsdl.teststeps.HttpTestRequestStep;
77 import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequest;
78 import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep;
79 import com.eviware.soapui.impl.wsdl.teststeps.registry.HttpRequestStepFactory;
80 import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestRequestStepFactory;
81 import com.eviware.soapui.model.iface.Attachment;
82 import com.eviware.soapui.model.iface.Interface;
83 import com.eviware.soapui.model.settings.Settings;
84 import com.eviware.soapui.model.support.ModelSupport;
85 import com.eviware.soapui.model.testsuite.TestSuite;
86 import com.eviware.soapui.settings.ProxySettings;
87 import com.eviware.soapui.settings.WebRecordingSettings;
88 import com.eviware.soapui.support.StringUtils;
89 import com.eviware.soapui.support.UISupport;
90 import com.eviware.soapui.support.components.BrowserComponent;
91 import com.eviware.soapui.support.components.JComponentInspector;
92 import com.eviware.soapui.support.components.JInspectorPanel;
93 import com.eviware.soapui.support.components.JInspectorPanelFactory;
94 import com.eviware.soapui.support.components.JXToolBar;
95 import com.eviware.soapui.support.types.StringList;
96 import com.eviware.soapui.support.types.StringToStringsMap;
97 import com.eviware.x.form.XFormDialog;
98 import com.eviware.x.form.XFormField;
99 import com.eviware.x.form.XFormFieldListener;
100 import com.eviware.x.form.support.ADialogBuilder;
101 import com.eviware.x.form.support.AField;
102 import com.eviware.x.form.support.AForm;
103 import com.eviware.x.form.support.AField.AFieldType;
104 import com.jgoodies.forms.builder.ButtonBarBuilder;
105
106 /***
107 * A SOAP Monitor..
108 */
109
110 @SuppressWarnings( "serial" )
111 public class SoapMonitor extends JPanel
112 {
113 private static final String ALL_FILTER_OPTION = "- all -";
114 private JProgressBar progressBar;
115 private JButton stopButton = null;
116
117 private JXTable logTable = null;
118 private MonitorLogTableModel tableModel = null;
119
120 private String httpProxyHost = null;
121 private int httpProxyPort = 80;
122
123 private JButton startButton;
124 private final WsdlProject project;
125 private MessageExchangeRequestMessageEditor requestViewer;
126 private MessageExchangeResponseMessageEditor responseViewer;
127 private SoapUIListenerSupport<MonitorListener> listeners = new SoapUIListenerSupport<MonitorListener>(
128 MonitorListener.class );
129 private MessageExchangeModelItem requestModelItem;
130 private JButton optionsButton;
131 private int listenPort;
132 private String targetEndpoint;
133 private JButton clearButton;
134 private int maxRows;
135 private JButton addToTestCaseButton;
136
137 private JButton createRequestButton;
138 private JButton addToMockServiceButton;
139 private Stack<WsdlMonitorMessageExchange> messageExchangeStack = new Stack<WsdlMonitorMessageExchange>();
140 private StackProcessor stackProcessor = new StackProcessor();
141 private PatternFilter operationFilter;
142 private PatternFilter interfaceFilter;
143 private PatternFilter targetHostFilter;
144 private JLabel infoLabel;
145 private PatternFilter requestHostFilter;
146 private JComboBox requestHostFilterCombo;
147 private JComboBox targetHostFilterCombo;
148 private JComboBox interfaceFilterCombo;
149 private JComboBox operationFilterCombo;
150 private DefaultComboBoxModel operationFilterModel;
151 private DefaultComboBoxModel requestFilterModel;
152 private DefaultComboBoxModel targetHostFilterModel;
153 private JLabel rowCountLabel = new JLabel();
154 private Map<AbstractInterface<?>, String> addedEndpoints;
155 private JXToolBar toolbar;
156 private String incomingRequestWss;
157 private String incomingResponseWss;
158 private boolean setAsProxy;
159 private XFormDialog optionsDialog;
160 private SoapMonitorEngine monitorEngine;
161 private String oldProxyHost;
162 private String oldProxyPort;
163 private boolean oldProxyEnabled;
164 private String sslEndpoint;
165 private JInspectorPanel inspectorPanel;
166
167 public SoapMonitor( WsdlProject project, int listenPort, String incomingRequestWss, String incomingResponseWss,
168 JXToolBar mainToolbar, boolean setAsProxy, String sslEndpoint )
169 {
170 super( new BorderLayout() );
171 this.project = project;
172 this.listenPort = listenPort;
173 this.incomingRequestWss = incomingRequestWss;
174 this.incomingResponseWss = incomingResponseWss;
175 this.setAsProxy = setAsProxy;
176 this.maxRows = 100;
177 this.sslEndpoint = sslEndpoint;
178
179
180
181 this.setLayout( new BorderLayout() );
182
183 add( buildToolbars( mainToolbar ), BorderLayout.NORTH );
184 add( buildContent(), BorderLayout.CENTER );
185
186 start();
187 }
188
189 public SoapMonitor( WsdlProject project, int sourcePort, String incomingRequestWss, String incomingResponseWss,
190 JXToolBar toolbar, boolean setAsProxy )
191 {
192 this( project, sourcePort, incomingRequestWss, incomingResponseWss, toolbar, setAsProxy, null );
193 }
194
195 private JComponent buildContent()
196 {
197 inspectorPanel = JInspectorPanelFactory.build( buildLog() );
198
199 JComponentInspector<JComponent> viewInspector = new JComponentInspector<JComponent>( buildViewer(),
200 "Message Content", "Shows message content", true );
201 inspectorPanel.addInspector( viewInspector );
202
203 return inspectorPanel.getComponent();
204 }
205
206 private JComponent buildLog()
207 {
208 tableModel = new MonitorLogTableModel();
209 logTable = new JXTable( 1, 2 );
210 logTable.setColumnControlVisible( true );
211 logTable.setModel( tableModel );
212 logTable.setHorizontalScrollEnabled( true );
213 logTable.setSelectionMode( ListSelectionModel.MULTIPLE_INTERVAL_SELECTION );
214
215 operationFilter = new PatternFilter( ".*", 0, 4 );
216 operationFilter.setAcceptNull( true );
217 interfaceFilter = new PatternFilter( ".*", 0, 3 );
218 interfaceFilter.setAcceptNull( true );
219 targetHostFilter = new PatternFilter( ".*", 0, 2 );
220 targetHostFilter.setAcceptNull( true );
221 requestHostFilter = new PatternFilter( ".*", 0, 1 );
222 requestHostFilter.setAcceptNull( true );
223
224 Filter[] filters = new Filter[] { requestHostFilter, targetHostFilter, interfaceFilter, operationFilter };
225
226 FilterPipeline pipeline = new FilterPipeline( filters );
227 logTable.setFilters( pipeline );
228
229 ListSelectionModel sel = logTable.getSelectionModel();
230 sel.addListSelectionListener( new ListSelectionListener()
231 {
232 public void valueChanged( ListSelectionEvent event )
233 {
234 int row = logTable.getSelectedRow();
235 if( row == -1 )
236 {
237
238
239 requestModelItem.setMessageExchange( null );
240 }
241 else
242 {
243 WsdlMonitorMessageExchange exchange = tableModel.getMessageExchangeAt( row );
244 requestModelItem.setMessageExchange( exchange );
245
246
247
248 }
249
250 addToMockServiceButton.setEnabled( row != -1 );
251 addToTestCaseButton.setEnabled( row != -1 );
252
253 createRequestButton.setEnabled( row != -1 );
254 }
255 } );
256
257 JPanel tablePane = new JPanel();
258 tablePane.setLayout( new BorderLayout() );
259
260 toolbar.addGlue();
261
262 tablePane.add( buildFilterBar(), BorderLayout.NORTH );
263 tablePane.add( new JScrollPane( logTable ), BorderLayout.CENTER );
264
265 return tablePane;
266 }
267
268 private JPanel buildFilterBar()
269 {
270 requestFilterModel = new DefaultComboBoxModel( new String[] { ALL_FILTER_OPTION } );
271 targetHostFilterModel = new DefaultComboBoxModel( new String[] { ALL_FILTER_OPTION } );
272 Dimension comboBoxSize = new Dimension( 90, 18 );
273 requestHostFilterCombo = UISupport.setFixedSize( new JComboBox( requestFilterModel ), comboBoxSize );
274
275
276
277
278 ButtonBarBuilder toolbar = new ButtonBarBuilder();
279
280 toolbar.addFixed( new JLabel( "Request Host" ) );
281 toolbar.addRelatedGap();
282 toolbar.addFixed( requestHostFilterCombo );
283 toolbar.addUnrelatedGap();
284
285 requestHostFilterCombo.addItemListener( new ItemListener()
286 {
287 public void itemStateChanged( ItemEvent e )
288 {
289 int ix = requestHostFilterCombo.getSelectedIndex();
290 if( ix == -1 )
291 return;
292
293 requestHostFilter.setAcceptNull( ix == 0 );
294
295 if( ix == 0 )
296 requestHostFilter.setPattern( ".*", 0 );
297 else
298 requestHostFilter.setPattern( requestHostFilterCombo.getSelectedItem().toString(), 0 );
299
300 updateRowCountLabel();
301 }
302 } );
303
304 toolbar.addFixed( new JLabel( "Target Host" ) );
305 toolbar.addRelatedGap();
306 targetHostFilterCombo = UISupport.setFixedSize( new JComboBox( targetHostFilterModel ), comboBoxSize );
307 toolbar.addFixed( targetHostFilterCombo );
308 toolbar.addUnrelatedGap();
309
310 targetHostFilterCombo.addItemListener( new ItemListener()
311 {
312 public void itemStateChanged( ItemEvent e )
313 {
314 int ix = targetHostFilterCombo.getSelectedIndex();
315 if( ix == -1 )
316 return;
317
318 targetHostFilter.setAcceptNull( ix == 0 );
319
320 if( ix == 0 )
321 targetHostFilter.setPattern( ".*", 0 );
322 else
323 targetHostFilter.setPattern( targetHostFilterCombo.getSelectedItem().toString(), 0 );
324
325 updateRowCountLabel();
326 }
327 } );
328
329 String[] interfaceNames = ModelSupport.getNames( new String[] { ALL_FILTER_OPTION }, ModelSupport.getChildren(
330 getProject(), WsdlInterface.class ) );
331
332 toolbar.addFixed( new JLabel( "Interface" ) );
333 toolbar.addRelatedGap();
334 interfaceFilterCombo = UISupport.setFixedSize( new JComboBox( interfaceNames ), comboBoxSize );
335 toolbar.addFixed( interfaceFilterCombo );
336 toolbar.addUnrelatedGap();
337
338 operationFilterModel = new DefaultComboBoxModel( new String[] { ALL_FILTER_OPTION } );
339 interfaceFilterCombo.addItemListener( new ItemListener()
340 {
341 public void itemStateChanged( ItemEvent e )
342 {
343 String item = ( String )interfaceFilterCombo.getSelectedItem();
344 operationFilterModel.removeAllElements();
345
346 if( item == null || getProject().getInterfaceByName( item ) == null )
347 {
348 operationFilterModel.addElement( ALL_FILTER_OPTION );
349 interfaceFilter.setPattern( ".*", 0 );
350 }
351 else if( getProject().getInterfaceByName( item ) != null )
352 {
353 WsdlInterface iface = ( WsdlInterface )getProject().getInterfaceByName( item );
354 String[] operationNames = ModelSupport.getNames( new String[] { ALL_FILTER_OPTION }, iface
355 .getOperationList() );
356 for( String s : operationNames )
357 operationFilterModel.addElement( s );
358
359 interfaceFilter.setPattern( iface.getName(), 0 );
360 }
361 }
362 } );
363
364 toolbar.addFixed( new JLabel( "Operation" ) );
365 toolbar.addRelatedGap();
366 operationFilterCombo = UISupport.setFixedSize( new JComboBox( operationFilterModel ), comboBoxSize );
367 toolbar.addFixed( operationFilterCombo );
368
369 operationFilterCombo.addItemListener( new ItemListener()
370 {
371 public void itemStateChanged( ItemEvent e )
372 {
373 int ix = operationFilterCombo.getSelectedIndex();
374 if( ix == -1 )
375 {
376 operationFilter.setPattern( ".*", 0 );
377 updateRowCountLabel();
378 return;
379 }
380
381 operationFilter.setAcceptNull( ix == 0 );
382
383 if( ix == 0 )
384 operationFilter.setPattern( ".*", 0 );
385 else
386 operationFilter.setPattern( operationFilterCombo.getSelectedItem().toString(), 0 );
387
388 updateRowCountLabel();
389 }
390 } );
391
392 toolbar.setBorder( BorderFactory.createEmptyBorder( 3, 2, 3, 0 ) );
393 return toolbar.getPanel();
394 }
395
396 protected void updateRowCountLabel()
397 {
398 rowCountLabel.setText( logTable.getRowCount() + "/" + tableModel.getRowCount() + " entries" );
399 }
400
401 private JComponent buildViewer()
402 {
403 requestModelItem = new MessageExchangeModelItem( "monitor message exchange", null )
404 {
405
406 @Override
407 public boolean hasRawData()
408 {
409 return true;
410 }
411 };
412
413 requestViewer = new MessageExchangeRequestMessageEditor( requestModelItem );
414 responseViewer = new MessageExchangeResponseMessageEditor( requestModelItem );
415
416 return UISupport.createHorizontalSplit( requestViewer, responseViewer );
417 }
418
419 private JComponent buildToolbars( JXToolBar mainToolbar )
420 {
421 toolbar = UISupport.createSmallToolbar();
422 mainToolbar.addFixed( startButton = UISupport.createToolbarButton( UISupport
423 .createImageIcon( "/run_testcase.gif" ) ) );
424 mainToolbar.addFixed( stopButton = UISupport.createToolbarButton( UISupport
425 .createImageIcon( "/stop_testcase.gif" ) ) );
426 mainToolbar.addFixed( optionsButton = UISupport.createToolbarButton( new SoapMonitorOptionsAction() ) );
427
428 toolbar.addFixed( createRequestButton = UISupport
429 .createToolbarButton( UISupport.createImageIcon( "/request.gif" ) ) );
430 toolbar.addFixed( addToTestCaseButton = UISupport.createToolbarButton( UISupport
431 .createImageIcon( "/testCase.gif" ) ) );
432
433
434
435 toolbar.addFixed( addToMockServiceButton = UISupport.createToolbarButton( UISupport
436 .createImageIcon( "/mockService.gif" ) ) );
437 toolbar.addFixed( clearButton = UISupport
438 .createToolbarButton( UISupport.createImageIcon( "/clear_loadtest.gif" ) ) );
439
440 startButton.setToolTipText( "Starts the HTTP Monitor as configured" );
441 stopButton.setToolTipText( "Stops the HTTP Monitor" );
442 optionsButton.setToolTipText( "Sets Monitor Options" );
443 clearButton.setToolTipText( "Clear all/selected messages from the log" );
444 createRequestButton.setToolTipText( "Creates requests from selected messages" );
445 addToTestCaseButton.setToolTipText( "Adds selected requests to a TestCase" );
446
447
448 addToMockServiceButton.setToolTipText( "Adds selected reponses to a MockService" );
449
450 createRequestButton.setEnabled( false );
451 addToMockServiceButton.setEnabled( false );
452 addToTestCaseButton.setEnabled( false );
453
454
455 startButton.addActionListener( new ActionListener()
456 {
457 public void actionPerformed( ActionEvent e )
458 {
459 start();
460 }
461 } );
462
463 stopButton.addActionListener( new ActionListener()
464 {
465 public void actionPerformed( ActionEvent e )
466 {
467 stop();
468 }
469 } );
470
471 clearButton.addActionListener( new ClearAction() );
472 createRequestButton.addActionListener( new CreateRequestsAction() );
473 addToTestCaseButton.addActionListener( new AddToTestCaseAction() );
474
475
476 addToMockServiceButton.addActionListener( new AddToMockServiceAction() );
477
478 mainToolbar.addGlue();
479
480 infoLabel = new JLabel();
481 infoLabel.setPreferredSize( new Dimension( 150, 20 ) );
482 infoLabel.setOpaque( false );
483 mainToolbar.addFixed( infoLabel );
484
485 progressBar = new JProgressBar();
486
487 JPanel progressBarPanel = UISupport.createProgressBarPanel( progressBar, 2, false );
488 progressBarPanel.setPreferredSize( new Dimension( 60, 20 ) );
489
490 mainToolbar.addFixed( progressBarPanel );
491 return toolbar;
492 }
493
494 /***
495 * Method start
496 */
497 public void start()
498 {
499 int localPort = getLocalPort();
500
501
502 monitorEngine = new SoapMonitorEngineImpl();
503 ( ( SoapMonitorEngineImpl )monitorEngine ).setSslEndpoint( sslEndpoint );
504 monitorEngine.start( this, localPort );
505
506 if( monitorEngine.isRunning() )
507 {
508 stopButton.setEnabled( true );
509 startButton.setEnabled( false );
510 optionsButton.setEnabled( false );
511 infoLabel.setText( ( monitorEngine.isProxy() ? "HTTP Proxy " : "SSL Tunnel " ) + "on port " + localPort );
512 progressBar.setIndeterminate( true );
513
514 if( setAsProxy )
515 {
516 oldProxyHost = SoapUI.getSettings().getString( ProxySettings.HOST, "" );
517 oldProxyPort = SoapUI.getSettings().getString( ProxySettings.PORT, "" );
518 oldProxyEnabled = SoapUI.getSettings().getBoolean( ProxySettings.ENABLE_PROXY );
519
520 SoapUI.getSettings().setString( ProxySettings.HOST, "127.0.0.1" );
521 SoapUI.getSettings().setString( ProxySettings.PORT, String.valueOf( localPort ) );
522 SoapUI.getSettings().setBoolean( ProxySettings.ENABLE_PROXY, true );
523 SoapUI.setProxyEnabled( true );
524 JToggleButton applyProxyButton = ( JToggleButton )SoapUI.getApplyProxyButton();
525 if( applyProxyButton != null )
526 applyProxyButton.setIcon( UISupport.createImageIcon( SoapUI.PROXY_ENABLED_ICON ) );
527 }
528
529 SoapUI.log.info( "Started HTTP Monitor on local port " + localPort );
530 }
531 else
532 {
533 stopButton.setEnabled( false );
534 startButton.setEnabled( true );
535 optionsButton.setEnabled( true );
536 infoLabel.setText( "Stopped" );
537 progressBar.setIndeterminate( false );
538
539 SoapUI.log.info( "Could not start HTTP Monitor on local port " + localPort );
540 }
541 }
542
543 /***
544 * Method close
545 */
546 public void close()
547 {
548 stop();
549 }
550
551 /***
552 * Method stop
553 */
554 public void stop()
555 {
556 monitorEngine.stop();
557 if( addedEndpoints != null )
558 {
559 for( Interface iface : addedEndpoints.keySet() )
560 iface.removeEndpoint( addedEndpoints.get( iface ) );
561
562 addedEndpoints.clear();
563 }
564
565 stopButton.setEnabled( false );
566 startButton.setEnabled( true );
567 optionsButton.setEnabled( true );
568 progressBar.setIndeterminate( false );
569 infoLabel.setText( "Stopped" );
570
571 if( setAsProxy )
572 {
573 SoapUI.getSettings().setString( ProxySettings.HOST, oldProxyHost );
574 SoapUI.getSettings().setString( ProxySettings.PORT, oldProxyPort );
575 SoapUI.getSettings().setBoolean( ProxySettings.ENABLE_PROXY, oldProxyEnabled );
576 SoapUI.setProxyEnabled( oldProxyEnabled );
577 JToggleButton applyProxyButton = ( JToggleButton )SoapUI.getApplyProxyButton();
578 if( applyProxyButton != null )
579 {
580 if( oldProxyEnabled )
581 {
582 applyProxyButton.setIcon( UISupport.createImageIcon( SoapUI.PROXY_ENABLED_ICON ) );
583 }
584 else
585 {
586 applyProxyButton.setIcon( UISupport.createImageIcon( SoapUI.PROXY_DISABLED_ICON ) );
587 }
588 }
589 }
590 }
591
592 @AForm( description = "Set options for adding selected requests to a MockService", name = "Add To MockService" )
593 private final class AddToMockServiceAction implements ActionListener
594 {
595 private static final String CREATE_NEW_OPTION = "<Create New>";
596 private XFormDialog dialog;
597
598 @AField( name = "Target MockService", description = "The target TestSuite", type = AFieldType.ENUMERATION )
599 public final static String MOCKSERVICE = "Target MockService";
600
601 @AField( name = "Open Editor", description = "Open the created MockService", type = AFieldType.BOOLEAN )
602 public final static String OPENEDITOR = "Open Editor";
603
604 public void actionPerformed( ActionEvent e )
605 {
606 int[] rows = logTable.getSelectedRows();
607 if( rows.length == 0 )
608 return;
609
610 if( dialog == null )
611 {
612 dialog = ADialogBuilder.buildDialog( this.getClass() );
613 }
614
615 String[] testSuiteNames = ModelSupport.getNames( new String[] { CREATE_NEW_OPTION }, getProject()
616 .getMockServiceList() );
617 dialog.setOptions( MOCKSERVICE, testSuiteNames );
618
619 if( dialog.show() )
620 {
621 int withoutOperation = 0;
622 for( int row : rows )
623 {
624 WsdlMonitorMessageExchange me = tableModel.getMessageExchangeAt( row );
625 if( me.getOperation() == null )
626 withoutOperation++ ;
627 }
628 if( withoutOperation == rows.length )
629 {
630 UISupport.showInfoMessage( "No SOAP requests selected!" );
631 return;
632 }
633 String targetMockServiceName = dialog.getValue( MOCKSERVICE );
634
635 WsdlMockService mockService = getProject().getMockServiceByName( targetMockServiceName );
636 if( mockService == null )
637 {
638 targetMockServiceName = ModelSupport.promptForUniqueName( "MockService", getProject(), "" );
639 if( targetMockServiceName == null )
640 return;
641
642 mockService = getProject().addNewMockService( targetMockServiceName );
643 mockService.setIncomingWss( incomingResponseWss );
644 }
645
646 int cnt = 0;
647 for( int row : rows )
648 {
649 WsdlMonitorMessageExchange me = tableModel.getMessageExchangeAt( row );
650 if( me.getOperation() == null )
651 continue;
652
653 WsdlMockOperation mockOperation = mockService.getMockOperation( me.getOperation() );
654 if( mockOperation == null )
655 mockOperation = mockService.addNewMockOperation( me.getOperation() );
656
657 WsdlMockResponse mockResponse = mockOperation
658 .addNewMockResponse( "Monitor Response " + ( ++cnt ), false );
659 mockResponse.setResponseContent( me.getResponseContent() );
660
661 Attachment[] requestAttachments = me.getResponseAttachments();
662 if( requestAttachments != null )
663 {
664 for( Attachment attachment : requestAttachments )
665 {
666 mockResponse.addAttachment( attachment );
667 }
668 }
669 }
670
671 if( cnt == 0 )
672 {
673 UISupport.showInfoMessage( "No response messages found" );
674 }
675 else
676 {
677 UISupport.showInfoMessage( "Added " + cnt + " MockResponses to MockService" );
678
679 if( dialog.getBooleanValue( OPENEDITOR ) )
680 UISupport.selectAndShow( mockService );
681 }
682 }
683 }
684 }
685
686 @AForm( description = "Set options for adding selected requests to a TestCase", name = "Add To TestCase" )
687 private final class AddToTestCaseAction implements ActionListener
688 {
689 private static final String CREATE_NEW_OPTION = "<Create New>";
690 private XFormDialog dialog;
691
692 @AField( name = "Target TestSuite", description = "The target TestSuite", type = AFieldType.ENUMERATION )
693 public final static String TESTSUITE = "Target TestSuite";
694
695 @AField( name = "Target TestCase", description = "The target TestCase for the requests", type = AFieldType.ENUMERATION )
696 public final static String TESTCASE = "Target TestCase";
697
698 @AField( name = "Open Editor", description = "Open the created TestCase", type = AFieldType.BOOLEAN )
699 public final static String OPENEDITOR = "Open Editor";
700
701 TestSuite testSuite;
702
703 public void actionPerformed( ActionEvent e )
704 {
705 int[] rows = logTable.getSelectedRows();
706 if( rows.length == 0 )
707 return;
708
709 if( dialog == null )
710 {
711 dialog = ADialogBuilder.buildDialog( this.getClass() );
712 dialog.getFormField( TESTSUITE ).addFormFieldListener( new XFormFieldListener()
713 {
714 public void valueChanged( XFormField sourceField, String newValue, String oldValue )
715 {
716 if( newValue.equals( CREATE_NEW_OPTION ) )
717 {
718 dialog.setOptions( TESTCASE, new String[] { CREATE_NEW_OPTION } );
719 }
720 else
721 {
722 testSuite = getProject().getTestSuiteByName( newValue );
723 dialog.setOptions( TESTCASE, testSuite == null ? new String[] { CREATE_NEW_OPTION } : ModelSupport
724 .getNames( testSuite.getTestCaseList(), new String[] { CREATE_NEW_OPTION } ) );
725 }
726 }
727 } );
728 }
729
730 String[] testSuiteNames = ModelSupport.getNames( new String[] { CREATE_NEW_OPTION }, getProject()
731 .getTestSuiteList() );
732 dialog.setOptions( TESTSUITE, testSuiteNames );
733 testSuite = getProject().getTestSuiteByName( dialog.getValue( TESTSUITE ) );
734 dialog.setOptions( TESTCASE, testSuite == null ? new String[] { CREATE_NEW_OPTION } : ModelSupport.getNames(
735 testSuite.getTestCaseList(), new String[] { CREATE_NEW_OPTION } ) );
736
737 if( dialog.show() )
738 {
739 String targetTestSuiteName = dialog.getValue( TESTSUITE );
740 String targetTestCaseName = dialog.getValue( TESTCASE );
741
742 WsdlTestSuite testSuite = getProject().getTestSuiteByName( targetTestSuiteName );
743 if( testSuite == null )
744 {
745 targetTestSuiteName = ModelSupport.promptForUniqueName( "TestSuite", getProject(), "" );
746 if( targetTestSuiteName == null )
747 return;
748
749 testSuite = getProject().addNewTestSuite( targetTestSuiteName );
750 }
751
752 WsdlTestCase testCase = testSuite.getTestCaseByName( targetTestCaseName );
753 if( testCase == null )
754 {
755 targetTestCaseName = ModelSupport.promptForUniqueName( "TestCase", testSuite, "" );
756 if( targetTestCaseName == null )
757 return;
758
759 testCase = testSuite.addNewTestCase( targetTestCaseName );
760 }
761
762 for( int row : rows )
763 {
764 WsdlMonitorMessageExchange me = tableModel.getMessageExchangeAt( row );
765 if( me.getOperation() != null )
766 {
767 WsdlTestRequestStep test = ( WsdlTestRequestStep )testCase.insertTestStep( WsdlTestRequestStepFactory
768 .createConfig( me.getOperation(), "Monitor Request " + ( row + 1 ) ), -1 );
769
770 WsdlTestRequest request = test.getTestRequest();
771 request.setRequestContent( me.getRequestContent() );
772 request.setEndpoint( me.getTargetUrl().toString() );
773 request.setIncomingWss( incomingRequestWss );
774
775 Attachment[] requestAttachments = me.getRequestAttachments();
776 if( requestAttachments != null )
777 {
778 for( Attachment attachment : requestAttachments )
779 {
780 request.importAttachment( attachment );
781 }
782 }
783 }
784 else
785 {
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804 HttpRequestStepFactory httpRequestStepFactory = new HttpRequestStepFactory();
805 HttpTestRequestStep test = ( HttpTestRequestStep )testCase.insertTestStep( httpRequestStepFactory
806 .createConfig( me, "Monitor Request " + ( row + 1 ) ), -1 );
807
808 test.getTestRequest().setRequestHeaders( excludeHeaders( me.getRequestHeaders() ) );
809
810 HttpTestRequest request = ( HttpTestRequest )test.getHttpRequest();
811
812 request.setEndpoint( me.getTargetUrl().toString() );
813
814 String existingMediaType = me.getResponseHeaders().get( "Content-Type", "" );
815 if( !StringUtils.isNullOrEmpty( existingMediaType ) )
816 {
817 request.setMediaType( existingMediaType );
818 }
819 if( "application/octet-stream".equals( existingMediaType )
820 || "application/x-amf".equals( existingMediaType ) )
821 {
822 request.attachBinaryData( me.getRequestContent().getBytes(), existingMediaType );
823 }
824 else
825 {
826 request.setRequestContent( me.getRequestContent() );
827 test.getTestRequest().setRequestContent( me.getRequestContent() );
828 }
829 Attachment[] requestAttachments = me.getRequestAttachments();
830 if( requestAttachments != null )
831 {
832 for( Attachment attachment : requestAttachments )
833 {
834 request.importAttachment( attachment );
835 }
836 }
837
838
839 }
840 }
841
842 if( dialog.getBooleanValue( OPENEDITOR ) )
843 UISupport.selectAndShow( testCase );
844 }
845 }
846 }
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981 private final class CreateRequestsAction implements ActionListener
982 {
983 public void actionPerformed( ActionEvent e )
984 {
985 int[] rows = logTable.getSelectedRows();
986 if( rows.length == 0 )
987 return;
988
989 if( UISupport.confirm( "Create " + rows.length + " requests", "Create Request" ) )
990 {
991 int withoutOperation = 0;
992 for( int row : rows )
993 {
994 WsdlMonitorMessageExchange me = tableModel.getMessageExchangeAt( row );
995 if( me.getOperation() == null )
996 {
997 withoutOperation++ ;
998 continue;
999 }
1000
1001 WsdlRequest request = me.getOperation().addNewRequest( "Monitor Request " + ( row + 1 ) );
1002
1003 request.setRequestContent( me.getRequestContent() );
1004 request.setEndpoint( me.getTargetUrl().toString() );
1005
1006 Attachment[] requestAttachments = me.getRequestAttachments();
1007 if( requestAttachments != null )
1008 {
1009 for( Attachment attachment : requestAttachments )
1010 {
1011 request.importAttachment( attachment );
1012 }
1013 }
1014 }
1015 if( withoutOperation > 0 )
1016 {
1017 UISupport.showInfoMessage( "For " + withoutOperation + "request(s) there are no operations",
1018 "Create Request" );
1019 }
1020 }
1021 }
1022 }
1023
1024 private final class ClearAction implements ActionListener
1025 {
1026 public void actionPerformed( ActionEvent e )
1027 {
1028 if( logTable.getRowCount() == 0 )
1029 return;
1030
1031 int[] rows = logTable.getSelectedRows();
1032
1033 if( rows.length == 0 )
1034 {
1035 if( UISupport.confirm( "Clear monitor log?", "Clear Log" ) )
1036 tableModel.clear();
1037 }
1038 else if( UISupport.confirm( "Clear " + rows.length + " rows from monitor log?", "Clear Log" ) )
1039 {
1040 tableModel.clearRows( rows );
1041 }
1042 }
1043 }
1044
1045 @SuppressWarnings( "unchecked" )
1046 public class MonitorLogTableModel extends AbstractTableModel
1047 {
1048 private List<WsdlMonitorMessageExchange> exchanges = new TreeList();
1049 private DateFormat sdf;
1050
1051 public MonitorLogTableModel()
1052 {
1053 sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
1054 }
1055
1056 public synchronized void clear()
1057 {
1058 int sz = exchanges.size();
1059 while( exchanges.size() > 0 )
1060 {
1061 WsdlMonitorMessageExchange removed = exchanges.remove( 0 );
1062 removed.discard();
1063 }
1064
1065 fireTableRowsDeleted( 0, sz );
1066
1067 while( requestFilterModel.getSize() > 1 )
1068 requestFilterModel.removeElementAt( 1 );
1069
1070 while( targetHostFilterModel.getSize() > 1 )
1071 targetHostFilterModel.removeElementAt( 1 );
1072
1073 updateRowCountLabel();
1074 }
1075
1076 public synchronized void clearRows( int[] indices )
1077 {
1078 for( int c = indices.length; c > 0; c-- )
1079 {
1080 int index = indices[c - 1];
1081 WsdlMonitorMessageExchange removed = exchanges.remove( logTable.convertRowIndexToModel( index ) );
1082 removed.discard();
1083 fireTableRowsDeleted( index, index );
1084 updateRowCountLabel();
1085 }
1086 }
1087
1088 public int getColumnCount()
1089 {
1090 return 12;
1091 }
1092
1093 public WsdlMonitorMessageExchange getMessageExchangeAt( int tableRow )
1094 {
1095 return exchanges.get( logTable.convertRowIndexToModel( tableRow ) );
1096 }
1097
1098 @Override
1099 public String getColumnName( int column )
1100 {
1101 switch( column )
1102 {
1103 case 0 :
1104 return "Count.";
1105 case 1 :
1106 return "Time";
1107 case 2 :
1108 return "Request Host";
1109 case 3 :
1110 return "Target Host";
1111 case 4 :
1112 return "Interface";
1113 case 5 :
1114 return "Operation";
1115 case 6 :
1116 return "Time Taken";
1117 case 7 :
1118 return "Req Sz";
1119 case 8 :
1120 return "Resp Sz";
1121 case 9 :
1122 return "Method";
1123 case 10 :
1124 return "Path";
1125 case 11 :
1126 return "Content-Type";
1127 }
1128
1129 return null;
1130 }
1131
1132 public int getRowCount()
1133 {
1134 return exchanges.size();
1135 }
1136
1137 public Object getValueAt( int rowIndex, int columnIndex )
1138 {
1139 if( rowIndex < 0 || rowIndex >= exchanges.size() )
1140 return null;
1141
1142 WsdlMonitorMessageExchange exchange = exchanges.get( rowIndex );
1143 if( exchange == null )
1144 return null;
1145
1146 switch( columnIndex )
1147 {
1148 case 0 :
1149 return rowIndex;
1150 case 1 :
1151 return sdf.format( new Date( exchange.getTimestamp() ) );
1152 case 2 :
1153 return exchange.getRequestHost();
1154 case 3 :
1155 return exchange.getTargetUrl().getHost();
1156 case 4 :
1157 return exchange.getOperation() == null ? "- unknown -" : exchange.getOperation().getInterface().getName();
1158 case 5 :
1159 return exchange.getOperation() == null ? "- unknown -" : exchange.getOperation().getName();
1160 case 6 :
1161 return String.valueOf( exchange.getTimeTaken() );
1162 case 7 :
1163 return String.valueOf( exchange.getRequestContentLength() );
1164 case 8 :
1165 return String.valueOf( exchange.getResponseContentLength() );
1166 case 9 :
1167 return String.valueOf( exchange.getRequestMethod() );
1168 case 10 :
1169 return exchange.getTargetUrl().getPath();
1170 case 11 :
1171 return String.valueOf( exchange.getResponseContentType() );
1172 }
1173
1174 return null;
1175 }
1176
1177 public synchronized void addMessageExchange( WsdlMonitorMessageExchange exchange )
1178 {
1179 exchanges.add( exchange );
1180 int size = exchanges.size();
1181 fireTableRowsInserted( size - 1, size );
1182
1183 fitSizeToMaxRows();
1184
1185 String requestHost = exchange.getRequestHost();
1186 if( requestFilterModel.getIndexOf( requestHost ) == -1 )
1187 {
1188 requestFilterModel.addElement( requestHost );
1189 }
1190
1191 String host = exchange.getTargetUrl().getHost();
1192 if( targetHostFilterModel.getIndexOf( host ) == -1 )
1193 {
1194 targetHostFilterModel.addElement( host );
1195 }
1196
1197 updateRowCountLabel();
1198 }
1199
1200 public void fitSizeToMaxRows()
1201 {
1202 int removeCnt = 0;
1203
1204 while( exchanges.size() > maxRows )
1205 {
1206 WsdlMonitorMessageExchange removed = exchanges.remove( 0 );
1207 removed.discard();
1208 removeCnt++ ;
1209 }
1210
1211 if( removeCnt > 0 )
1212 {
1213 fireTableDataChanged();
1214 updateRowCountLabel();
1215 }
1216 }
1217 }
1218
1219 protected String getHttpProxyHost()
1220 {
1221 return httpProxyHost;
1222 }
1223
1224 /***
1225 * excludes proxy headers as well as headers set for excluding in Global
1226 * Preferences/WebRecordingSettings.EXCLUDED_HEADERS
1227 *
1228 * @param requestHeaders
1229 * @return
1230 */
1231 private StringToStringsMap excludeHeaders( StringToStringsMap requestHeaders )
1232 {
1233 StringToStringsMap stsmap = new StringToStringsMap();
1234 for( String key : requestHeaders.getKeys() )
1235 {
1236 if( !( key.contains( "Proxy" ) || key.contains( "Content" ) ) && !BrowserComponent.isHeaderExcluded( key ) )
1237 {
1238 stsmap.add( key, requestHeaders.get( key, "" ) );
1239 }
1240 }
1241 return stsmap;
1242 }
1243
1244 protected void setHttpProxyHost( String proxyHost )
1245 {
1246 httpProxyHost = proxyHost;
1247 }
1248
1249 protected int getHttpProxyPort()
1250 {
1251 return httpProxyPort;
1252 }
1253
1254 protected void setHttpProxyPort( int proxyPort )
1255 {
1256 httpProxyPort = proxyPort;
1257 }
1258
1259
1260
1261
1262
1263
1264 public String getTargetHost()
1265 {
1266 String host = targetEndpoint;
1267
1268 try
1269 {
1270 URL url = new URL( host );
1271 return url.getHost();
1272 }
1273 catch( MalformedURLException e )
1274 {
1275 return host;
1276 }
1277 }
1278
1279 public String getTargetEndpoint()
1280 {
1281 return targetEndpoint;
1282 }
1283
1284 public int getTargetPort()
1285 {
1286 try
1287 {
1288 URL url = new URL( targetEndpoint );
1289 return url.getPort() == -1 ? 80 : url.getPort();
1290 }
1291 catch( MalformedURLException e )
1292 {
1293 return 80;
1294 }
1295 }
1296
1297 public int getLocalPort()
1298 {
1299 return listenPort;
1300 }
1301
1302 public synchronized void addMessageExchange( WsdlMonitorMessageExchange messageExchange )
1303 {
1304 messageExchangeStack.push( messageExchange );
1305
1306 if( !stackProcessor.isRunning() )
1307 new Thread( stackProcessor, "SoapMonitor StackProcessor for project [" + getProject().getName() + "]" )
1308 .start();
1309 }
1310
1311 private class StackProcessor implements Runnable
1312 {
1313 private boolean canceled;
1314 private boolean running;
1315
1316 public void run()
1317 {
1318 running = true;
1319 SoapUI.log.info( "Started stackprocessor for soapmonitor in project [" + getProject().getName() + "]" );
1320 while( !canceled && messageExchangeStack.size() > 0 )
1321 {
1322 WsdlMonitorMessageExchange messageExchange = messageExchangeStack.pop();
1323 if( messageExchange != null )
1324 {
1325 processMessage( messageExchange );
1326 }
1327
1328 try
1329 {
1330 Thread.sleep( 100 );
1331 }
1332 catch( InterruptedException e )
1333 {
1334 e.printStackTrace();
1335 }
1336 }
1337 running = false;
1338 }
1339
1340 private synchronized void processMessage( WsdlMonitorMessageExchange messageExchange )
1341 {
1342 messageExchange.prepare( project.getWssContainer().getIncomingWssByName( incomingRequestWss ), project
1343 .getWssContainer().getIncomingWssByName( incomingResponseWss ) );
1344
1345 tableModel.addMessageExchange( messageExchange );
1346
1347 fireOnMessageExchange( messageExchange );
1348 }
1349
1350 @SuppressWarnings( "unused" )
1351 public void cancel()
1352 {
1353 canceled = true;
1354 }
1355
1356 @SuppressWarnings( "unused" )
1357 protected boolean isCanceled()
1358 {
1359 return canceled;
1360 }
1361
1362 protected boolean isRunning()
1363 {
1364 return running;
1365 }
1366 }
1367
1368 public MonitorLogTableModel getLogModel()
1369 {
1370 return tableModel;
1371 }
1372
1373 public void addSoapMonitorListener( MonitorListener listener )
1374 {
1375 listeners.add( listener );
1376 }
1377
1378 public void removeSoapMonitorListener( MonitorListener listener )
1379 {
1380 listeners.remove( listener );
1381 }
1382
1383 public WsdlProject getProject()
1384 {
1385 return project;
1386 }
1387
1388 public class SoapMonitorOptionsAction extends AbstractAction
1389 {
1390
1391 public SoapMonitorOptionsAction()
1392 {
1393 putValue( SMALL_ICON, UISupport.createImageIcon( "/options.gif" ) );
1394 }
1395
1396 public void actionPerformed( ActionEvent e )
1397 {
1398 if( optionsDialog == null )
1399 {
1400 optionsDialog = ADialogBuilder.buildDialog( OptionsForm.class );
1401 }
1402
1403 StringList endpoints = new StringList();
1404 endpoints.add( null );
1405
1406 for( WsdlInterface iface : ModelSupport.getChildren( getProject(), WsdlInterface.class ) )
1407 {
1408 endpoints.addAll( iface.getEndpoints() );
1409 }
1410
1411 optionsDialog.setIntValue( OptionsForm.PORT, listenPort );
1412 optionsDialog.setIntValue( OptionsForm.MAXROWS, maxRows );
1413
1414 optionsDialog.setOptions( OptionsForm.REQUEST_WSS, StringUtils.merge( project.getWssContainer()
1415 .getIncomingWssNames(), "<none>" ) );
1416 optionsDialog.setOptions( OptionsForm.RESPONSE_WSS, StringUtils.merge( project.getWssContainer()
1417 .getIncomingWssNames(), "<none>" ) );
1418
1419 optionsDialog.setValue( OptionsForm.REQUEST_WSS, incomingRequestWss );
1420 optionsDialog.setValue( OptionsForm.RESPONSE_WSS, incomingResponseWss );
1421 optionsDialog.setValue( LaunchForm.SET_CONTENT_TYPES, project.getSettings().getString(
1422 LaunchForm.SET_CONTENT_TYPES, SoapMonitorAction.defaultContentTypes() ) );
1423
1424 if( optionsDialog.show() )
1425 {
1426 Settings settings = getProject().getSettings();
1427
1428 settings.setLong( OptionsForm.PORT, listenPort = optionsDialog.getIntValue( OptionsForm.PORT, listenPort ) );
1429 settings.setLong( OptionsForm.MAXROWS, maxRows = optionsDialog.getIntValue( OptionsForm.MAXROWS, maxRows ) );
1430 settings.setString( LaunchForm.SET_CONTENT_TYPES, optionsDialog.getValue( LaunchForm.SET_CONTENT_TYPES ) );
1431
1432 incomingRequestWss = optionsDialog.getValue( OptionsForm.REQUEST_WSS );
1433 incomingResponseWss = optionsDialog.getValue( OptionsForm.RESPONSE_WSS );
1434
1435 tableModel.fitSizeToMaxRows();
1436 }
1437 }
1438
1439 @AForm( name = "HTTP Monitor Options", description = "Set options for HTTP Monitor", helpUrl = HelpUrls.SOAPMONITOR_HELP_URL, icon = UISupport.OPTIONS_ICON_PATH )
1440 private class OptionsForm
1441 {
1442 @AField( description = "The local port to listen on", name = "Port", type = AFieldType.INT )
1443 public final static String PORT = "Port";
1444
1445 @AField( description = "The maximum number of exchanges to log", name = "Max Log", type = AFieldType.INT )
1446 public final static String MAXROWS = "Max Log";
1447
1448 @AField( description = "The Incoming WSS configuration to use for processing requests", name = "Incoming Request WSS", type = AFieldType.ENUMERATION )
1449 public final static String REQUEST_WSS = "Incoming Request WSS";
1450
1451 @AField( description = "The Outgoing WSS configuration to use for processing responses", name = "Incoming Response WSS", type = AFieldType.ENUMERATION )
1452 public final static String RESPONSE_WSS = "Incoming Response WSS";
1453
1454 @AField( description = "Content types to monitor", name = "Content types to monitor", type = AFieldType.STRINGAREA )
1455 public final static String SET_CONTENT_TYPES = "Content types to monitor";
1456 }
1457 }
1458
1459 public void release()
1460 {
1461 requestViewer.release();
1462 responseViewer.release();
1463
1464 if( optionsDialog != null )
1465 {
1466 optionsDialog.release();
1467 optionsDialog = null;
1468 }
1469
1470 inspectorPanel.release();
1471 }
1472
1473 public boolean isRunning()
1474 {
1475 return monitorEngine.isRunning();
1476 }
1477
1478 public void fireOnMessageExchange( WsdlMonitorMessageExchange messageExchange )
1479 {
1480 for( MonitorListener listener : listeners.get() )
1481 {
1482 try
1483 {
1484 listener.onMessageExchange( messageExchange );
1485 }
1486 catch( Throwable t )
1487 {
1488 SoapUI.logError( t );
1489 }
1490 }
1491 }
1492
1493 public void fireOnRequest( ServletRequest request, ServletResponse response )
1494 {
1495 for( MonitorListener listener : listeners.get() )
1496 {
1497 try
1498 {
1499 listener.onRequest( this, request, response );
1500 }
1501 catch( Throwable t )
1502 {
1503 SoapUI.logError( t );
1504 }
1505 }
1506 }
1507
1508 public void fireBeforeProxy( ServletRequest request, ServletResponse response, HttpMethod method,
1509 HostConfiguration hostConfiguration )
1510 {
1511 for( MonitorListener listener : listeners.get() )
1512 {
1513 try
1514 {
1515 listener.beforeProxy( this, request, response, method, hostConfiguration );
1516 }
1517 catch( Throwable t )
1518 {
1519 SoapUI.logError( t );
1520 }
1521 }
1522 }
1523
1524 public void fireAfterProxy( ServletRequest request, ServletResponse response, HttpMethod method,
1525 WsdlMonitorMessageExchange capturedData )
1526 {
1527 for( MonitorListener listener : listeners.get() )
1528 {
1529 try
1530 {
1531 listener.afterProxy( this, request, response, method, capturedData );
1532 }
1533 catch( Throwable t )
1534 {
1535 SoapUI.logError( t );
1536 }
1537 }
1538 }
1539
1540 public static class SoapUIListenerSupport<T extends Object>
1541 {
1542 private Set<T> listeners = new HashSet<T>();
1543 @SuppressWarnings( "unused" )
1544 private final Class<T> listenerClass;
1545
1546 public SoapUIListenerSupport( Class<T> listenerClass )
1547 {
1548 this.listenerClass = listenerClass;
1549 listeners.addAll( SoapUI.getListenerRegistry().getListeners( listenerClass ) );
1550 }
1551
1552 public void add( T listener )
1553 {
1554 listeners.add( listener );
1555 }
1556
1557 public void remove( T listener )
1558 {
1559 listeners.remove( listener );
1560 }
1561
1562 public Collection<T> get()
1563 {
1564 return listeners;
1565 }
1566 }
1567
1568 public MessageExchangeModelItem getRequestModelItem()
1569 {
1570 return requestModelItem;
1571 }
1572 }