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.ItemEvent;
20  import java.awt.event.ItemListener;
21  import java.beans.PropertyChangeEvent;
22  import java.beans.PropertyChangeListener;
23  import java.util.ArrayList;
24  import java.util.List;
25  
26  import javax.swing.AbstractAction;
27  import javax.swing.AbstractListModel;
28  import javax.swing.Action;
29  import javax.swing.BorderFactory;
30  import javax.swing.JComboBox;
31  import javax.swing.JComponent;
32  import javax.swing.JLabel;
33  import javax.swing.JList;
34  import javax.swing.JPanel;
35  import javax.swing.JScrollPane;
36  import javax.swing.JTabbedPane;
37  import javax.swing.ListCellRenderer;
38  import javax.swing.ListModel;
39  
40  import org.apache.xmlbeans.XmlObject;
41  
42  import com.eviware.soapui.SoapUI;
43  import com.eviware.soapui.config.DispatchStyleConfig;
44  import com.eviware.soapui.config.DispatchStyleConfig.Enum;
45  import com.eviware.soapui.impl.wsdl.WsdlInterface;
46  import com.eviware.soapui.impl.wsdl.WsdlOperation;
47  import com.eviware.soapui.impl.wsdl.actions.mockoperation.NewMockResponseAction;
48  import com.eviware.soapui.impl.wsdl.actions.mockoperation.OpenRequestForMockOperationAction;
49  import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
50  import com.eviware.soapui.impl.wsdl.mock.WsdlMockOperation;
51  import com.eviware.soapui.impl.wsdl.mock.WsdlMockRequest;
52  import com.eviware.soapui.impl.wsdl.mock.WsdlMockResponse;
53  import com.eviware.soapui.impl.wsdl.mock.WsdlMockResult;
54  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.GroovyEditor;
55  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.GroovyEditorModel;
56  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
57  import com.eviware.soapui.model.ModelItem;
58  import com.eviware.soapui.model.iface.Interface;
59  import com.eviware.soapui.model.iface.Operation;
60  import com.eviware.soapui.model.mock.MockOperation;
61  import com.eviware.soapui.model.mock.MockResponse;
62  import com.eviware.soapui.model.mock.MockServiceListener;
63  import com.eviware.soapui.model.settings.Settings;
64  import com.eviware.soapui.model.support.InterfaceListenerAdapter;
65  import com.eviware.soapui.model.support.ProjectListenerAdapter;
66  import com.eviware.soapui.model.util.ModelItemNames;
67  import com.eviware.soapui.support.UISupport;
68  import com.eviware.soapui.support.action.swing.ActionList;
69  import com.eviware.soapui.support.action.swing.ActionSupport;
70  import com.eviware.soapui.support.action.swing.SwingActionDelegate;
71  import com.eviware.soapui.support.components.JComponentInspector;
72  import com.eviware.soapui.support.components.JInspectorPanel;
73  import com.eviware.soapui.support.components.JXToolBar;
74  import com.eviware.soapui.support.swing.ExtendedComboBoxModel;
75  import com.eviware.soapui.support.swing.ModelItemListMouseListener;
76  import com.eviware.soapui.support.types.StringList;
77  import com.eviware.soapui.support.xml.XmlUtils;
78  import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
79  import com.jgoodies.forms.builder.ButtonBarBuilder;
80  
81  /***
82   * DesktopPanel for WsdlGroovyTestSteps
83   * 
84   * @author Ole.Matzura
85   */
86  
87  public class WsdlMockOperationDesktopPanel extends ModelItemDesktopPanel<WsdlMockOperation>
88  {
89  	private JList responseList;
90  	private JComboBox interfaceCombo;
91  	private JComboBox operationCombo;
92  	private JComboBox dispatchCombo;
93  	private JPanel dispatchPanel;
94  	private InternalInterfaceListener interfaceListener = new InternalInterfaceListener();
95  	private InternalProjectListener projectListener = new InternalProjectListener();
96  	private WsdlInterface currentInterface;
97  	private JPanel groovyEditorPanel;
98  	private JPanel xpathEditorPanel;
99  	private JComboBox defaultResponseCombo;
100 	private ResponseListModel responseListModel;
101 	private GroovyEditor xpathEditor;
102 	private GroovyEditor groovyEditor;
103 	private JComponentInspector dispatchInspector;
104 
105 	public WsdlMockOperationDesktopPanel(WsdlMockOperation mockOperation)
106 	{
107 		super( mockOperation );
108 		
109 		buildUI();
110 		setPreferredSize( new Dimension( 600, 440 ));
111 		
112 		mockOperation.getMockService().getProject().addProjectListener( projectListener );
113 		
114 		WsdlOperation operation = getModelItem().getOperation();
115 		if( operation != null )
116 		{
117 			currentInterface = operation.getInterface();
118 			currentInterface.addInterfaceListener( interfaceListener );
119 		}
120 	}
121 
122 	private void buildUI()
123 	{
124 		add( buildToolbar(), BorderLayout.NORTH );
125 		
126       JInspectorPanel inspectorPanel = new JInspectorPanel( buildResponseList() );
127       inspectorPanel.setDefaultDividerLocation( 0.5F );
128       dispatchInspector = new JComponentInspector( 
129 				      			buildDispatchEditor(), "Dispatch (" + getModelItem().getDispatchStyle().toString() + ")", 
130 				      			"Configures current dispatch style", true );
131 		inspectorPanel.addInspector( dispatchInspector);
132       inspectorPanel.activate( dispatchInspector );
133 		
134       add( inspectorPanel, BorderLayout.CENTER );
135 	}
136 
137 	private JComponent buildResponseList()
138 	{
139 		responseListModel = new ResponseListModel();
140 		responseList = new JList( responseListModel );
141 		responseList.addMouseListener( new ModelItemListMouseListener() {
142 
143 			@Override
144 			protected ActionList getActionsForRow( JList list, int row )
145 			{
146 				ActionList actions = super.getActionsForRow( list, row );
147 				
148 				actions.insertAction( SwingActionDelegate.createDelegate( NewMockResponseAction.SOAPUI_ACTION_ID, getModelItem(), null, 
149 							"/addToMockService.gif"	), 0 );
150 				
151 				actions.insertAction( SwingActionDelegate.createDelegate( OpenRequestForMockOperationAction.SOAPUI_ACTION_ID, getModelItem(), null, 
152 							"/open_request.gif"), 1 );
153 				
154 				if( actions.getActionCount() > 2 )
155 					actions.insertAction( ActionSupport.SEPARATOR_ACTION, 2 );
156 				
157 				return actions;
158 			}
159 		} );
160 		responseList.setCellRenderer( new ResponseListCellRenderer() );
161 		
162 		JScrollPane scrollPane = new JScrollPane( responseList );
163 		JTabbedPane tabs = new JTabbedPane();
164 		tabs.addTab( "MockResponses", UISupport.buildPanelWithToolbar( buildMockResponseListToolbar(), scrollPane ));
165 		
166 		return UISupport.createTabPanel( tabs, true );
167 	}
168 	
169 	private JComponent buildMockResponseListToolbar()
170 	{
171 		JXToolBar toolbar = UISupport.createToolbar();
172 		toolbar.add( UISupport.createToolbarButton( 
173 					SwingActionDelegate.createDelegate( NewMockResponseAction.SOAPUI_ACTION_ID, getModelItem(), 
174 								null, "/mockResponse.gif" )));
175 
176 		return toolbar;
177 	}
178 
179 	private JComponent buildDispatchEditor()
180 	{
181 		buildGroovyEditor();
182 		buildXPathEditor();
183 		
184 		dispatchPanel = new JPanel( new BorderLayout() );
185 		dispatchPanel.setOpaque( true );
186 		ButtonBarBuilder builder = new ButtonBarBuilder();
187 		builder.addFixed( new JLabel( "Dispatch: ") );
188 		builder.addRelatedGap();
189 		dispatchCombo = new JComboBox( new Object[] { "Sequence", "Random", "XPath", "Script"} );
190 		
191 		dispatchCombo.addItemListener( new ItemListener() {
192 
193 			public void itemStateChanged( ItemEvent e )
194 			{
195 				if( dispatchPanel.getComponentCount() > 1 )
196 					dispatchPanel.remove( 1 );
197 				
198 				String item = ( String ) dispatchCombo.getSelectedItem();
199 				if( item.equalsIgnoreCase( "Script" ))
200 				{
201 					getModelItem().setDispatchStyle( DispatchStyleConfig.SCRIPT );
202 					dispatchPanel.add( groovyEditorPanel );
203 					groovyEditor.getEditArea().setText( getModelItem().getDispatchPath() );
204 					defaultResponseCombo.setEnabled( true );
205 				}
206 				else if( item.equalsIgnoreCase( "XPath" ))
207 				{
208 					getModelItem().setDispatchStyle( DispatchStyleConfig.XPATH );
209 					dispatchPanel.add( xpathEditorPanel );
210 					xpathEditor.getEditArea().setText( getModelItem().getDispatchPath() );
211 					defaultResponseCombo.setEnabled( true );
212 				}
213 				else if( item.equalsIgnoreCase( "Sequence" ))
214 				{
215 					getModelItem().setDispatchStyle( DispatchStyleConfig.SEQUENCE );
216 					defaultResponseCombo.setEnabled( false );
217 				}
218 				else if( item.equalsIgnoreCase( "Random" ))
219 				{
220 					getModelItem().setDispatchStyle( DispatchStyleConfig.RANDOM );
221 					defaultResponseCombo.setEnabled( false );
222 				}
223 				
224 				dispatchPanel.revalidate();
225 				dispatchPanel.repaint();
226 				
227 				Enum dispatchStyle = getModelItem().getDispatchStyle();
228 				if( dispatchInspector != null && dispatchStyle != null )
229 					dispatchInspector.setTitle( "Dispatch (" + dispatchStyle + ")" );
230 			}} );
231 		
232 		builder.addFixed( dispatchCombo );
233 		
234 		builder.addUnrelatedGap();
235 		builder.addFixed( new JLabel( "Default Response: ") );
236 		builder.addRelatedGap();
237 		
238 		ModelItemNames<MockResponse> names = new ModelItemNames<MockResponse>(getModelItem().getMockResponses());
239 		defaultResponseCombo = new JComboBox( new ExtendedComboBoxModel( names.getNames() ) );
240 		defaultResponseCombo.setPreferredSize( new Dimension( 150, 20 ) );
241 		defaultResponseCombo.addItemListener( new ItemListener() {
242 
243 			public void itemStateChanged( ItemEvent e )
244 			{
245 				Object selectedItem = defaultResponseCombo.getSelectedItem();
246 				getModelItem().setDefaultResponse( ( String ) selectedItem );
247 			}} );
248 		
249 		builder.addFixed( defaultResponseCombo );
250 		builder.setBorder( BorderFactory.createEmptyBorder( 2, 3, 3, 3 ) );
251 		
252 		dispatchPanel.add( builder.getPanel(), BorderLayout.NORTH );
253 		
254 		// init data
255 		defaultResponseCombo.setSelectedItem( getModelItem().getDefaultResponse() );
256 		DispatchStyleConfig.Enum dispatchStyle = getModelItem().getDispatchStyle();
257 		if( dispatchStyle.equals( DispatchStyleConfig.SEQUENCE ))
258 		{
259 			dispatchCombo.setSelectedItem( "Sequence" );
260 			defaultResponseCombo.setEnabled( false );
261 		}
262 		else if( dispatchStyle.equals( DispatchStyleConfig.RANDOM ))
263 		{
264 			dispatchCombo.setSelectedItem( "Random" );
265 			defaultResponseCombo.setEnabled( false );
266 		}
267 		else if( dispatchStyle.equals( DispatchStyleConfig.SCRIPT ))
268 		{
269 			dispatchCombo.setSelectedItem( "Script" );
270 		}
271 		else if( dispatchStyle.equals( DispatchStyleConfig.XPATH ))
272 		{
273 			dispatchCombo.setSelectedItem( "XPath" );
274 		}
275 		
276 		return dispatchPanel;
277 	}
278 
279 	private void buildXPathEditor()
280 	{
281 		xpathEditorPanel = new JPanel( new BorderLayout() );
282 		DispatchXPathGroovyEditorModel editorModel = new DispatchXPathGroovyEditorModel();
283 		xpathEditor = new GroovyEditor( editorModel );
284 		xpathEditorPanel.add( new JScrollPane( xpathEditor), BorderLayout.CENTER );
285 		xpathEditorPanel.add( buildXPathEditorToolbar( editorModel ), BorderLayout.PAGE_START );
286 	}
287 	
288 	public GroovyEditor getXPathEditor()
289 	{
290 		return xpathEditor;
291 	}
292 
293 	protected JXToolBar buildXPathEditorToolbar( DispatchXPathGroovyEditorModel editorModel )
294 	{
295 		JXToolBar toolbar = UISupport.createToolbar();
296 		toolbar.addSpace( 3 );
297 		toolbar.addFixed( UISupport.createToolbarButton( editorModel.getRunAction() ));
298 		toolbar.addGlue();
299 		toolbar.addFixed( createActionButton( new ShowOnlineHelpAction(HelpUrls.MOCKOPERATION_XPATHDISPATCH_HELP_URL), true ) );
300 		return toolbar;
301 	}
302 
303 	private void buildGroovyEditor()
304 	{
305 		groovyEditorPanel = new JPanel( new BorderLayout() );
306 		DispatchScriptGroovyEditorModel editorModel = new DispatchScriptGroovyEditorModel();
307 		groovyEditor = new GroovyEditor( editorModel );
308 		JScrollPane scrollPane = new JScrollPane( groovyEditor );
309 		groovyEditorPanel.add( scrollPane, BorderLayout.CENTER );
310 		UISupport.addPreviewCorner( scrollPane, true );
311 		groovyEditorPanel.add( buildGroovyEditorToolbar( editorModel ), BorderLayout.PAGE_START );
312 	}
313 
314 	protected JXToolBar buildGroovyEditorToolbar( DispatchScriptGroovyEditorModel editorModel )
315 	{
316 		JXToolBar toolbar = UISupport.createToolbar();
317 		toolbar.addSpace( 3 );
318 		toolbar.addFixed( UISupport.createToolbarButton( editorModel.getRunAction() ));
319 		toolbar.addGlue();
320 		
321 		JLabel label = new JLabel("<html>Script is invoked with <code>log</code>, <code>context</code>, " +
322 				"<code>requestContext</code>, <code>mockRequest</code> and <code>mockOperation</code> variables</html>");
323 		label.setToolTipText( label.getText() );
324 		label.setMaximumSize( label.getPreferredSize() );
325 		
326 		toolbar.add( label);
327 		toolbar.addFixed( createActionButton( new ShowOnlineHelpAction(HelpUrls.MOCKOPERATION_SCRIPTDISPATCH_HELP_URL), true ) );
328 		return toolbar;
329 	}
330 
331 	private Component buildToolbar()
332 	{
333 		JXToolBar toolbar = UISupport.createToolbar();
334 		toolbar.addSpace( 3 );
335 		
336 		toolbar.addFixed( UISupport.createToolbarButton( 
337 					SwingActionDelegate.createDelegate( NewMockResponseAction.SOAPUI_ACTION_ID, getModelItem(), null, 
338 							"/addToMockService.gif"	)));
339 		toolbar.addFixed( UISupport.createToolbarButton(
340 					SwingActionDelegate.createDelegate( OpenRequestForMockOperationAction.SOAPUI_ACTION_ID, getModelItem(), null, 
341 								"/open_request.gif") ));
342 		toolbar.addUnrelatedGap();
343 		
344 		ModelItemNames<Interface> names = new ModelItemNames<Interface>(getModelItem().getMockService().getProject().getInterfaceList());
345 		interfaceCombo = new JComboBox( names.getNames() );
346 		interfaceCombo.setSelectedIndex( -1 );
347 		interfaceCombo.addItemListener( new InterfaceComboListener() );
348 		
349 		toolbar.addLabeledFixed( "Interface", interfaceCombo );
350 		toolbar.addUnrelatedGap();
351 		operationCombo = new JComboBox( new ExtendedComboBoxModel() );
352 		operationCombo.setPreferredSize( new Dimension( 150, 20 ) );
353 		operationCombo.addItemListener( new OperationComboListener() );
354 		
355 		toolbar.addLabeledFixed( "Operation", operationCombo );
356 		
357 		WsdlOperation operation = getModelItem().getOperation();
358 		interfaceCombo.setSelectedItem( operation == null ? null : operation.getInterface().getName() );
359 		operationCombo.setSelectedItem( operation == null ? null : operation.getName() );
360 		
361 		toolbar.addGlue();
362 		toolbar.addFixed( createActionButton( new ShowOnlineHelpAction(HelpUrls.MOCKOPERATION_HELP_URL), true ) );
363 			
364 		return toolbar;
365 	}
366 	
367 	public boolean onClose( boolean canCancel )
368 	{
369 		if( currentInterface != null )
370 			currentInterface.removeInterfaceListener( interfaceListener );
371 		
372 		getModelItem().getMockService().getProject().removeProjectListener( projectListener );
373 		responseListModel.release();
374 		
375 		groovyEditor.release();
376 		xpathEditor.release();
377 		
378 		return release();
379 	}
380 	
381 	public boolean dependsOn(ModelItem modelItem)
382 	{
383 		return modelItem == getModelItem() || modelItem == getModelItem().getMockService()
384 				|| modelItem == getModelItem().getMockService().getProject();
385 	}
386 	
387 	private final class OperationComboListener implements ItemListener
388 	{
389 		public void itemStateChanged( ItemEvent e )
390 		{
391 			WsdlInterface iface = getModelItem().getMockService().getProject().getInterfaceByName( interfaceCombo.getSelectedItem().toString() );
392 			WsdlOperation operation = iface.getOperationByName( operationCombo.getSelectedItem().toString() );
393 			getModelItem().setOperation( operation );
394 		}
395 	}
396 
397 	private final class InterfaceComboListener implements ItemListener
398 	{
399 		public void itemStateChanged( ItemEvent e )
400 		{
401 			if( currentInterface != null )
402 			{
403 				currentInterface.removeInterfaceListener( interfaceListener );
404 			}
405 			
406 			Object selectedItem = interfaceCombo.getSelectedItem();
407 			if( selectedItem == null )
408 			{
409 				operationCombo.setModel( new ExtendedComboBoxModel() );
410 				currentInterface = null;
411 			}
412 			else
413 			{
414 				currentInterface = getModelItem().getMockService().getProject().getInterfaceByName( selectedItem.toString() );
415 				ModelItemNames<Operation> names = new ModelItemNames<Operation>( currentInterface.getOperationList() );
416 				operationCombo.setModel( new ExtendedComboBoxModel( names.getNames()) );
417 				
418 				currentInterface.addInterfaceListener( interfaceListener );
419 			}
420 		}
421 	}
422 
423 	private final class InternalProjectListener extends ProjectListenerAdapter
424 	{
425 		@Override
426 		public void interfaceAdded( Interface iface )
427 		{
428 			interfaceCombo.addItem( iface.getName() );
429 		}
430 
431 		@Override
432 		public void interfaceRemoved( Interface iface )
433 		{
434 			if( interfaceCombo.getSelectedItem().equals( iface.getName() ))
435 			{
436 				getModelItem().setOperation( null );
437 			}
438 		}
439 	}
440 
441 	private final class InternalInterfaceListener extends InterfaceListenerAdapter
442 	{
443 		@Override
444 		public void operationAdded( Operation operation )
445 		{
446 			operationCombo.addItem( operation.getName() );
447 		}
448 
449 		@Override
450 		public void operationRemoved( Operation operation )
451 		{
452 			Object selectedItem = operationCombo.getSelectedItem();
453 			operationCombo.removeItem( operation.getName() );
454 			
455 			if( selectedItem.equals( operation.getName() ))
456 			{
457 				getModelItem().setOperation( null );
458 				interfaceCombo.setSelectedIndex( -1 );
459 			}
460 		}
461 
462 		@Override
463 		public void operationUpdated( Operation operation )
464 		{
465 			ExtendedComboBoxModel model = ((ExtendedComboBoxModel)operationCombo.getModel());
466 			int ix = model.getIndexOf( operation.getName() );
467 			if( ix != -1 )
468 			{
469 				model.setElementAt( operation.getName(), ix );
470 			}
471 		}
472 	}
473 
474 	public class DispatchScriptGroovyEditorModel implements GroovyEditorModel
475 	{
476 		private RunScriptAction runScriptAction = new RunScriptAction();
477 		
478 		public String[] getKeywords()
479 		{
480 			return new String[] { "mockRequest", "context", "requestContext", "log", "mockOperation" };
481 		}
482 
483 		public Action getRunAction()
484 		{
485 			return runScriptAction;
486 		}
487 
488 		public String getScript()
489 		{
490 			return getModelItem().getDispatchPath();
491 		}
492 
493 		public Settings getSettings()
494 		{
495 			return getModelItem().getSettings();
496 		}
497 
498 		public void setScript( String text )
499 		{
500 			getModelItem().setDispatchPath( text );
501 		}
502 
503 		public String getScriptName()
504 		{
505 			return "Dispatch";
506 		}
507 	}
508 	
509 	public class DispatchXPathGroovyEditorModel implements GroovyEditorModel
510 	{
511 		private RunXPathAction runXPathAction = new RunXPathAction();
512 
513 		public String[] getKeywords()
514 		{
515 			return new String[] { "define", "namespace"};
516 		}
517 
518 		public Action getRunAction()
519 		{
520 			return runXPathAction;
521 		}
522 
523 		public String getScript()
524 		{
525 			return getModelItem().getDispatchPath();
526 		}
527 
528 		public Settings getSettings()
529 		{
530 			return getModelItem().getSettings();
531 		}
532 
533 		public void setScript( String text )
534 		{
535 			getModelItem().setDispatchPath( text );
536 		}
537 
538 		public String getScriptName()
539 		{
540 			return null;
541 		}
542 	}
543 
544 	public class ResponseListModel extends AbstractListModel implements ListModel, MockServiceListener, PropertyChangeListener
545 	{
546 		private List<WsdlMockResponse> responses = new ArrayList<WsdlMockResponse>();
547 		
548 		public ResponseListModel()
549 		{
550 			for( int c = 0; c < getModelItem().getMockResponseCount(); c++ )
551 			{
552 				WsdlMockResponse mockResponse = ( WsdlMockResponse ) getModelItem().getMockResponseAt( c );
553 				mockResponse.addPropertyChangeListener( this );
554 				
555 				responses.add( mockResponse);
556 			}
557 			
558 			getModelItem().getMockService().addMockServiceListener( this );
559 		}
560 		
561 		public Object getElementAt( int arg0 )
562 		{
563 			return responses.get( arg0 );
564 		}
565 
566 		public int getSize()
567 		{
568 			return responses.size();
569 		}
570 
571 		public void mockOperationAdded( MockOperation operation )
572 		{
573 			
574 		}
575 
576 		public void mockOperationRemoved( MockOperation operation )
577 		{
578 			
579 		}
580 
581 		public void mockResponseAdded( MockResponse response )
582 		{
583 			if( response.getMockOperation() != getModelItem() )
584 				return;
585 			
586 			responses.add( ( WsdlMockResponse ) response );
587 			response.addPropertyChangeListener( this );
588 			fireIntervalAdded( this, responses.size()-1, responses.size()-1 );
589 			
590 			defaultResponseCombo.addItem( response.getName() );
591 		}
592 
593 		public void mockResponseRemoved( MockResponse response )
594 		{
595 			if( response.getMockOperation() != getModelItem() )
596 				return;
597 			
598 			int ix = responses.indexOf( response );
599 			responses.remove( ix );
600 			response.removePropertyChangeListener( this );
601 			fireIntervalRemoved( this, ix, ix );
602 			
603 			defaultResponseCombo.removeItem( response.getName() );
604 		}
605 
606 		public void propertyChange( PropertyChangeEvent arg0 )
607 		{
608 			if( arg0.getPropertyName().equals( WsdlMockOperation.NAME_PROPERTY ))
609 			{
610 				int ix = responses.indexOf( arg0.getSource() );
611 				fireContentsChanged( this, ix, ix );
612 				
613 				ExtendedComboBoxModel model = ( ExtendedComboBoxModel ) defaultResponseCombo.getModel();
614 				model.setElementAt( arg0.getNewValue(), ix );
615 				
616 				if( model.getSelectedItem().equals( arg0.getOldValue()  ))
617 						model.setSelectedItem( arg0.getNewValue() );
618 			}
619 		}
620 		
621 		public void release()
622 		{
623 			for( WsdlMockResponse operation : responses )
624 			{
625 				operation.removePropertyChangeListener( this );
626 			}
627 			
628 			getModelItem().getMockService().removeMockServiceListener( this );
629 		}
630 	}
631 	
632 	private final static class ResponseListCellRenderer extends JLabel implements ListCellRenderer
633 	{
634 		public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
635 				boolean cellHasFocus)
636 		{
637 			MockResponse testStep = (MockResponse) value;
638 			setText(testStep.getName());
639 			setIcon(testStep.getIcon());
640 
641 			if (isSelected)
642 			{
643 				setBackground(list.getSelectionBackground());
644 				setForeground(list.getSelectionForeground());
645 			}
646 			else
647 			{
648 				setBackground(list.getBackground());
649 				setForeground(list.getForeground());
650 			}
651 
652 			setEnabled(list.isEnabled());
653 			setFont(list.getFont());
654 			setOpaque(true);
655 			setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
656 
657 			return this;
658 		}
659 	}
660 	
661 	private class RunScriptAction extends AbstractAction
662 	{
663 		public RunScriptAction()
664 		{
665 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_groovy_script.gif" ));
666 			putValue( Action.SHORT_DESCRIPTION, "Runs this script using a mockRequest and context" );
667 		}
668 		
669 		public void actionPerformed( ActionEvent e )
670 		{
671 			WsdlMockResult lastMockResult = getModelItem().getLastMockResult();
672 			WsdlMockRequest mockRequest = lastMockResult == null ? null : lastMockResult.getMockRequest();
673 
674 			try
675 			{
676 				Object retVal = getModelItem().evaluateDispatchScript( mockRequest );
677 				UISupport.showInfoMessage( "Script returned [" + retVal + "]" );
678 			}
679 			catch( Exception e1 )
680 			{
681 				UISupport.showErrorMessage( e1 );
682 			}
683 		}}
684 	
685 	private class RunXPathAction extends AbstractAction
686 	{
687 		public RunXPathAction()
688 		{
689 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_groovy_script.gif" ));
690 			putValue( Action.SHORT_DESCRIPTION, "Evaluates this xpath expression against the latest request" );
691 		}
692 		
693 		public void actionPerformed( ActionEvent e )
694 		{
695 			WsdlMockResult lastMockResult = getModelItem().getLastMockResult();
696 			if( lastMockResult == null )
697 			{
698 				UISupport.showErrorMessage( "Missing last request to select from" );
699 				return;
700 			}
701 			
702 			try
703 			{
704 				XmlObject[] retVal = getModelItem().evaluateDispatchXPath( lastMockResult.getMockRequest() );
705 				StringList list = new StringList();
706 				for( XmlObject xmlObject : retVal )
707 				{
708 					list.add( XmlUtils.getNodeValue( xmlObject.getDomNode() ) );
709 				}
710 				
711 				UISupport.showInfoMessage( "XPath returned " + list.toString() );
712 			}
713 			catch( Exception e1 )
714 			{
715 				SoapUI.logError( e1 );
716 			}
717 		}}
718 }