1
2
3
4
5
6
7
8
9
10
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
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 }