1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.panels.request;
14
15 import java.awt.BorderLayout;
16 import java.awt.Component;
17 import java.awt.Dimension;
18 import java.awt.event.ActionEvent;
19 import java.awt.event.FocusAdapter;
20 import java.awt.event.FocusEvent;
21 import java.awt.event.FocusListener;
22 import java.awt.event.ItemEvent;
23 import java.awt.event.ItemListener;
24 import java.beans.PropertyChangeEvent;
25 import java.beans.PropertyChangeListener;
26 import java.security.cert.Certificate;
27
28 import javax.swing.AbstractAction;
29 import javax.swing.Action;
30 import javax.swing.BorderFactory;
31 import javax.swing.Box;
32 import javax.swing.JButton;
33 import javax.swing.JComboBox;
34 import javax.swing.JComponent;
35 import javax.swing.JEditorPane;
36 import javax.swing.JPanel;
37 import javax.swing.JPopupMenu;
38 import javax.swing.JScrollPane;
39 import javax.swing.JSeparator;
40 import javax.swing.JSplitPane;
41 import javax.swing.JTabbedPane;
42 import javax.swing.JTable;
43 import javax.swing.JToggleButton;
44 import javax.swing.JToolBar;
45 import javax.swing.SwingUtilities;
46 import javax.swing.event.ChangeEvent;
47 import javax.swing.event.ChangeListener;
48 import javax.swing.event.TableModelEvent;
49 import javax.swing.event.TableModelListener;
50 import javax.swing.text.html.HTMLEditorKit;
51
52 import org.apache.log4j.Logger;
53
54 import com.eviware.soapui.SoapUI;
55 import com.eviware.soapui.impl.wsdl.WsdlRequest;
56 import com.eviware.soapui.impl.wsdl.WsdlSubmitContext;
57 import com.eviware.soapui.impl.wsdl.actions.request.AddRequestToMockServiceAction;
58 import com.eviware.soapui.impl.wsdl.actions.request.CloneRequestAction;
59 import com.eviware.soapui.impl.wsdl.actions.request.CreateEmptyRequestAction;
60 import com.eviware.soapui.impl.wsdl.actions.request.RecreateRequestAction;
61 import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
62 import com.eviware.soapui.impl.wsdl.panels.attachments.AttachmentPanel;
63 import com.eviware.soapui.impl.wsdl.panels.request.actions.WSIValidateRequestAction;
64 import com.eviware.soapui.impl.wsdl.panels.request.components.RequestMessageXmlEditor;
65 import com.eviware.soapui.impl.wsdl.panels.request.components.RequestXmlDocument;
66 import com.eviware.soapui.impl.wsdl.panels.request.components.ResponseMessageXmlEditor;
67 import com.eviware.soapui.impl.wsdl.panels.request.components.ResponseXmlDocument;
68 import com.eviware.soapui.impl.wsdl.panels.request.components.SoapMessageXmlEditor;
69 import com.eviware.soapui.impl.wsdl.panels.request.components.editor.XmlDocument;
70 import com.eviware.soapui.impl.wsdl.panels.request.components.editor.views.source.XmlSourceEditorView;
71 import com.eviware.soapui.impl.wsdl.panels.support.EndpointsComboBoxModel;
72 import com.eviware.soapui.impl.wsdl.submit.transports.http.SSLInfo;
73 import com.eviware.soapui.impl.wsdl.submit.transports.http.WsdlResponse;
74 import com.eviware.soapui.impl.wsdl.support.HelpUrls;
75 import com.eviware.soapui.model.ModelItem;
76 import com.eviware.soapui.model.iface.Submit;
77 import com.eviware.soapui.model.iface.SubmitContext;
78 import com.eviware.soapui.model.iface.SubmitListener;
79 import com.eviware.soapui.model.iface.Request.SubmitException;
80 import com.eviware.soapui.model.iface.Submit.Status;
81 import com.eviware.soapui.settings.UISettings;
82 import com.eviware.soapui.support.UISupport;
83 import com.eviware.soapui.support.action.swing.SwingActionDelegate;
84 import com.eviware.soapui.support.actions.ChangeSplitPaneOrientationAction;
85 import com.eviware.soapui.support.components.JEditorStatusBarWithProgress;
86 import com.eviware.soapui.support.components.JXToolBar;
87 import com.eviware.soapui.support.swing.SoapUISplitPaneUI;
88 import com.eviware.soapui.support.types.StringToStringMap;
89 import com.eviware.soapui.support.xml.JXEditTextArea;
90 import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
91
92 /***
93 * Abstract DesktopPanel for WsdlRequests
94 *
95 * @author Ole.Matzura
96 */
97
98 public class AbstractWsdlRequestDesktopPanel<T extends ModelItem, T2 extends WsdlRequest> extends ModelItemDesktopPanel<T>
99 {
100 private final static Logger log = Logger.getLogger(AbstractWsdlRequestDesktopPanel.class);
101
102 private JComboBox endpointCombo;
103 private JButton submitButton;
104 private JButton cancelButton;
105 private EndpointsComboBoxModel endpointsModel;
106 private JEditorStatusBarWithProgress statusBar;
107 private JButton splitButton;
108 private Submit submit;
109 private JButton recreateButton;
110 private JButton cloneButton;
111 private JButton createEmptyButton;
112 private InternalSubmitListener internalSubmitListener;
113 private JSplitPane requestSplitPane;
114 private MoveFocusAction moveFocusAction;
115 private ClosePanelAction closePanelAction = new ClosePanelAction();
116 private T2 request;
117
118 private SoapMessageXmlEditor requestEditor;
119 private SoapMessageXmlEditor responseEditor;
120
121
122
123 private JTabbedPane requestTabs;
124 private JPanel requestTabPanel;
125 private JToggleButton tabsButton;
126
127 public boolean responseHasFocus;
128
129 private JTabbedPane requestEditorTabs;
130 private JTabbedPane responseEditorTabs;
131
132 private JPanel requestEditorTabPanel;
133 private JPanel responseEditorTabPanel;
134 private AttachmentPropertyChangeListener attachmentsPropertyChangeListener = new AttachmentPropertyChangeListener();
135 private StringToStringMapTableModel requestHeadersModel;
136 private JTable requestHeadersTable;
137 private StringToStringMapTableModel responseHeadersModel;
138
139 private JEditorPane sslInfoPane;
140 private JButton addToMockServiceButton;
141
142
143
144
145 private AbstractAction wsiValidateAction;
146
147 private AttachmentPanel requestAttachmentPanel;
148 private AttachmentPanel responseAttachmentPanel;
149
150 public AbstractWsdlRequestDesktopPanel(T modelItem)
151 {
152 super(modelItem);
153 }
154
155 protected void init(T2 request)
156 {
157 this.request = request;
158
159 this.endpointsModel = new EndpointsComboBoxModel(request);
160 internalSubmitListener = createSubmitListener();
161
162 request.addSubmitListener(internalSubmitListener);
163
164 add(buildContent(), BorderLayout.CENTER);
165 add(buildToolbar(), BorderLayout.NORTH);
166 add(buildStatusLabel(), BorderLayout.SOUTH);
167
168 setPreferredSize(new Dimension(600, 500));
169
170 request.addPropertyChangeListener( attachmentsPropertyChangeListener );
171
172 addFocusListener( new FocusAdapter() {
173
174 @Override
175 public void focusGained( FocusEvent e )
176 {
177 if( requestTabs.getSelectedIndex() == 1 || responseHasFocus )
178 responseEditor.requestFocusInWindow();
179 else
180 requestEditor.requestFocusInWindow();
181 }} );
182 }
183
184 protected InternalSubmitListener createSubmitListener()
185 {
186 return new InternalSubmitListener();
187 }
188
189 public final T2 getRequest()
190 {
191 return request;
192 }
193
194 public final SoapMessageXmlEditor getRequestEditor()
195 {
196 return requestEditor;
197 }
198
199 public final SoapMessageXmlEditor getResponseEditor()
200 {
201 return responseEditor;
202 }
203
204 public Submit getSubmit()
205 {
206 return submit;
207 }
208
209 protected JComponent buildStatusLabel()
210 {
211 statusBar = new JEditorStatusBarWithProgress();
212 statusBar.setBorder( BorderFactory.createEmptyBorder( 1, 0, 0, 0 ));
213
214 return statusBar;
215 }
216
217 public JEditorStatusBarWithProgress getStatusBar()
218 {
219 return statusBar;
220 }
221
222 @SuppressWarnings("unchecked")
223 protected JComponent buildContent()
224 {
225 requestSplitPane = UISupport.createHorizontalSplit();
226 requestSplitPane.setResizeWeight(0.5);
227 requestSplitPane.setBorder(null);
228
229 submitButton = createActionButton(new SubmitAction(), true);
230 cancelButton = createActionButton(new CancelAction(), false);
231 splitButton = createActionButton(new ChangeSplitPaneOrientationAction(requestSplitPane), true);
232
233 tabsButton = new JToggleButton( new ChangeToTabsAction() );
234 tabsButton.setPreferredSize( UISupport.TOOLBAR_BUTTON_DIMENSION );
235
236 recreateButton = createActionButton(new RecreateRequestAction(request), true);
237 addToMockServiceButton = createActionButton(
238 SwingActionDelegate.createDelegate( AddRequestToMockServiceAction.SOAPUI_ACTION_ID, request, null, "/addToMockService.gif" ), true );
239
240 cloneButton = createActionButton(
241 SwingActionDelegate.createDelegate( CloneRequestAction.SOAPUI_ACTION_ID, request, null, "/clone_request.gif" ), true );
242
243 createEmptyButton = createActionButton(new CreateEmptyRequestAction(request), true);
244
245 submitButton.setEnabled(request.getEndpoint() != null && request.getEndpoint().trim().length() > 0);
246 wsiValidateAction =
247 SwingActionDelegate.createDelegate( new WSIValidateRequestAction(), request, "alt W" );
248 wsiValidateAction.setEnabled( request.getResponse() != null );
249
250 moveFocusAction = new MoveFocusAction();
251
252 requestEditor = buildRequestEditor();
253 responseEditor = buildResponseEditor();
254
255 requestEditorTabs = new JTabbedPane( JTabbedPane.BOTTOM );
256 requestEditorTabs.setTabLayoutPolicy( JTabbedPane.SCROLL_TAB_LAYOUT );
257 requestEditorTabs.addTab( "SOAP Request", requestEditor );
258 requestAttachmentPanel = new AttachmentPanel( request, true );
259 requestEditorTabs.addTab( "Request Attachments (" + request.getAttachmentCount() + ")"
260 , requestAttachmentPanel);
261 requestEditorTabs.addTab( "HTTP Headers (" + request.getRequestHeaders().size() + ")", createRequestHttpHeadersPanel() );
262 requestEditorTabs.addChangeListener( new ChangeListener() {
263
264 public void stateChanged( ChangeEvent e )
265 {
266 SwingUtilities.invokeLater( new Runnable() {
267
268 public void run()
269 {
270 int ix = requestEditorTabs.getSelectedIndex();
271 if( ix == 0 )
272 requestEditor.requestFocus();
273 }} );
274
275 }} );
276
277 responseEditorTabs = new JTabbedPane( JTabbedPane.BOTTOM );
278 responseEditorTabs.setTabLayoutPolicy( JTabbedPane.SCROLL_TAB_LAYOUT );
279 responseEditorTabs.addTab( "SOAP Response", responseEditor );
280 responseAttachmentPanel = new AttachmentPanel( request, false );
281 responseEditorTabs.addTab( "Response Attachments (" + (request.getResponse() == null ? 0 :
282 request.getResponse().getAttachments().length) + ")", responseAttachmentPanel);
283 responseEditorTabs.addTab( "HTTP Headers", createResponseHttpHeadersPanel() );
284 String sslInfoTabTitle = "SSL Info";
285 if( request.getResponse() != null && ((WsdlResponse)request.getResponse()).getSSLInfo() != null )
286 sslInfoTabTitle += " (" + ((WsdlResponse)request.getResponse()).getSSLInfo().getPeerCertificates().length + " certs)";
287 else
288 sslInfoTabTitle += " (-)";
289
290 responseEditorTabs.addTab( sslInfoTabTitle, createSSLInfoPanel() );
291 responseEditorTabs.addChangeListener( new ChangeListener() {
292
293 public void stateChanged( ChangeEvent e )
294 {
295 SwingUtilities.invokeLater( new Runnable() {
296
297 public void run()
298 {
299 int ix = responseEditorTabs.getSelectedIndex();
300 if( ix == 0 )
301 responseEditor.requestFocus();
302 }} );
303
304 }} );
305
306 requestTabs = new JTabbedPane();
307 requestTabs.addChangeListener( new ChangeListener() {
308
309 public void stateChanged( ChangeEvent e )
310 {
311 SwingUtilities.invokeLater( new Runnable() {
312
313 public void run()
314 {
315 int ix = requestTabs.getSelectedIndex();
316 if( ix == 0 && requestEditorTabs.getSelectedIndex() == 0 )
317 requestEditor.requestFocus();
318 else if( ix == 1 && responseEditorTabs.getSelectedIndex() == 0 )
319 responseEditor.requestFocus();
320 }} );
321 }} );
322
323 requestTabPanel = UISupport.createTabPanel( requestTabs, true );
324
325 requestEditorTabPanel = UISupport.createTabPanel(requestEditorTabs, false);
326 responseEditorTabPanel = UISupport.createTabPanel(responseEditorTabs, false);
327
328 if( request.getSettings().getBoolean( UISettings.START_WITH_REQUEST_TABS ))
329 {
330 requestTabs.addTab( "Request", requestEditorTabPanel );
331 requestTabs.addTab( "Response", responseEditorTabPanel );
332 splitButton.setEnabled( false );
333 tabsButton.setSelected( true );
334
335 return requestTabPanel;
336 }
337 else
338 {
339 requestSplitPane.setTopComponent(requestEditorTabPanel);
340 requestSplitPane.setBottomComponent(responseEditorTabPanel);
341 requestSplitPane.setDividerLocation(0.5);
342 return requestSplitPane;
343 }
344 }
345
346 private Component createSSLInfoPanel()
347 {
348 JPanel panel = new JPanel( new BorderLayout());
349
350 sslInfoPane = new JEditorPane();
351 sslInfoPane.setEditorKit( new HTMLEditorKit() );
352 panel.add( new JScrollPane( sslInfoPane ));
353
354 return panel;
355 }
356
357 private void updateSSLInfo( SSLInfo sslInfo )
358 {
359 String sslInfoTabTitle = "SSL Info";
360
361 if( sslInfo == null )
362 {
363 sslInfoPane.setText( "<html><body>Not an SSL connection</body></html>" );
364 sslInfoTabTitle += " (-)";
365 }
366 else
367 {
368 StringBuffer buf = new StringBuffer( "<html><body><table cellpadding=1 cellspacing=1 border=0>" );
369
370 buf.append( "<tr><td><b>CipherSuite:</b></td><td align=left valign=top>" ).
371 append( sslInfo.getCipherSuite().toString() ).append( "</td></tr>");
372
373 if( sslInfo.getLocalPrincipal() != null )
374 buf.append( "<tr><td><b>LocalPrincipal:</b></td><td align=left valign=top>" ).
375 append( sslInfo.getLocalPrincipal().getName() ).append( "</td></tr>");
376
377 Certificate[] localCertificates = sslInfo.getLocalCertificates();
378
379 if( localCertificates != null)
380 {
381 buf.append( "</table><table cellpadding=0 cellspacing=0 border=0>" );
382
383 int cnt = 1;
384 for( Certificate cert : localCertificates )
385 {
386 buf.append( "<tr><td><b>Local Certificate " ).append( cnt++ ).
387 append( ":</b><pre><font size=-1>" ).
388 append( cert.toString() ).append( "</font></pre></td></tr>");
389
390 }
391
392 buf.append( "</table><table cellpadding=1 cellspacing=1 border=0>" );
393 }
394
395 if( sslInfo.getPeerPrincipal() != null )
396 buf.append( "<tr><td><b>PeerPrincipal:</b></td><td align=left valign=top>" ).
397 append( sslInfo.getPeerPrincipal().toString() ).append( "</td></tr>");
398
399 Certificate[] peerCertificates = sslInfo.getPeerCertificates();
400 if( peerCertificates != null)
401 {
402 buf.append( "</table><table cellpadding=0 cellspacing=0 border=0>" );
403
404 int cnt = 1;
405 for( Certificate cert : peerCertificates )
406 {
407 buf.append( "<tr><td colspan=2><b>Peer Certificate " ).append( cnt++ ).
408 append( ":</b><pre><font size=-1>" ).
409 append( cert.toString() ).append( "</font></pre></td></tr>");
410 }
411
412 buf.append( "</table><table cellpadding=0 cellspacing=0 border=0>" );
413 }
414
415 buf.append( "</table></body></html>" );
416 sslInfoPane.setText( buf.toString() );
417
418 sslInfoTabTitle += " (" + sslInfo.getPeerCertificates().length + " certs)";
419 }
420
421 responseEditorTabs.setTitleAt( 3, sslInfoTabTitle );
422 }
423
424 private Component createResponseHttpHeadersPanel()
425 {
426 responseHeadersModel = new StringToStringMapTableModel(
427 request.getResponse() == null ? new StringToStringMap() :
428 request.getResponse().getResponseHeaders(), "Header", "Value", false );
429
430 responseHeadersModel.addTableModelListener( new TableModelListener()
431 {
432 public void tableChanged( TableModelEvent arg0 )
433 {
434 responseEditorTabs.setTitleAt( 2, "HTTP Headers (" + responseHeadersModel.getRowCount() + ")");
435 }} );
436
437 JTable responseHeadersTable = new JTable( responseHeadersModel );
438 return new JScrollPane( responseHeadersTable );
439 }
440
441 private Component createRequestHttpHeadersPanel()
442 {
443 requestHeadersModel = new StringToStringMapTableModel( request.getRequestHeaders(), "Header", "Value", true );
444 requestHeadersModel.addTableModelListener( new TableModelListener()
445 {
446 public void tableChanged( TableModelEvent arg0 )
447 {
448 getRequest().setRequestHeaders( requestHeadersModel.getData() );
449 requestEditorTabs.setTitleAt( 2, "HTTP Headers (" + requestHeadersModel.getRowCount() + ")");
450 }} );
451
452 requestHeadersTable = new JTable( requestHeadersModel );
453 JPanel panel = new JPanel( new BorderLayout() );
454
455 panel.add( new JScrollPane( requestHeadersTable ), BorderLayout.CENTER );
456
457 JXToolBar builder = UISupport.createToolbar();
458 builder.addFixed( new JButton( new AbstractAction( "Add" ) {
459
460 public void actionPerformed( ActionEvent arg0 )
461 {
462 Object header = UISupport.prompt( "Specify name of header to add", "Add HTTP Header", "" );
463 if( header != null )
464 {
465 requestHeadersModel.add( header.toString(), "" );
466 }
467 }} ));
468 builder.addRelatedGap();
469 builder.addFixed( new JButton( new AbstractAction("Remove" ){
470
471 public void actionPerformed( ActionEvent arg0 )
472 {
473 int row = requestHeadersTable.getSelectedRow();
474 if( row != -1 && UISupport.confirm( "Delete selected header?", "Remove Header" ) )
475 {
476 requestHeadersModel.remove( row );
477 }
478 }} ));
479
480
481
482 builder.addGlue();
483 builder.addFixed( UISupport.createToolbarButton( new ShowOnlineHelpAction(HelpUrls.HEADERS_HELP_URL)));
484
485 panel.add( builder, BorderLayout.SOUTH );
486
487 return panel;
488 }
489
490 protected SoapMessageXmlEditor buildResponseEditor()
491 {
492 return new WsdlResponseMessageEditor( new ResponseXmlDocument( request ));
493 }
494
495 protected SoapMessageXmlEditor buildRequestEditor()
496 {
497 return new WsdlRequestMessageEditor( new RequestXmlDocument( request ));
498 }
499
500 protected JComponent buildToolbar()
501 {
502 endpointCombo = new JComboBox(endpointsModel);
503 endpointCombo.setToolTipText(endpointsModel.getSelectedItem().toString());
504
505 endpointCombo.addItemListener(new ItemListener()
506 {
507 public void itemStateChanged(ItemEvent e)
508 {
509 Object item = endpointCombo.getSelectedItem();
510 if (item == null)
511 {
512 endpointCombo.setToolTipText("- no endpoint set for request -");
513 }
514 else
515 {
516 String selectedItem = item.toString();
517 endpointCombo.setToolTipText(selectedItem);
518 }
519
520 submitButton.setEnabled(submit == null && request.getEndpoint() != null
521 && request.getEndpoint().trim().length() > 0);
522 }
523 });
524
525 JXToolBar toolbar = UISupport.createToolbar();
526
527 toolbar.add( submitButton );
528 insertButtons( toolbar );
529
530 toolbar.add( addToMockServiceButton);
531
532
533 toolbar.add(recreateButton);
534 toolbar.add(createEmptyButton);
535 toolbar.add(cloneButton);
536 toolbar.add(cancelButton);
537 toolbar.addSeparator();
538 toolbar.add(endpointCombo);
539
540 toolbar.add( Box.createHorizontalGlue() );
541 toolbar.add( tabsButton );
542 toolbar.add(splitButton);
543 toolbar.add(UISupport.createToolbarButton(new ShowOnlineHelpAction(getHelpUrl())));
544
545 return toolbar;
546 }
547
548 protected String getHelpUrl()
549 {
550 return HelpUrls.REQUESTEDITOR_HELP_URL;
551 }
552
553 protected void insertButtons(JToolBar toolbar)
554 {
555 }
556
557 public void setEnabled(boolean enabled)
558 {
559 endpointCombo.setEnabled(enabled);
560 requestEditor.setEditable(enabled);
561 responseEditor.setEditable(enabled);
562
563 submitButton.setEnabled(enabled && request.getEndpoint() != null
564 && request.getEndpoint().trim().length() > 0);
565 recreateButton.setEnabled(enabled);
566 createEmptyButton.setEnabled(enabled);
567 cloneButton.setEnabled(enabled);
568
569 statusBar.setIndeterminate( !enabled );
570 }
571
572 private final class AttachmentPropertyChangeListener implements PropertyChangeListener
573 {
574 public void propertyChange(PropertyChangeEvent evt)
575 {
576 if( evt.getPropertyName().equals( WsdlRequest.ATTACHMENTS_PROPERTY ))
577 {
578 requestEditorTabs.setTitleAt( 1, "Request Attachments (" + request.getAttachmentCount() + ")");
579 }
580 else if( evt.getPropertyName().equals( WsdlRequest.RESPONSE_PROPERTY ))
581 {
582 responseEditorTabs.setTitleAt( 1, "Response Attachments (" + (request.getResponse() == null ? 0 :
583 request.getResponse().getAttachments().length) + ")" );
584 }
585 else if( evt.getPropertyName().equals( WsdlRequest.REQUEST_HEADERS_PROPERTY ))
586 {
587 requestHeadersModel.setData( ( StringToStringMap ) evt.getNewValue() );
588 }
589 }
590 }
591
592 public class WsdlRequestMessageEditor extends RequestMessageXmlEditor<WsdlRequest>
593 {
594 private InputAreaFocusListener inputAreaFocusListener;
595 private JXEditTextArea inputArea;
596
597 public WsdlRequestMessageEditor(XmlDocument document)
598 {
599 super(document, request );
600
601 XmlSourceEditorView editor = getSourceEditor();
602 inputArea = editor.getInputArea();
603 inputArea.getInputHandler().addKeyBinding("A+ENTER", submitButton.getAction());
604 inputArea.getInputHandler().addKeyBinding("A+X", cancelButton.getAction());
605 inputArea.getInputHandler().addKeyBinding("AC+TAB", moveFocusAction);
606 inputArea.getInputHandler().addKeyBinding("F5", recreateButton.getAction());
607 inputArea.getInputHandler().addKeyBinding("C+F4", closePanelAction);
608
609 inputAreaFocusListener = new InputAreaFocusListener();
610 inputArea.addFocusListener( inputAreaFocusListener);
611 }
612
613 @Override
614 public void release()
615 {
616 super.release();
617 inputArea.removeFocusListener( inputAreaFocusListener );
618 }
619 }
620
621 public class WsdlResponseMessageEditor extends ResponseMessageXmlEditor<WsdlRequest>
622 {
623 private JXEditTextArea inputArea;
624 private ResultAreaFocusListener resultAreaFocusListener;
625
626 public WsdlResponseMessageEditor(XmlDocument document)
627 {
628 super(document, request );
629
630 XmlSourceEditorView editor = getSourceEditor();
631
632 inputArea = editor.getInputArea();
633 resultAreaFocusListener = new ResultAreaFocusListener();
634 inputArea.addFocusListener(resultAreaFocusListener);
635
636 inputArea.getInputHandler().addKeyBinding("A+ENTER", submitButton.getAction());
637 inputArea.getInputHandler().addKeyBinding("A+X", cancelButton.getAction());
638 inputArea.getInputHandler().addKeyBinding("AC+TAB", moveFocusAction);
639 inputArea.getInputHandler().addKeyBinding("C+F4", closePanelAction);
640
641 JPopupMenu inputPopup = editor.getEditorPopup();
642 inputPopup.insert( new JSeparator(), 2 );
643 inputPopup.insert( wsiValidateAction, 3 );
644 }
645
646 @Override
647 public void release()
648 {
649 super.release();
650
651 inputArea.removeFocusListener( resultAreaFocusListener );
652 }
653 }
654
655 protected final class InputAreaFocusListener implements FocusListener
656 {
657 public void focusGained(FocusEvent e)
658 {
659 responseHasFocus = false;
660
661 statusBar.setTarget( requestEditor.getSourceEditor().getInputArea() );
662 if( !splitButton.isEnabled() )
663 {
664 requestTabs.setSelectedIndex( 0 );
665 return;
666 }
667
668 if (getModelItem().getSettings().getBoolean(UISettings.NO_RESIZE_REQUEST_EDITOR))
669 return;
670
671
672 if (((SoapUISplitPaneUI) requestSplitPane.getUI()).hasBeenDragged())
673 return;
674
675 int pos = requestSplitPane.getDividerLocation();
676 if (pos >= 600)
677 return;
678 if (requestSplitPane.getMaximumDividerLocation() > 700)
679 requestSplitPane.setDividerLocation(600);
680 else
681 requestSplitPane.setDividerLocation(0.8);
682 }
683
684 public void focusLost(FocusEvent e)
685 {
686 }
687 }
688
689 protected final class ResultAreaFocusListener implements FocusListener
690 {
691 public void focusGained(FocusEvent e)
692 {
693 responseHasFocus = true;
694
695 statusBar.setTarget( responseEditor.getSourceEditor().getInputArea() );
696 if( !splitButton.isEnabled() )
697 {
698 requestTabs.setSelectedIndex( 1 );
699 return;
700 }
701
702 if (request.getSettings().getBoolean(UISettings.NO_RESIZE_REQUEST_EDITOR))
703 return;
704
705
706 if (((SoapUISplitPaneUI) requestSplitPane.getUI()).hasBeenDragged() || request.getResponse() == null)
707 return;
708
709 int pos = requestSplitPane.getDividerLocation();
710 int maximumDividerLocation = requestSplitPane.getMaximumDividerLocation();
711 if (pos + 600 < maximumDividerLocation)
712 return;
713
714 if (maximumDividerLocation > 700)
715 requestSplitPane.setDividerLocation(maximumDividerLocation - 600);
716 else
717 requestSplitPane.setDividerLocation(0.2);
718 }
719
720 public void focusLost(FocusEvent e)
721 {
722 }
723 }
724
725 public class SubmitAction extends AbstractAction
726 {
727 public SubmitAction()
728 {
729 putValue(Action.SMALL_ICON, UISupport.createImageIcon("/submit_request.gif"));
730 putValue(Action.SHORT_DESCRIPTION, "Submit request to specified endpoint URL");
731 putValue(Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "alt ENTER" ));
732 }
733
734 public void actionPerformed(ActionEvent e)
735 {
736 if (submit != null && submit.getStatus() == Submit.Status.RUNNING)
737 {
738 if (UISupport.confirm("Cancel current request?", "Submit Request"))
739 {
740 submit.cancel();
741 }
742 else
743 return;
744 }
745
746 try
747 {
748 submit = doSubmit();
749 }
750 catch (SubmitException e1)
751 {
752 SoapUI.logError( e1 );
753 }
754 }
755 }
756
757 protected Submit doSubmit() throws SubmitException
758 {
759 return request.submit(new WsdlSubmitContext(null), true);
760 }
761
762 private class CancelAction extends AbstractAction
763 {
764 public CancelAction()
765 {
766 super();
767 putValue(Action.SMALL_ICON, UISupport.createImageIcon("/cancel_request.gif"));
768 putValue(Action.SHORT_DESCRIPTION, "Aborts ongoing request");
769 putValue(Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "alt X" ));
770 }
771
772 public void actionPerformed(ActionEvent e)
773 {
774 if (submit == null)
775 return;
776
777 cancelButton.setEnabled(false);
778 submit.cancel();
779 setEnabled(true);
780 submit = null;
781 }
782 }
783
784 private class ClosePanelAction extends AbstractAction
785 {
786 public void actionPerformed(ActionEvent e)
787 {
788 SoapUI.getDesktop().closeDesktopPanel(getModelItem());
789 }
790 }
791
792 private class MoveFocusAction extends AbstractAction
793 {
794 public void actionPerformed(ActionEvent e)
795 {
796 if (requestEditor.hasFocus())
797 {
798 responseEditor.requestFocus();
799 }
800 else
801 {
802 requestEditor.requestFocus();
803 }
804 }
805 }
806
807 protected class InternalSubmitListener implements SubmitListener
808 {
809 protected InternalSubmitListener()
810 {
811 }
812
813 public boolean beforeSubmit(Submit submit, SubmitContext context)
814 {
815 if (submit.getRequest() != request )
816 return true;
817
818 if( getModelItem().getSettings().getBoolean( UISettings.AUTO_VALIDATE_REQUEST ))
819 {
820 boolean result = requestEditor.saveDocument( true );
821 if( !result && getModelItem().getSettings().getBoolean( UISettings.ABORT_ON_INVALID_REQUEST ))
822 {
823 statusBar.setInfo( "Cancelled request due to invalid content" );
824 return false;
825 }
826 }
827 else requestEditor.saveDocument( false );
828
829 setEnabled( false );
830 cancelButton.setEnabled( AbstractWsdlRequestDesktopPanel.this.submit != null );
831 wsiValidateAction.setEnabled( false );
832 return true;
833 }
834
835 public void afterSubmit(Submit submit, SubmitContext context)
836 {
837 if (submit.getRequest() != request )
838 return;
839
840 Status status = submit.getStatus();
841 WsdlResponse response = (WsdlResponse) submit.getResponse();
842 if (status != Status.CANCELED )
843 {
844 request.setResponse(response, context);
845 }
846
847 cancelButton.setEnabled(false);
848 wsiValidateAction.setEnabled( request.getResponse() != null );
849 setEnabled(true);
850
851 String message = null;
852 String infoMessage = null;
853 String requestName = request.getOperation().getInterface().getName() + "."
854 + request.getOperation().getName() + ":" + request.getName();
855
856 if (status == Status.CANCELED)
857 {
858 message = "CANCELED";
859 infoMessage = "[" + requestName + "] - CANCELED";
860 }
861 else
862 {
863 if (status == Status.ERROR || response == null)
864 {
865 message = "Error getting response; " + submit.getError();
866 infoMessage = "Error getting response for [" + requestName + "]; " + submit.getError();
867 }
868 else
869 {
870 message = "response time: " + response.getTimeTaken() + "ms (" + response.getContentLength() + " bytes)";
871 infoMessage = "Got response for [" + requestName + "] in " + response.getTimeTaken() + "ms ("
872 + response.getContentLength() + " bytes)";
873
874 if( !splitButton.isEnabled() )
875 requestTabs.setSelectedIndex( 1 );
876
877 responseEditor.requestFocus();
878 }
879
880 responseHeadersModel.setData( submit.getResponse() == null ? null : submit.getResponse().getResponseHeaders());
881
882 updateSSLInfo( response == null ? null : response.getSSLInfo() );
883 wsiValidateAction.setEnabled( true );
884 }
885
886 logMessages(message, infoMessage);
887
888 if( getModelItem().getSettings().getBoolean( UISettings.AUTO_VALIDATE_RESPONSE ))
889 responseEditor.getSourceEditor().validate();
890
891 AbstractWsdlRequestDesktopPanel.this.submit = null;
892 }
893
894 protected void logMessages(String message, String infoMessage)
895 {
896 log.info(infoMessage);
897 statusBar.setInfo(message);
898 }
899 }
900
901 public boolean onClose(boolean canCancel)
902 {
903 if (canCancel)
904 {
905 if (submit != null && submit.getStatus() == Submit.Status.RUNNING)
906 {
907 Boolean retVal = UISupport.confirmOrCancel("Cancel request before closing?", "Closing window");
908 if (retVal == null)
909 return false;
910
911 if (retVal.booleanValue() && submit.getStatus() == Submit.Status.RUNNING)
912 submit.cancel();
913 }
914 }
915 else if (submit != null && submit.getStatus() == Submit.Status.RUNNING)
916 {
917 submit.cancel();
918 }
919
920 request.removeSubmitListener( internalSubmitListener );
921 request.removePropertyChangeListener( attachmentsPropertyChangeListener );
922 endpointsModel.release();
923
924 requestEditor.saveDocument( false );
925 requestEditor.release();
926 responseEditor.release();
927
928 requestAttachmentPanel.release();
929 responseAttachmentPanel.release();
930
931 responseEditor.getParent().remove( responseEditor );
932 responseEditorTabs.removeAll();
933 requestEditor.getParent().remove( requestEditor );
934 requestEditorTabs.removeAll();
935 requestSplitPane.removeAll();
936 sslInfoPane.getParent().remove( sslInfoPane );
937
938 return super.release();
939 }
940
941 public boolean dependsOn(ModelItem modelItem)
942 {
943 return modelItem == request || modelItem == request.getOperation()
944 || modelItem == request.getOperation().getInterface()
945 || modelItem == request.getOperation().getInterface().getProject();
946 }
947
948 public String getDescription()
949 {
950 return "Request: [" + request.getName() + "] - " + request.getOperation().getInterface().getName() +
951 "#" + request.getOperation().getName();
952 }
953
954 private final class ChangeToTabsAction extends AbstractAction
955 {
956 public ChangeToTabsAction()
957 {
958 putValue(Action.SMALL_ICON, UISupport.createImageIcon("/toggle_tabs.gif"));
959 putValue(Action.SHORT_DESCRIPTION, "Toggles to tab-based layout");
960 }
961
962 public void actionPerformed(ActionEvent e)
963 {
964 if( splitButton.isEnabled() )
965 {
966 splitButton.setEnabled( false );
967 removeContent( requestSplitPane );
968 setContent( requestTabPanel );
969 requestTabs.addTab( "Request", requestEditorTabPanel );
970 requestTabs.addTab( "Response", responseEditorTabPanel );
971
972 if( responseHasFocus )
973 {
974 requestTabs.setSelectedIndex( 1 );
975 requestEditorTabs.requestFocus();
976 }
977 else
978 {
979 responseEditorTabs.requestFocus();
980 }
981 }
982 else
983 {
984 int selectedIndex = requestTabs.getSelectedIndex();
985
986 splitButton.setEnabled( true );
987 removeContent( requestTabPanel );
988 setContent( requestSplitPane );
989 requestSplitPane.setTopComponent(requestEditorTabPanel);
990 requestSplitPane.setBottomComponent(responseEditorTabPanel);
991 requestSplitPane.setDividerLocation(0.5);
992
993 if( selectedIndex == 0 )
994 requestEditor.requestFocus();
995 else
996 responseEditor.requestFocus();
997 }
998
999 revalidate();
1000 }
1001 }
1002
1003 public void setContent(JComponent content)
1004 {
1005 add( content, BorderLayout.CENTER );
1006 }
1007
1008 public void removeContent(JComponent content)
1009 {
1010 remove( content );
1011 }
1012 }