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.request;
14  
15  import java.awt.BorderLayout;
16  import java.awt.Dimension;
17  import java.awt.event.ActionEvent;
18  import java.awt.event.FocusAdapter;
19  import java.awt.event.FocusEvent;
20  import java.awt.event.FocusListener;
21  import java.awt.event.ItemEvent;
22  import java.awt.event.ItemListener;
23  
24  import javax.swing.AbstractAction;
25  import javax.swing.Action;
26  import javax.swing.BorderFactory;
27  import javax.swing.Box;
28  import javax.swing.JButton;
29  import javax.swing.JComboBox;
30  import javax.swing.JComponent;
31  import javax.swing.JPanel;
32  import javax.swing.JPopupMenu;
33  import javax.swing.JSeparator;
34  import javax.swing.JSplitPane;
35  import javax.swing.JTabbedPane;
36  import javax.swing.JToggleButton;
37  import javax.swing.JToolBar;
38  import javax.swing.SwingUtilities;
39  import javax.swing.event.ChangeEvent;
40  import javax.swing.event.ChangeListener;
41  
42  import org.apache.log4j.Logger;
43  
44  import com.eviware.soapui.SoapUI;
45  import com.eviware.soapui.impl.wsdl.WsdlRequest;
46  import com.eviware.soapui.impl.wsdl.WsdlSubmitContext;
47  import com.eviware.soapui.impl.wsdl.actions.request.AddRequestToMockServiceAction;
48  import com.eviware.soapui.impl.wsdl.actions.request.CloneRequestAction;
49  import com.eviware.soapui.impl.wsdl.actions.request.CreateEmptyRequestAction;
50  import com.eviware.soapui.impl.wsdl.actions.request.RecreateRequestAction;
51  import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
52  import com.eviware.soapui.impl.wsdl.panels.request.actions.WSIValidateRequestAction;
53  import com.eviware.soapui.impl.wsdl.panels.request.components.RequestMessageXmlEditor;
54  import com.eviware.soapui.impl.wsdl.panels.request.components.RequestXmlDocument;
55  import com.eviware.soapui.impl.wsdl.panels.request.components.ResponseMessageXmlEditor;
56  import com.eviware.soapui.impl.wsdl.panels.request.components.ResponseXmlDocument;
57  import com.eviware.soapui.impl.wsdl.panels.request.components.SoapMessageXmlEditor;
58  import com.eviware.soapui.impl.wsdl.panels.request.components.editor.XmlDocument;
59  import com.eviware.soapui.impl.wsdl.panels.request.components.editor.support.DefaultXmlDocument;
60  import com.eviware.soapui.impl.wsdl.panels.request.components.editor.views.source.XmlSourceEditorView;
61  import com.eviware.soapui.impl.wsdl.panels.support.EndpointsComboBoxModel;
62  import com.eviware.soapui.impl.wsdl.submit.transports.http.WsdlResponse;
63  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
64  import com.eviware.soapui.model.ModelItem;
65  import com.eviware.soapui.model.iface.Submit;
66  import com.eviware.soapui.model.iface.SubmitContext;
67  import com.eviware.soapui.model.iface.SubmitListener;
68  import com.eviware.soapui.model.iface.Request.SubmitException;
69  import com.eviware.soapui.model.iface.Submit.Status;
70  import com.eviware.soapui.settings.UISettings;
71  import com.eviware.soapui.support.UISupport;
72  import com.eviware.soapui.support.action.swing.SwingActionDelegate;
73  import com.eviware.soapui.support.actions.ChangeSplitPaneOrientationAction;
74  import com.eviware.soapui.support.components.JEditorStatusBarWithProgress;
75  import com.eviware.soapui.support.components.JXToolBar;
76  import com.eviware.soapui.support.swing.SoapUISplitPaneUI;
77  import com.eviware.soapui.support.xml.JXEditTextArea;
78  import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
79  
80  /***
81   * Abstract DesktopPanel for WsdlRequests
82   * 
83   * @author Ole.Matzura
84   */
85  
86  public class AbstractWsdlRequestDesktopPanel<T extends ModelItem, T2 extends WsdlRequest> extends ModelItemDesktopPanel<T>
87  {
88  	private final static Logger log = Logger.getLogger(AbstractWsdlRequestDesktopPanel.class);
89  
90  	private JComboBox endpointCombo;
91  	private JButton submitButton;
92  	private JButton cancelButton;
93  	private EndpointsComboBoxModel endpointsModel;
94  	private JEditorStatusBarWithProgress statusBar;
95  	private JButton splitButton;
96  	private Submit submit;
97  	private JButton recreateButton;
98  	private JButton cloneButton;
99  	private JButton createEmptyButton;
100 	private InternalSubmitListener internalSubmitListener;
101 	private JSplitPane requestSplitPane;
102 	private MoveFocusAction moveFocusAction;
103 	private ClosePanelAction closePanelAction = new ClosePanelAction();
104 	private T2 request;
105 
106 	private SoapMessageXmlEditor requestEditor;
107 	private SoapMessageXmlEditor responseEditor;
108 
109 	private JTabbedPane requestTabs;
110 	private JPanel requestTabPanel;
111 	private JToggleButton tabsButton;
112 
113 	public boolean responseHasFocus;
114 
115 	private JButton addToMockServiceButton;
116 	
117 	private AbstractAction wsiValidateAction;
118 	private SubmitAction submitAction;
119 
120 	public AbstractWsdlRequestDesktopPanel(T modelItem)
121 	{
122 		super(modelItem);
123 	}
124 
125 	protected void init(T2 request)
126 	{
127 		this.request = request;
128 		
129 		this.endpointsModel = new EndpointsComboBoxModel(request);
130 		internalSubmitListener = createSubmitListener();
131 
132 		request.addSubmitListener(internalSubmitListener);
133 
134 		add(buildContent(), BorderLayout.CENTER);
135 		add(buildToolbar(), BorderLayout.NORTH);
136 		add(buildStatusLabel(), BorderLayout.SOUTH);
137 
138 		setPreferredSize(new Dimension(600, 500));
139 		
140 		addFocusListener( new FocusAdapter() {
141 
142 			@Override
143 			public void focusGained( FocusEvent e )
144 			{
145 				if( requestTabs.getSelectedIndex() == 1 || responseHasFocus )
146 					responseEditor.requestFocusInWindow();
147 				else
148 					requestEditor.requestFocusInWindow();
149 			}} );
150 	}
151 
152 	protected InternalSubmitListener createSubmitListener()
153 	{
154 		return new InternalSubmitListener();
155 	}
156 	
157 	public final T2 getRequest()
158 	{
159 		return request;
160 	}
161 	
162 	public final SoapMessageXmlEditor getRequestEditor()
163 	{
164 		return requestEditor;
165 	}
166 
167 	public final SoapMessageXmlEditor getResponseEditor()
168 	{
169 		return responseEditor;
170 	}
171 	
172 	public Submit getSubmit()
173 	{
174 		return submit;
175 	}
176 
177 	protected JComponent buildStatusLabel()
178 	{
179 		statusBar = new JEditorStatusBarWithProgress();
180 		statusBar.setBorder( BorderFactory.createEmptyBorder( 1, 0, 0, 0 ));
181 		
182 		return statusBar;
183 	}
184 	
185 	public JEditorStatusBarWithProgress getStatusBar()
186 	{
187 		return statusBar;
188 	}
189 
190 	@SuppressWarnings("unchecked")
191 	protected JComponent buildContent()
192 	{
193 		requestSplitPane = UISupport.createHorizontalSplit();
194 		requestSplitPane.setResizeWeight(0.5);
195 		requestSplitPane.setBorder(null);
196 		
197 		submitAction = new SubmitAction();
198 		submitButton = createActionButton(submitAction, true);
199 		cancelButton = createActionButton(new CancelAction(), false);
200 		splitButton = createActionButton(new ChangeSplitPaneOrientationAction(requestSplitPane), true);
201 		
202 		tabsButton = new JToggleButton( new ChangeToTabsAction() );
203 		tabsButton.setPreferredSize( UISupport.TOOLBAR_BUTTON_DIMENSION );
204 		
205 		recreateButton = createActionButton(new RecreateRequestAction(request), true);
206 		addToMockServiceButton = createActionButton( 
207 					SwingActionDelegate.createDelegate( AddRequestToMockServiceAction.SOAPUI_ACTION_ID, request, null, "/addToMockService.gif" ), true );
208 		
209 		cloneButton = createActionButton(
210 					SwingActionDelegate.createDelegate( CloneRequestAction.SOAPUI_ACTION_ID, request, null, "/clone_request.gif" ), true );
211 		
212 		createEmptyButton = createActionButton(new CreateEmptyRequestAction(request), true);
213 
214 		submitButton.setEnabled(request.getEndpoint() != null && request.getEndpoint().trim().length() > 0);
215 		wsiValidateAction = 
216 			SwingActionDelegate.createDelegate( new WSIValidateRequestAction(), request, "alt W" ); 
217 		wsiValidateAction.setEnabled( request.getResponse() != null );
218 		
219 		moveFocusAction = new MoveFocusAction();
220 
221 		requestEditor = buildRequestEditor();
222 		responseEditor = buildResponseEditor();
223 		
224 		requestTabs = new JTabbedPane();
225 		requestTabs.addChangeListener( new ChangeListener() {
226 
227 			public void stateChanged( ChangeEvent e )
228 			{
229 				SwingUtilities.invokeLater( new Runnable() {
230 
231 					public void run()
232 					{
233 						int ix = requestTabs.getSelectedIndex();
234 						if( ix == 0 )
235 							requestEditor.requestFocus(); 
236 						else if( ix == 1 )
237 							responseEditor.requestFocus(); 
238 					}} );
239 			}} );
240 		
241 	   requestTabPanel = UISupport.createTabPanel( requestTabs, true );
242 	   
243 		if( request.getSettings().getBoolean( UISettings.START_WITH_REQUEST_TABS ))
244 	   {
245 	   	requestTabs.addTab( "Request", requestEditor );
246 	   	requestTabs.addTab( "Response", responseEditor );
247 	   	splitButton.setEnabled( false );
248 	   	tabsButton.setSelected( true );
249 	   	
250 	   	return requestTabPanel;
251 	   }
252 	   else
253 	   {
254 	   	requestSplitPane.setTopComponent(requestEditor);
255 	   	requestSplitPane.setBottomComponent(responseEditor);
256 	   	requestSplitPane.setDividerLocation(0.5);
257 	   	return requestSplitPane;
258 	   }
259 	}
260 
261 	public SubmitAction getSubmitAction()
262 	{
263 		return submitAction;
264 	}
265 
266 	protected SoapMessageXmlEditor buildResponseEditor()
267 	{
268 		return new WsdlResponseMessageEditor( new ResponseXmlDocument( request ));
269 	}
270 
271 	protected SoapMessageXmlEditor buildRequestEditor()
272 	{
273 		return new WsdlRequestMessageEditor( new RequestXmlDocument( request ));
274 	}
275 	
276 	public static class OneWayResponseMessageEditor extends SoapMessageXmlEditor<ModelItem>
277 	{
278 		public OneWayResponseMessageEditor( ModelItem modelItem )
279 		{
280 			super( new DefaultXmlDocument(), modelItem );
281 		}
282 	}
283 
284 	protected JComponent buildToolbar()
285 	{
286 		endpointCombo = new JComboBox(endpointsModel);
287 		endpointCombo.setToolTipText(endpointsModel.getSelectedItem().toString());
288 
289 		endpointCombo.addItemListener(new ItemListener()
290 		{
291 			public void itemStateChanged(ItemEvent e)
292 			{
293 				Object item = endpointCombo.getSelectedItem();
294 				if (item == null)
295 				{
296 					endpointCombo.setToolTipText("- no endpoint set for request -");
297 				}
298 				else
299 				{
300 					String selectedItem = item.toString();
301 					endpointCombo.setToolTipText(selectedItem);
302 				}
303 
304 				submitButton.setEnabled(submit == null && request.getEndpoint() != null
305 						&& request.getEndpoint().trim().length() > 0);
306 			}
307 		});
308 
309 		JXToolBar toolbar =  UISupport.createToolbar(); 
310 		
311 		toolbar.add( submitButton );
312 		insertButtons( toolbar );
313 		
314 		toolbar.add( addToMockServiceButton);
315 		
316 		toolbar.add(recreateButton);
317 		toolbar.add(createEmptyButton);
318 		toolbar.add(cloneButton);
319 		toolbar.add(cancelButton);
320 		toolbar.addSeparator();
321 		toolbar.add(endpointCombo);
322 		
323 		toolbar.add( Box.createHorizontalGlue() );
324 		toolbar.add( tabsButton );
325 		toolbar.add(splitButton);
326 		toolbar.add(UISupport.createToolbarButton(new ShowOnlineHelpAction(getHelpUrl())));
327 		
328 		return toolbar;
329 	}
330 
331 	protected String getHelpUrl()
332 	{
333 		return HelpUrls.REQUESTEDITOR_HELP_URL;
334 	}
335 
336 	protected void insertButtons(JToolBar toolbar)
337 	{
338 	}
339 
340 	public void setEnabled(boolean enabled)
341 	{
342 		endpointCombo.setEnabled(enabled);
343 		requestEditor.setEditable(enabled);
344 		responseEditor.setEditable(enabled);
345 
346 		submitButton.setEnabled(enabled && request.getEndpoint() != null
347 				&& request.getEndpoint().trim().length() > 0);
348 		recreateButton.setEnabled(enabled);
349 		createEmptyButton.setEnabled(enabled);
350 		cloneButton.setEnabled(enabled);
351 		
352 		statusBar.setIndeterminate( !enabled );
353 	}
354 
355 	public class WsdlRequestMessageEditor extends RequestMessageXmlEditor<WsdlRequest>
356 	{
357 		private InputAreaFocusListener inputAreaFocusListener;
358 		private JXEditTextArea inputArea;
359 
360 		public WsdlRequestMessageEditor(XmlDocument document)
361 		{
362 			super(document, request );
363 			
364 			XmlSourceEditorView editor = getSourceEditor();
365 			inputArea = editor.getInputArea();
366 			inputArea.getInputHandler().addKeyBinding("A+ENTER", submitButton.getAction());
367 			inputArea.getInputHandler().addKeyBinding("A+X", cancelButton.getAction());
368 			inputArea.getInputHandler().addKeyBinding("AC+TAB", moveFocusAction);
369 			inputArea.getInputHandler().addKeyBinding("F5", recreateButton.getAction());
370 			inputArea.getInputHandler().addKeyBinding("C+F4", closePanelAction);
371 			
372 			inputAreaFocusListener = new InputAreaFocusListener();
373 			inputArea.addFocusListener( inputAreaFocusListener);
374 		}
375 
376 		@Override
377 		public void release()
378 		{
379 			super.release();
380 			inputArea.removeFocusListener( inputAreaFocusListener );
381 		}
382 	}
383 
384 	public class WsdlResponseMessageEditor extends ResponseMessageXmlEditor<WsdlRequest>
385 	{
386 		private JXEditTextArea inputArea;
387 		private ResultAreaFocusListener resultAreaFocusListener;
388 
389 		public WsdlResponseMessageEditor(XmlDocument document)
390 		{
391 			super(document, request );
392 		
393 			XmlSourceEditorView editor = getSourceEditor();
394 			
395 			inputArea = editor.getInputArea();
396 			resultAreaFocusListener = new ResultAreaFocusListener();
397 			inputArea.addFocusListener(resultAreaFocusListener);
398 			
399 			inputArea.getInputHandler().addKeyBinding("A+ENTER", submitButton.getAction());
400 			inputArea.getInputHandler().addKeyBinding("A+X", cancelButton.getAction());
401 			inputArea.getInputHandler().addKeyBinding("AC+TAB", moveFocusAction);
402 			inputArea.getInputHandler().addKeyBinding("C+F4", closePanelAction);
403 			
404 			JPopupMenu inputPopup = editor.getEditorPopup();
405 			inputPopup.insert( new JSeparator(), 2 );
406 			inputPopup.insert( wsiValidateAction, 3 );
407 		}
408 
409 		@Override
410 		public void release()
411 		{
412 			super.release();
413 			
414 			inputArea.removeFocusListener( resultAreaFocusListener );
415 		}
416 	}
417 	
418 	protected final class InputAreaFocusListener implements FocusListener
419 	{
420 		public void focusGained(FocusEvent e)
421 		{
422 			responseHasFocus = false;
423 			
424 			statusBar.setTarget( requestEditor.getSourceEditor().getInputArea() );
425 			if( !splitButton.isEnabled() )
426 			{
427 				requestTabs.setSelectedIndex( 0 );
428 				return;
429 			}
430 			
431 			if (getModelItem().getSettings().getBoolean(UISettings.NO_RESIZE_REQUEST_EDITOR))
432 				return;
433 
434 			// dont resize if split has been dragged
435 			if (((SoapUISplitPaneUI) requestSplitPane.getUI()).hasBeenDragged())
436 				return;
437 
438 			int pos = requestSplitPane.getDividerLocation();
439 			if (pos >= 600)
440 				return;
441 			if (requestSplitPane.getMaximumDividerLocation() > 700)
442 				requestSplitPane.setDividerLocation(600);
443 			else
444 				requestSplitPane.setDividerLocation(0.8);
445 		}
446 
447 		public void focusLost(FocusEvent e)
448 		{
449 		}
450 	}
451 
452 	protected final class ResultAreaFocusListener implements FocusListener
453 	{
454 		public void focusGained(FocusEvent e)
455 		{
456 			responseHasFocus = true;
457 			
458 			statusBar.setTarget( responseEditor.getSourceEditor().getInputArea() );
459 			if( !splitButton.isEnabled() )
460 			{
461 				requestTabs.setSelectedIndex( 1 );
462 				return;
463 			}
464 			
465 			if (request.getSettings().getBoolean(UISettings.NO_RESIZE_REQUEST_EDITOR))
466 				return;
467 
468 			// dont resize if split has been dragged or result is empty
469 			if (((SoapUISplitPaneUI) requestSplitPane.getUI()).hasBeenDragged() || request.getResponse() == null)
470 				return;
471 
472 			int pos = requestSplitPane.getDividerLocation();
473 			int maximumDividerLocation = requestSplitPane.getMaximumDividerLocation();
474 			if (pos + 600 < maximumDividerLocation)
475 				return;
476 
477 			if (maximumDividerLocation > 700)
478 				requestSplitPane.setDividerLocation(maximumDividerLocation - 600);
479 			else
480 				requestSplitPane.setDividerLocation(0.2);
481 		}
482 
483 		public void focusLost(FocusEvent e)
484 		{
485 		}
486 	}
487 
488 	public class SubmitAction extends AbstractAction
489 	{
490 		public SubmitAction()
491 		{
492 			putValue(Action.SMALL_ICON, UISupport.createImageIcon("/submit_request.gif"));
493 			putValue(Action.SHORT_DESCRIPTION, "Submit request to specified endpoint URL");
494 			putValue(Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "alt ENTER" ));
495 		}
496 
497 		public void actionPerformed(ActionEvent e)
498 		{
499 			if (submit != null && submit.getStatus() == Submit.Status.RUNNING)
500 			{
501 				if (UISupport.confirm("Cancel current request?", "Submit Request"))
502 				{
503 					submit.cancel();
504 				}
505 				else
506 					return;
507 			}
508 
509 			try
510 			{
511 				submit = doSubmit();
512 			}
513 			catch (SubmitException e1)
514 			{
515 				SoapUI.logError( e1 );
516 			}
517 		}
518 	}
519 	
520 	protected Submit doSubmit() throws SubmitException
521 	{
522 		return request.submit(new WsdlSubmitContext(null), true);
523 	}
524 
525 	private class CancelAction extends AbstractAction
526 	{
527 		public CancelAction()
528 		{
529 			super();
530 			putValue(Action.SMALL_ICON, UISupport.createImageIcon("/cancel_request.gif"));
531 			putValue(Action.SHORT_DESCRIPTION, "Aborts ongoing request");
532 			putValue(Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "alt X" ));
533 		}
534 
535 		public void actionPerformed(ActionEvent e)
536 		{
537 			if (submit == null)
538 				return;
539 
540 			cancelButton.setEnabled(false);
541 			submit.cancel();
542 			setEnabled(true);
543 			submit = null;
544 		}
545 	}
546 
547 	private class ClosePanelAction extends AbstractAction
548 	{
549 		public void actionPerformed(ActionEvent e)
550 		{
551 			SoapUI.getDesktop().closeDesktopPanel(getModelItem());
552 		}
553 	}
554 
555 	private class MoveFocusAction extends AbstractAction
556 	{
557 		public void actionPerformed(ActionEvent e)
558 		{
559 			if (requestEditor.hasFocus())
560 			{
561 				responseEditor.requestFocus();
562 			}
563 			else
564 			{
565 				requestEditor.requestFocus();
566 			}
567 		}
568 	}
569 
570 	protected class InternalSubmitListener implements SubmitListener
571 	{
572 		protected InternalSubmitListener()
573 		{
574 		}
575 
576 		public boolean beforeSubmit(Submit submit, SubmitContext context)
577 		{
578 			if (submit.getRequest() != request )
579 				return true;
580 			
581 			if( getModelItem().getSettings().getBoolean( UISettings.AUTO_VALIDATE_REQUEST ))
582 			{
583 				boolean result = requestEditor.saveDocument( true );
584 				if( !result &&  getModelItem().getSettings().getBoolean( UISettings.ABORT_ON_INVALID_REQUEST ))
585 				{
586 					statusBar.setInfo( "Cancelled request due to invalid content" );
587 					return false;
588 				}
589 			}
590 			else requestEditor.saveDocument( false );
591 
592 			setEnabled( false );
593 			cancelButton.setEnabled( AbstractWsdlRequestDesktopPanel.this.submit != null );
594 			wsiValidateAction.setEnabled( false );
595 			return true;
596 		}
597 
598 		public void afterSubmit(Submit submit, SubmitContext context)
599 		{
600 			if (submit.getRequest() != request )
601 				return;
602 			
603 			Status status = submit.getStatus();
604 			WsdlResponse response = (WsdlResponse) submit.getResponse();
605 			if (status != Status.CANCELED )
606 			{
607 				request.setResponse(response, context);
608 			}
609 			
610 			cancelButton.setEnabled(false);
611 			wsiValidateAction.setEnabled( request.getResponse() != null );
612 			setEnabled(true);
613 
614 			String message = null;
615 			String infoMessage = null;
616 			String requestName = request.getOperation().getInterface().getName() + "."
617 					+ request.getOperation().getName() + ":" + request.getName();
618 
619 			if (status == Status.CANCELED)
620 			{
621 				message = "CANCELED";
622 				infoMessage = "[" + requestName + "] - CANCELED";
623 			}
624 			else
625 			{
626 				if (status == Status.ERROR || response == null)
627 				{
628 					message = "Error getting response; " + submit.getError();
629 					infoMessage = "Error getting response for [" + requestName + "]; " + submit.getError();
630 				}
631 				else
632 				{
633 					message = "response time: " + response.getTimeTaken() + "ms (" + response.getContentLength() + " bytes)";
634 					infoMessage = "Got response for [" + requestName + "] in " + response.getTimeTaken() + "ms ("
635 							+ response.getContentLength() + " bytes)";
636 
637 					if( !splitButton.isEnabled() )
638 						requestTabs.setSelectedIndex( 1 );
639 					
640 					responseEditor.requestFocus();
641 				}
642 				
643 //				responseHeadersModel.setData( submit.getResponse() == null ? null : submit.getResponse().getResponseHeaders());
644 				
645 //				updateSSLInfo( response == null ? null : response.getSSLInfo() );
646 				wsiValidateAction.setEnabled( true );
647 			}
648 
649 			logMessages(message, infoMessage);
650 			
651 			if( getModelItem().getSettings().getBoolean( UISettings.AUTO_VALIDATE_RESPONSE ))
652 				responseEditor.getSourceEditor().validate();
653 
654 			AbstractWsdlRequestDesktopPanel.this.submit = null;
655 		}
656 
657 		protected void logMessages(String message, String infoMessage)
658 		{
659 			log.info(infoMessage);
660 			statusBar.setInfo(message);
661 		}
662 	}
663 
664 	public boolean onClose(boolean canCancel)
665 	{
666 		if (canCancel)
667 		{
668 			if (submit != null && submit.getStatus() == Submit.Status.RUNNING)
669 			{
670 				Boolean retVal = UISupport.confirmOrCancel("Cancel request before closing?", "Closing window");
671 				if (retVal == null)
672 					return false;
673 
674 				if (retVal.booleanValue() && submit.getStatus() == Submit.Status.RUNNING)
675 					submit.cancel();
676 			}
677 		}
678 		else if (submit != null && submit.getStatus() == Submit.Status.RUNNING)
679 		{
680 			submit.cancel();
681 		}
682 
683 		request.removeSubmitListener( internalSubmitListener );
684 		endpointsModel.release();
685 
686 		requestEditor.saveDocument( false );
687 		requestEditor.release();
688 		responseEditor.release();
689 		
690 		responseEditor.getParent().remove( responseEditor );
691 		requestEditor.getParent().remove( requestEditor );
692 		requestSplitPane.removeAll();
693 		
694 		return super.release();
695 	}
696 
697 	public boolean dependsOn(ModelItem modelItem)
698 	{
699 		return modelItem == request || modelItem == request.getOperation()
700 				|| modelItem == request.getOperation().getInterface()
701 				|| modelItem == request.getOperation().getInterface().getProject();
702 	}
703 
704 	private final class ChangeToTabsAction extends AbstractAction
705 	{
706 		public ChangeToTabsAction()
707 		{
708 			putValue(Action.SMALL_ICON, UISupport.createImageIcon("/toggle_tabs.gif"));
709 			putValue(Action.SHORT_DESCRIPTION, "Toggles to tab-based layout");
710 		}
711 		
712 		public void actionPerformed(ActionEvent e)
713 		{
714 			if( splitButton.isEnabled() )
715 			{
716 				splitButton.setEnabled( false );
717 				removeContent( requestSplitPane );
718 				setContent( requestTabPanel );
719 				requestTabs.addTab( "Request", requestEditor );
720 				requestTabs.addTab( "Response", responseEditor );
721 				
722 				if( responseHasFocus )
723 				{
724 					requestTabs.setSelectedIndex( 1 );
725 					requestEditor.requestFocus();
726 				}
727 			}
728 			else
729 			{
730 				int selectedIndex = requestTabs.getSelectedIndex();
731 				
732 				splitButton.setEnabled( true );
733 				removeContent( requestTabPanel );
734 				setContent( requestSplitPane );
735 				requestSplitPane.setTopComponent(requestEditor);
736 		   	requestSplitPane.setBottomComponent(responseEditor);
737 		   	requestSplitPane.setDividerLocation(0.5);
738 		   	
739 		   	if( selectedIndex == 0 )
740 		   		requestEditor.requestFocus();
741 		   	else
742 		   		responseEditor.requestFocus();
743 			}
744 			
745 			revalidate();
746 		}
747 	}
748 	
749 	public void setContent(JComponent content)
750 	{
751 		add( content, BorderLayout.CENTER );
752 	}
753 
754 	public void removeContent(JComponent content)
755 	{
756 		remove( content );
757 	}
758 }