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