View Javadoc

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