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 }