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.mockoperation;
    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.beans.PropertyChangeEvent;
    23  import java.beans.PropertyChangeListener;
    24
    25  import javax.swing.AbstractAction;
    26  import javax.swing.Action;
    27  import javax.swing.BorderFactory;
    28  import javax.swing.Box;
    29  import javax.swing.JButton;
    30  import javax.swing.JComponent;
    31  import javax.swing.JLabel;
    32  import javax.swing.JPanel;
    33  import javax.swing.JPopupMenu;
    34  import javax.swing.JScrollPane;
    35  import javax.swing.JSeparator;
    36  import javax.swing.JSplitPane;
    37  import javax.swing.JTabbedPane;
    38  import javax.swing.JTable;
    39  import javax.swing.JToggleButton;
    40  import javax.swing.JToolBar;
    41  import javax.swing.event.TableModelEvent;
    42  import javax.swing.event.TableModelListener;
    43
    44  import com.eviware.soapui.SoapUI;
    45  import com.eviware.soapui.impl.wsdl.actions.mockresponse.OpenRequestForMockResponseAction;
    46  import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
    47  import com.eviware.soapui.impl.wsdl.mock.WsdlMockRequest;
    48  import com.eviware.soapui.impl.wsdl.mock.WsdlMockResponse;
    49  import com.eviware.soapui.impl.wsdl.mock.WsdlMockResult;
    50  import com.eviware.soapui.impl.wsdl.panels.attachments.MockAttachmentPanel;
    51  import com.eviware.soapui.impl.wsdl.panels.mockoperation.actions.CreateEmptyMockResponseAction;
    52  import com.eviware.soapui.impl.wsdl.panels.mockoperation.actions.CreateFaultMockResponseAction;
    53  import com.eviware.soapui.impl.wsdl.panels.mockoperation.actions.RecreateMockResponseAction;
    54  import com.eviware.soapui.impl.wsdl.panels.mockoperation.actions.WSIValidateResponseAction;
    55  import com.eviware.soapui.impl.wsdl.panels.request.StringToStringMapTableModel;
    56  import com.eviware.soapui.impl.wsdl.panels.request.components.RequestMessageXmlEditor;
    57  import com.eviware.soapui.impl.wsdl.panels.request.components.ResponseMessageXmlEditor;
    58  import com.eviware.soapui.impl.wsdl.panels.request.components.SoapMessageXmlEditor;
    59  import com.eviware.soapui.impl.wsdl.panels.request.components.editor.XmlDocument;
    60  import com.eviware.soapui.impl.wsdl.panels.request.components.editor.views.source.XmlSourceEditorView;
    61  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.GroovyEditor;
    62  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.GroovyEditorModel;
    63  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
    64  import com.eviware.soapui.model.ModelItem;
    65  import com.eviware.soapui.model.mock.MockRunner;
    66  import com.eviware.soapui.model.settings.Settings;
    67  import com.eviware.soapui.settings.UISettings;
    68  import com.eviware.soapui.support.UISupport;
    69  import com.eviware.soapui.support.action.swing.SwingActionDelegate;
    70  import com.eviware.soapui.support.actions.ChangeSplitPaneOrientationAction;
    71  import com.eviware.soapui.support.components.JEditorStatusBarWithProgress;
    72  import com.eviware.soapui.support.components.JXToolBar;
    73  import com.eviware.soapui.support.swing.SoapUISplitPaneUI;
    74  import com.eviware.soapui.support.types.StringToStringMap;
    75  import com.eviware.soapui.support.xml.JXEditTextArea;
    76  import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
    77
    78  /***
    79   * Abstract base DesktopPanel for WsdlMockResponses
    80   *
    81   * @author Ole.Matzura
    82   */
    83
    84  public class AbstractWsdlMockResponseDesktopPanel<T extends ModelItem, T2 extends WsdlMockResponse> extends ModelItemDesktopPanel<T>
    85  {
    86  	//private final static Log log = Logger.getLogger(WsdlMockOperationDesktopPanel.class);
    87  	private JEditorStatusBarWithProgress statusBar;
    88  	private JButton splitButton;
    89  	private MockRunner mockRunner;
    90  	private JButton recreateButton;
    91  	private JButton createEmptyButton;
    92  	private JSplitPane requestSplitPane;
    93  	private MoveFocusAction moveFocusAction;
    94  	private ClosePanelAction closePanelAction = new ClosePanelAction();
    95  	private RunScriptAction runScriptAction = new RunScriptAction();
    96
    97  	private SoapMessageXmlEditor requestEditor;
    98  	private SoapMessageXmlEditor responseEditor;
    99
    100 	public AbstractAction wsiValidateAction;
    101
    102 	private JTabbedPane requestTabs;
    103 	private JPanel requestTabPanel;
    104 	private JToggleButton tabsButton;
    105
    106 	public boolean responseHasFocus;
    107
    108 	private JTabbedPane requestEditorTabs;
    109 	private JTabbedPane responseEditorTabs;
    110
    111 	private JPanel requestEditorTabPanel;
    112 	private JPanel responseEditorTabPanel;
    113 	private InternalPropertyChangeListener propertyChangeListener = new InternalPropertyChangeListener();
    114 	private StringToStringMapTableModel responseHeadersModel;
    115 	private JTable responseHeadersTable;
    116 	private StringToStringMapTableModel requestHeadersModel;
    117 	private GroovyEditor responseScriptEditor;
    118 	private JButton createFaultButton;
    119 	private T2 mockResponse;
    120 	private JButton openRequestButton;
    121 	private MockAttachmentPanel requestAttachmentPanel;
    122 	private MockAttachmentPanel responseAttachmentPanel;;
    123
    124 	public AbstractWsdlMockResponseDesktopPanel(T modelItem)
    125 	{
    126 		super(modelItem);
    127 	}
    128
    129 	protected void init( T2 mockResponse )
    130 	{
    131 		this.mockResponse = mockResponse;
    132
    133 		add(buildContent(), BorderLayout.CENTER);
    134 		add(buildToolbar(), BorderLayout.NORTH);
    135 		add(buildStatusLabel(), BorderLayout.SOUTH);
    136
    137 		setPreferredSize(new Dimension(600, 500));
    138
    139 		mockResponse.addPropertyChangeListener( propertyChangeListener );
    140
    141 		addFocusListener( new FocusAdapter() {
    142
    143 			@Override
    144 			public void focusGained( FocusEvent e )
    145 			{
    146 				if( requestTabs.getSelectedIndex() == 1 || responseHasFocus )
    147 					responseEditor.requestFocus();
    148 				else
    149 					requestEditor.requestFocus();
    150 			}} );
    151 	}
    152
    153 	protected WsdlMockResponse getMockResponse()
    154 	{
    155 		return mockResponse;
    156 	}
    157
    158 	public final SoapMessageXmlEditor getRequestEditor()
    159 	{
    160 		return requestEditor;
    161 	}
    162
    163 	public final SoapMessageXmlEditor getResponseEditor()
    164 	{
    165 		return responseEditor;
    166 	}
    167
    168 	public MockRunner getSubmit()
    169 	{
    170 		return mockRunner;
    171 	}
    172
    173 	protected JComponent buildStatusLabel()
    174 	{
    175 		statusBar = new JEditorStatusBarWithProgress();
    176 		statusBar.setBorder( BorderFactory.createEmptyBorder( 1, 0, 0, 0 ));
    177
    178 		return statusBar;
    179 	}
    180
    181 	public JEditorStatusBarWithProgress getStatusBar()
    182 	{
    183 		return statusBar;
    184 	}
    185
    186 	@SuppressWarnings("unchecked")
    187 	protected JComponent buildContent()
    188 	{
    189 		requestSplitPane = UISupport.createHorizontalSplit();
    190 		requestSplitPane.setResizeWeight(0.5);
    191 		requestSplitPane.setBorder(null);
    192
    193 		splitButton = createActionButton(new ChangeSplitPaneOrientationAction(requestSplitPane), true);
    194
    195 		tabsButton = new JToggleButton( new ChangeToTabsAction() );
    196 		tabsButton.setPreferredSize( UISupport.TOOLBAR_BUTTON_DIMENSION );
    197
    198 		openRequestButton = createActionButton(
    199 					SwingActionDelegate.createDelegate( OpenRequestForMockResponseAction.SOAPUI_ACTION_ID, mockResponse, null,
    200 						"/open_request.gif"), true);
    201 		recreateButton = createActionButton(new RecreateMockResponseAction( mockResponse ), true);
    202 		createEmptyButton = createActionButton(new CreateEmptyMockResponseAction(mockResponse), true);
    203 		createFaultButton = createActionButton(new CreateFaultMockResponseAction(mockResponse), true);
    204
    205 		moveFocusAction = new MoveFocusAction();
    206 		wsiValidateAction = //new WSIValidateResponseAction( mockResponse );
    207 			SwingActionDelegate.createDelegate( new WSIValidateResponseAction(), mockResponse, "alt W" );
    208
    209 		requestEditor = buildRequestEditor();
    210 		responseEditor = buildResponseEditor();
    211 		JComponent scriptEditor = buildResponseScriptEditor();
    212
    213 		WsdlMockResult mockResult = mockResponse.getMockResult();
    214 		int requestHeadersSize = mockResult == null ? -1 : mockResult.getMockRequest().getRequestHeaders().size();
    215 		int requestAttachmentsSize = mockResult == null ? -1 : mockResult.getMockRequest().getRequestAttachments().length;
    216
    217 		requestEditorTabs = new JTabbedPane( JTabbedPane.BOTTOM );
    218 		requestEditorTabs.setTabLayoutPolicy( JTabbedPane.SCROLL_TAB_LAYOUT );
    219 		requestEditorTabs.addTab( "SOAP Request", requestEditor );
    220 		requestAttachmentPanel = new MockAttachmentPanel( mockResponse, false );
    221 		requestEditorTabs.addTab( "Request Attachments (" + (requestAttachmentsSize == -1 ? "-" : requestAttachmentsSize) + ")",
    222 					requestAttachmentPanel);
    223 		requestEditorTabs.addTab( "HTTP Headers (" + (requestHeadersSize == -1 ? "-" : requestHeadersSize ) + ")",
    224 					createRequestHttpHeadersPanel() );
    225
    226 		responseEditorTabs = new JTabbedPane( JTabbedPane.BOTTOM );
    227 		responseEditorTabs.setTabLayoutPolicy( JTabbedPane.SCROLL_TAB_LAYOUT );
    228 		responseEditorTabs.addTab( "Mock Response", responseEditor );
    229 		responseEditorTabs.addTab( "Response Script", scriptEditor );
    230 		responseAttachmentPanel = new MockAttachmentPanel( mockResponse, true );
    231 		responseEditorTabs.addTab( "Response Attachments (" +
    232 					mockResponse.getAttachments().length + ")", responseAttachmentPanel);
    233 		responseEditorTabs.addTab(  "Response HTTP Headers", createResponseHttpHeadersPanel() );
    234 		responseEditorTabs.setTitleAt( 3, "Response HTTP Headers (" + responseHeadersModel.getRowCount() + ")");
    235
    236 		requestTabs = new JTabbedPane();
    237 	   requestTabPanel = UISupport.createTabPanel( requestTabs, true );
    238
    239 	   requestEditorTabPanel = UISupport.createTabPanel(requestEditorTabs, false);
    240 		responseEditorTabPanel = UISupport.createTabPanel(responseEditorTabs, false);
    241
    242 		JComponent component = null;
    243
    244 		if( mockResponse.getSettings().getBoolean( UISettings.START_WITH_REQUEST_TABS ))
    245 	   {
    246 	   	requestTabs.addTab( "Last Request", requestEditorTabPanel );
    247 	   	requestTabs.addTab( "Mock Response", responseEditorTabPanel );
    248 	   	splitButton.setEnabled( false );
    249 	   	tabsButton.setSelected( true );
    250 	   	component = requestTabPanel;
    251
    252 	   	requestTabs.setSelectedIndex( 1 );
    253 	   }
    254 	   else
    255 	   {
    256 	   	requestSplitPane.setTopComponent(requestEditorTabPanel);
    257 	   	requestSplitPane.setBottomComponent(responseEditorTabPanel);
    258 	   	requestSplitPane.setDividerLocation(0.5);
    259 	   	component = requestSplitPane;
    260 	   }
    261
    262 		return component;
    263 	}
    264
    265 	private Component createRequestHttpHeadersPanel()
    266 	{
    267 		requestHeadersModel = new StringToStringMapTableModel( new StringToStringMap(), "Header", "Value", false );
    268 		requestHeadersModel.addTableModelListener( new TableModelListener()
    269 		{
    270 			public void tableChanged( TableModelEvent arg0 )
    271 			{
    272 				requestEditorTabs.setTitleAt( 2, "HTTP Headers (" + requestHeadersModel.getRowCount() + ")");
    273 			}} );
    274
    275 		JTable requestHeadersTable = new JTable( requestHeadersModel );
    276 		return new JScrollPane( requestHeadersTable );
    277 	}
    278
    279 	private Component createResponseHttpHeadersPanel()
    280 	{
    281 		responseHeadersModel = new StringToStringMapTableModel( mockResponse.getResponseHeaders(),
    282 					"Header", "Value", true );
    283 		responseHeadersModel.addTableModelListener( new TableModelListener()
    284 		{
    285 			public void tableChanged( TableModelEvent arg0 )
    286 			{
    287 				mockResponse.setResponseHeaders( responseHeadersModel.getData() );
    288 				responseEditorTabs.setTitleAt( 3, "Response HTTP Headers (" + responseHeadersModel.getRowCount() + ")");
    289 			}} );
    290
    291 		responseHeadersTable = new JTable( responseHeadersModel );
    292 		JPanel panel = new JPanel( new BorderLayout() );
    293
    294 		panel.add( new JScrollPane( responseHeadersTable ), BorderLayout.CENTER );
    295
    296 		JXToolBar builder = UISupport.createToolbar();
    297 		builder.addFixed( new JButton( new AbstractAction( "Add" ) {
    298
    299 			public void actionPerformed( ActionEvent arg0 )
    300 			{
    301 				Object header = UISupport.prompt( "Specify name of header to add", "Add HTTP Header", "" );
    302 				if( header != null )
    303 				{
    304 					responseHeadersModel.add( header.toString(), "" );
    305 				}
    306 			}} ));
    307 		builder.addRelatedGap();
    308 		builder.addFixed( new JButton( new AbstractAction("Remove" ){
    309
    310 			public void actionPerformed( ActionEvent arg0 )
    311 			{
    312 				int row = responseHeadersTable.getSelectedRow();
    313 				if( row != -1 && UISupport.confirm( "Delete selected header?", "Remove Header" ) )
    314 				{
    315 					responseHeadersModel.remove( row );
    316 				}
    317 			}} ));
    318
    319 		builder.addGlue();
    320 		builder.addFixed( UISupport.createToolbarButton( new ShowOnlineHelpAction(HelpUrls.HEADERS_HELP_URL)));
    321
    322 		panel.add( builder, BorderLayout.SOUTH );
    323
    324 		return panel;
    325 	}
    326
    327 	protected JComponent buildResponseScriptEditor()
    328 	{
    329 		responseScriptEditor = new GroovyEditor( new MockResponseGroovyEditorModel() );
    330
    331 		JPanel panel = new JPanel( new BorderLayout() );
    332 		panel.add( buildScriptToolbar(), BorderLayout.NORTH );
    333 		panel.add( new JScrollPane( responseScriptEditor ), BorderLayout.CENTER );
    334 		return panel;
    335 	}
    336
    337 	private JComponent buildScriptToolbar()
    338 	{
    339 		JXToolBar toolBar = UISupport.createToolbar();
    340 		JButton runButton = UISupport.createToolbarButton( runScriptAction );
    341 		toolBar.add( runButton );
    342 		toolBar.add( Box.createHorizontalGlue() );
    343 		JLabel label = new JLabel("<html>Script is invoked with <code>log</code>, <code>context</code>, " +
    344 				"<code>requestContext</code>, <code>mockRequest</code> and <code>mockResponse</code> variables</html>");
    345 		label.setToolTipText( label.getText() );
    346 		label.setMaximumSize( label.getPreferredSize() );
    347
    348 		toolBar.add( label);
    349 		toolBar.addUnrelatedGap();
    350 		toolBar.addFixed( createActionButton( new ShowOnlineHelpAction( HelpUrls.MOCKRESPONSE_SCRIPT_HELP_URL ), true ));
    351
    352 		return toolBar;
    353 	}
    354
    355 	protected SoapMessageXmlEditor buildResponseEditor()
    356 	{
    357 		return new ResponseMessageEditor( new MockResponseXmlDocument( mockResponse ));
    358 	}
    359
    360 	protected SoapMessageXmlEditor buildRequestEditor()
    361 	{
    362 		return new RequestMessageEditor( new MockRequestXmlDocument( mockResponse ));
    363 	}
    364
    365 	protected JComponent buildToolbar()
    366 	{
    367 		JXToolBar toolbar =  UISupport.createToolbar();
    368
    369 		toolbar.add( openRequestButton);
    370 		toolbar.addUnrelatedGap();
    371 		toolbar.add(recreateButton);
    372 		toolbar.add(createEmptyButton);
    373 		toolbar.add(createFaultButton);
    374
    375 		createToolbar( toolbar );
    376
    377 		toolbar.add( Box.createHorizontalGlue() );
    378 		toolbar.add( tabsButton );
    379 		toolbar.add(splitButton);
    380 		toolbar.add(UISupport.createToolbarButton(new ShowOnlineHelpAction(getHelpUrl())));
    381
    382 		return toolbar;
    383 	}
    384
    385 	protected void createToolbar( JXToolBar toolbar )
    386 	{
    387 	}
    388
    389 	protected String getHelpUrl()
    390 	{
    391 		return HelpUrls.REQUESTEDITOR_HELP_URL;
    392 	}
    393
    394 	protected void insertButtons(JToolBar toolbar)
    395 	{
    396 	}
    397
    398 	public void setEnabled(boolean enabled)
    399 	{
    400 		requestEditor.getSourceEditor().setEditable(enabled);
    401 		responseEditor.getSourceEditor().setEditable(enabled);
    402 		recreateButton.setEnabled(enabled);
    403 		createEmptyButton.setEnabled(enabled);
    404
    405
    406 		statusBar.setIndeterminate( !enabled );
    407 	}
    408
    409 	private final class InternalPropertyChangeListener implements PropertyChangeListener
    410 	{
    411 		public void propertyChange(PropertyChangeEvent evt)
    412 		{
    413 			if( evt.getPropertyName().equals( WsdlMockResponse.ATTACHMENTS_PROPERTY ))
    414 			{
    415 				responseEditorTabs.setTitleAt( 1, "Response Attachments (" + mockResponse.getAttachmentCount() + ")");
    416 			}
    417 			else if( evt.getPropertyName().equals( WsdlMockResponse.HEADERS_PROPERTY ))
    418 			{
    419 				responseHeadersModel.setData( ( StringToStringMap ) evt.getNewValue() );
    420 			}
    421 			else if( evt.getPropertyName().equals( WsdlMockResponse.MOCKRESULT_PROPERTY ))
    422 			{
    423 				WsdlMockRequest mockRequest = mockResponse.getMockResult().getMockRequest();
    424 				requestEditor.getXmlDocument().setXml( mockRequest == null ? "" : mockRequest.getRequestContent());
    425
    426 				// update headers
    427 				requestHeadersModel.setData( mockRequest.getRequestHeaders() );
    428 				requestEditorTabs.setTitleAt( 2, "HTTP Headers (" + (mockRequest == null ? "-" : mockRequest.getRequestHeaders().size() + ")") );
    429
    430 				// update attachments
    431 				requestEditorTabs.setTitleAt( 1, "Request Attachments (" + (mockRequest == null ? 0 :
    432 					mockRequest.getRequestAttachments().length) + ")" );
    433
    434 				wsiValidateAction.setEnabled( true );
    435 			}
    436 		}
    437 	}
    438
    439 	public class RequestMessageEditor extends RequestMessageXmlEditor<WsdlMockResponse>
    440 	{
    441 		public RequestMessageEditor(XmlDocument document)
    442 		{
    443 			super(document, mockResponse);
    444 		}
    445
    446 		protected XmlSourceEditorView buildSourceEditor()
    447 		{
    448 			XmlSourceEditorView editor = getSourceEditor();
    449 			JXEditTextArea inputArea = editor.getInputArea();
    450
    451 			inputArea.addFocusListener(new InputAreaFocusListener());
    452
    453 			inputArea.getInputHandler().addKeyBinding("AC+TAB", moveFocusAction);
    454 			inputArea.getInputHandler().addKeyBinding("F5", recreateButton.getAction());
    455 			inputArea.getInputHandler().addKeyBinding("C+F4", closePanelAction);
    456
    457 			return editor;
    458 		}
    459 	}
    460
    461
    462
    463 	public class ResponseMessageEditor extends ResponseMessageXmlEditor<WsdlMockResponse>
    464 	{
    465 		public ResponseMessageEditor(XmlDocument document)
    466 		{
    467 			super(document, mockResponse );
    468 		}
    469
    470 		protected XmlSourceEditorView buildSourceEditor()
    471 		{
    472 			XmlSourceEditorView editor = getSourceEditor();
    473
    474 			JXEditTextArea inputArea = editor.getInputArea();
    475 			inputArea.addFocusListener(new ResultAreaFocusListener());
    476
    477 			inputArea.getInputHandler().addKeyBinding("AC+TAB", moveFocusAction);
    478 			inputArea.getInputHandler().addKeyBinding("C+F4", closePanelAction);
    479
    480 			JPopupMenu inputPopup = editor.getEditorPopup();
    481 			inputPopup.insert( new JSeparator(), 2 );
    482 			inputPopup.insert( wsiValidateAction, 3 );
    483
    484 			return editor;
    485 		}
    486 	}
    487
    488 	protected final class InputAreaFocusListener implements FocusListener
    489 	{
    490 		public void focusGained(FocusEvent e)
    491 		{
    492 			responseHasFocus = false;
    493
    494 			statusBar.setTarget( requestEditor.getSourceEditor().getInputArea() );
    495 			if( !splitButton.isEnabled() )
    496 			{
    497 				requestTabs.setSelectedIndex( 0 );
    498 				return;
    499 			}
    500
    501 			if (getModelItem().getSettings().getBoolean(UISettings.NO_RESIZE_REQUEST_EDITOR))
    502 				return;
    503
    504 			// dont resize if split has been dragged
    505 			if (((SoapUISplitPaneUI) requestSplitPane.getUI()).hasBeenDragged())
    506 				return;
    507
    508 			int pos = requestSplitPane.getDividerLocation();
    509 			if (pos >= 600)
    510 				return;
    511 			if (requestSplitPane.getMaximumDividerLocation() > 700)
    512 				requestSplitPane.setDividerLocation(600);
    513 			else
    514 				requestSplitPane.setDividerLocation(0.8);
    515 		}
    516
    517 		public void focusLost(FocusEvent e)
    518 		{
    519 		}
    520 	}
    521
    522 	protected final class ResultAreaFocusListener implements FocusListener
    523 	{
    524 		public void focusGained(FocusEvent e)
    525 		{
    526 			responseHasFocus = true;
    527
    528 			statusBar.setTarget( responseEditor.getSourceEditor().getInputArea() );
    529 			if( !splitButton.isEnabled() )
    530 			{
    531 				requestTabs.setSelectedIndex( 1 );
    532 				return;
    533 			}
    534
    535 			if (getModelItem().getSettings().getBoolean(UISettings.NO_RESIZE_REQUEST_EDITOR))
    536 				return;
    537
    538 			// dont resize if split has been dragged or result is empty
    539 			if (((SoapUISplitPaneUI) requestSplitPane.getUI()).hasBeenDragged() )
    540 				return;
    541
    542 			int pos = requestSplitPane.getDividerLocation();
    543 			int maximumDividerLocation = requestSplitPane.getMaximumDividerLocation();
    544 			if (pos + 600 < maximumDividerLocation)
    545 				return;
    546
    547 			if (maximumDividerLocation > 700)
    548 				requestSplitPane.setDividerLocation(maximumDividerLocation - 600);
    549 			else
    550 				requestSplitPane.setDividerLocation(0.2);
    551 		}
    552
    553 		public void focusLost(FocusEvent e)
    554 		{
    555 		}
    556 	}
    557
    558 	private class ClosePanelAction extends AbstractAction
    559 	{
    560 		public void actionPerformed(ActionEvent e)
    561 		{
    562 			SoapUI.getDesktop().closeDesktopPanel(getModelItem());
    563 		}
    564 	}
    565
    566 	private class MoveFocusAction extends AbstractAction
    567 	{
    568 		public void actionPerformed(ActionEvent e)
    569 		{
    570 			if (requestEditor.hasFocus())
    571 			{
    572 				responseEditor.requestFocus();
    573 			}
    574 			else
    575 			{
    576 				requestEditor.requestFocus();
    577 			}
    578 		}
    579 	}
    580
    581 	public boolean dependsOn(ModelItem modelItem)
    582 	{
    583 		return modelItem == getModelItem() || modelItem == mockResponse.getMockOperation()
    584 				|| modelItem == mockResponse.getMockOperation().getMockService()
    585 				|| modelItem == mockResponse.getMockOperation().getMockService().getProject();
    586 	}
    587
    588 	public String getDescription()
    589 	{
    590 		return "MockResponse: [" + getModelItem().getName() + "] for " + mockResponse.getMockOperation().getName();
    591 	}
    592
    593 	private final class ChangeToTabsAction extends AbstractAction
    594 	{
    595 		public ChangeToTabsAction()
    596 		{
    597 			putValue(Action.SMALL_ICON, UISupport.createImageIcon("/toggle_tabs.gif"));
    598 			putValue(Action.SHORT_DESCRIPTION, "Toggles to tab-based layout");
    599 		}
    600
    601 		public void actionPerformed(ActionEvent e)
    602 		{
    603 			if( splitButton.isEnabled() )
    604 			{
    605 				splitButton.setEnabled( false );
    606 				removeContent( requestSplitPane );
    607 				setContent( requestTabPanel );
    608 				requestTabs.addTab( "Last Request", requestEditorTabPanel );
    609 				requestTabs.addTab( "Mock Response", responseEditorTabPanel );
    610
    611 				if( responseHasFocus )
    612 				{
    613 					requestTabs.setSelectedIndex( 1 );
    614 					requestEditorTabs.requestFocus();
    615 				}
    616 				else
    617 				{
    618 					responseEditorTabs.requestFocus();
    619 				}
    620 			}
    621 			else
    622 			{
    623 				int selectedIndex = requestTabs.getSelectedIndex();
    624
    625 				splitButton.setEnabled( true );
    626 				removeContent( requestTabPanel );
    627 				setContent( requestSplitPane );
    628 				requestSplitPane.setTopComponent(requestEditorTabPanel);
    629 		   	requestSplitPane.setBottomComponent(responseEditorTabPanel);
    630 		   	requestSplitPane.setDividerLocation(0.5);
    631
    632 		   	if( selectedIndex == 0 )
    633 		   		requestEditor.requestFocus();
    634 		   	else
    635 		   		responseEditor.requestFocus();
    636 			}
    637
    638 			revalidate();
    639 		}
    640 	}
    641
    642 	public void setContent(JComponent content)
    643 	{
    644 		add( content, BorderLayout.CENTER );
    645 	}
    646
    647 	public void removeContent(JComponent content)
    648 	{
    649 		remove( content );
    650 	}
    651
    652 	public boolean onClose( boolean canCancel )
    653 	{
    654 		mockResponse.removePropertyChangeListener( propertyChangeListener );
    655
    656 		requestEditor.release();
    657 		responseEditor.release();
    658 		responseScriptEditor.release();
    659
    660 		requestAttachmentPanel.release();
    661 		responseAttachmentPanel.release();
    662
    663 		responseEditor.getParent().remove( responseEditor );
    664 		responseEditor = null;
    665 		requestEditor.getParent().remove( requestEditor );
    666 		requestEditor = null;
    667
    668 		return release();
    669 	}
    670
    671 	private class RunScriptAction extends AbstractAction
    672 	{
    673 		public RunScriptAction()
    674 		{
    675 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_groovy_script.gif" ));
    676 			putValue( Action.SHORT_DESCRIPTION, "Runs this script using mock httpRequest/httpResponse objects" );
    677 		}
    678
    679 		public void actionPerformed(ActionEvent e)
    680 		{
    681 			try
    682 			{
    683 				mockResponse.evaluateScript( mockResponse.getMockResult() == null ? null :
    684 					mockResponse.getMockResult().getMockRequest() );
    685
    686 				StringToStringMap values = null;
    687 				if( mockResponse.getMockResult() != null )
    688 					values = mockResponse.getMockResult().getMockRequest().getContext().toStringToStringMap();
    689
    690 				if( values == null || values.isEmpty() )
    691 				{
    692 					UISupport.showInfoMessage( "No values were returned" );
    693 				}
    694 				else
    695 				{
    696 					String msg = "<html><body>Returned values:<br>";
    697
    698 					for( String name : values.keySet() )
    699 					{
    700 						msg += name + " : " + values.get( name ) + "<br>";
    701 					}
    702
    703 					msg +="</body></html>";
    704
    705 					UISupport.showInfoMessage( msg );
    706 				}
    707 			}
    708 			catch( Throwable e1 )
    709 			{
    710 				responseScriptEditor.selectError( e1.getMessage() );
    711 				UISupport.showErrorMessage( e1.toString() );
    712 			}
    713 		}
    714 	}
    715
    716 	private class MockResponseGroovyEditorModel implements GroovyEditorModel
    717 	{
    718 		public String[] getKeywords()
    719 		{
    720 			return new String[] {"context", "mockRequest", "mockResponse", "log", "requestContext" };
    721 		}
    722
    723 		public Action getRunAction()
    724 		{
    725 			return runScriptAction;
    726 		}
    727
    728 		public String getScript()
    729 		{
    730 			return mockResponse.getScript();
    731 		}
    732
    733 		public void setScript( String text )
    734 		{
    735 			mockResponse.setScript( text );
    736 		}
    737
    738 		public Settings getSettings()
    739 		{
    740 			return SoapUI.getSettings();
    741 		}}
    742 }