View Javadoc

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