View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2008 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.mock;
14  
15  import com.eviware.soapui.SoapUI;
16  import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
17  import com.eviware.soapui.impl.wsdl.actions.mockservice.AddNewMockOperationAction;
18  import com.eviware.soapui.impl.wsdl.actions.mockservice.MockServiceOptionsAction;
19  import com.eviware.soapui.impl.wsdl.mock.WsdlMockOperation;
20  import com.eviware.soapui.impl.wsdl.mock.WsdlMockRunContext;
21  import com.eviware.soapui.impl.wsdl.mock.WsdlMockRunner;
22  import com.eviware.soapui.impl.wsdl.mock.WsdlMockService;
23  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.AbstractGroovyEditorModel;
24  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.PropertyHolderTable;
25  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
26  import com.eviware.soapui.model.ModelItem;
27  import com.eviware.soapui.model.mock.*;
28  import com.eviware.soapui.model.support.MockRunListenerAdapter;
29  import com.eviware.soapui.settings.UISettings;
30  import com.eviware.soapui.support.DocumentListenerAdapter;
31  import com.eviware.soapui.support.StringUtils;
32  import com.eviware.soapui.support.Tools;
33  import com.eviware.soapui.support.UISupport;
34  import com.eviware.soapui.support.action.swing.ActionList;
35  import com.eviware.soapui.support.action.swing.DefaultActionList;
36  import com.eviware.soapui.support.action.swing.SwingActionDelegate;
37  import com.eviware.soapui.support.components.*;
38  import com.eviware.soapui.support.swing.AbstractListMouseListener;
39  import com.eviware.soapui.support.swing.ModelItemListKeyListener;
40  import com.eviware.soapui.support.swing.ModelItemListMouseListener;
41  import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
42  
43  import javax.swing.*;
44  import javax.swing.text.Document;
45  import java.awt.*;
46  import java.awt.event.ActionEvent;
47  import java.awt.event.ActionListener;
48  import java.beans.PropertyChangeEvent;
49  import java.beans.PropertyChangeListener;
50  import java.text.SimpleDateFormat;
51  import java.util.*;
52  import java.util.List;
53  
54  /***
55   * DesktopPanel for WsdlMockServices
56   *
57   * @author ole.matzura
58   */
59  
60  public class WsdlMockServiceDesktopPanel extends ModelItemDesktopPanel<WsdlMockService>
61  {
62     private JButton runButton;
63     private WsdlMockRunner mockRunner;
64     private JButton stopButton;
65     private JProgressBar progressBar;
66     private LogListModel logListModel;
67     private JList testLogList;
68     private JCheckBox enableLogCheckBox;
69     private JScrollPane logScrollPane;
70     private JList operationList;
71     private InternalMockRunListener mockRunListener;
72     private PropertyHolderTable propertiesTable;
73     private JUndoableTextArea descriptionArea;
74     private JButton showWsdlButton;
75     private JButton optionsButton;
76     private JLabel runInfoLabel;
77     private GroovyEditorComponent startGroovyEditor;
78     private GroovyEditorComponent stopGroovyEditor;
79     private GroovyEditorComponent onRequestGroovyEditor;
80     private GroovyEditorComponent afterRequestGroovyEditor;
81  
82     public WsdlMockServiceDesktopPanel( WsdlMockService mockService )
83     {
84        super( mockService );
85        buildUI();
86  
87        setPreferredSize( new Dimension( 400, 500 ) );
88  
89        mockRunListener = new InternalMockRunListener();
90        mockService.addMockRunListener( mockRunListener );
91     }
92  
93     public boolean onClose( boolean canCancel )
94     {
95        if( mockRunner != null && mockRunner.isRunning() && canCancel )
96        {
97           if( !UISupport.confirm( "Close and stop MockService", "Close MockService" ) )
98           {
99              return false;
100          }
101       }
102 
103       if( mockRunner != null )
104       {
105          if( mockRunner.isRunning() )
106             mockRunner.stop();
107 
108          mockRunner.release();
109       }
110 
111       getModelItem().removeMockRunListener( mockRunListener );
112       ( (OperationListModel) operationList.getModel() ).release();
113 
114       logListModel.clear();
115       propertiesTable.release();
116 
117       startGroovyEditor.getEditor().release();
118       stopGroovyEditor.getEditor().release();
119 
120       return release();
121    }
122 
123    public boolean dependsOn( ModelItem modelItem )
124    {
125       return modelItem == getModelItem() || modelItem == getModelItem().getProject();
126    }
127 
128    private void buildUI()
129    {
130       add( buildToolbar(), BorderLayout.NORTH );
131 
132       JInspectorPanel inspectorPanel = JInspectorPanelFactory.build( buildContent() );
133       inspectorPanel.setDefaultDividerLocation( 0.5F );
134       inspectorPanel.addInspector( new JComponentInspector<JComponent>(
135               buildLog(), "Message Log", "A log of processed requests and their responses", true ) );
136 
137       inspectorPanel.setCurrentInspector( "Message Log" );
138 
139       add( inspectorPanel.getComponent(), BorderLayout.CENTER );
140       add( new JLabel( "--" ), BorderLayout.PAGE_END );
141    }
142 
143    public boolean logIsEnabled()
144    {
145       return enableLogCheckBox.isSelected();
146    }
147 
148    private JComponent buildContent()
149    {
150       JTabbedPane tabs = new JTabbedPane();
151       JInspectorPanel inspectorPanel = JInspectorPanelFactory.build( buildOperationList() );
152 
153       tabs.addTab( "Operations", inspectorPanel.getComponent() );
154       addTabs( tabs, inspectorPanel );
155 
156       if( StringUtils.hasContent( getModelItem().getDescription() ) && getModelItem().getSettings().getBoolean( UISettings.SHOW_DESCRIPTIONS ) )
157       {
158          inspectorPanel.setCurrentInspector( "Description" );
159       }
160 
161       return UISupport.createTabPanel( tabs, true );
162    }
163 
164    protected void addTabs( JTabbedPane tabs, JInspectorPanel inspectorPanel )
165    {
166       inspectorPanel.addInspector( new JFocusableComponentInspector<JPanel>( buildDescriptionPanel(),
167               descriptionArea, "Description", "A description for this MockService", true ) );
168       inspectorPanel.addInspector( new JComponentInspector<JComponent>( buildPropertiesPanel(), "Properties", "Properties for this MockService", true ) );
169       inspectorPanel.addInspector( new GroovyEditorInspector( buildStartScriptPanel(), "Start Script", "A Groovy script to run when starting the MockService" ) );
170       inspectorPanel.addInspector( new GroovyEditorInspector( buildStopScriptPanel(), "Stop Script", "A Groovy script to run when stopping the MockService" ) );
171       inspectorPanel.addInspector( new GroovyEditorInspector( buildOnRequestScriptPanel(), "OnRequest Script", "A Groovy script to run when receiving a request before it is dispatched" ) );
172       inspectorPanel.addInspector( new GroovyEditorInspector( buildAfterRequestScriptPanel(), "AfterRequest Script", "A Groovy script to run after a request has been dispatched" ) );
173    }
174 
175    protected JComponent buildOperationList()
176    {
177       operationList = new JList( new OperationListModel() );
178       operationList.addMouseListener( new ModelItemListMouseListener()
179       {
180          private ActionList defaultActions;
181 
182          protected ActionList getDefaultActions()
183          {
184             if( defaultActions == null )
185             {
186                defaultActions = new DefaultActionList();
187                defaultActions.addAction( SwingActionDelegate.createDelegate( AddNewMockOperationAction.SOAPUI_ACTION_ID, getModelItem(), null,
188                        null ) );
189             }
190 
191             return defaultActions;
192          }
193       } );
194       operationList.setCellRenderer( new OperationListCellRenderer() );
195       operationList.addKeyListener( new ModelItemListKeyListener()
196       {
197 
198          @Override
199          public ModelItem getModelItemAt( int ix )
200          {
201             return getModelItem().getMockOperationAt( ix );
202          }
203       } );
204 
205       JScrollPane scrollPane = new JScrollPane( operationList );
206       return UISupport.buildPanelWithToolbar( buildMockOperationListToolbar(), scrollPane );
207    }
208 
209    private JComponent buildMockOperationListToolbar()
210    {
211       JXToolBar toolbar = UISupport.createToolbar();
212       toolbar.add( UISupport.createToolbarButton(
213               SwingActionDelegate.createDelegate( AddNewMockOperationAction.SOAPUI_ACTION_ID, getModelItem(),
214                       null, "/mockOperation.gif" ) ) );
215 
216       return toolbar;
217    }
218 
219    protected JComponent buildPropertiesPanel()
220    {
221       JPanel panel = new JPanel( new BorderLayout() );
222       propertiesTable = new PropertyHolderTable( getModelItem() );
223       panel.add( new JScrollPane( propertiesTable ), BorderLayout.CENTER );
224       return panel;
225    }
226 
227    protected GroovyEditorComponent buildStartScriptPanel()
228    {
229       startGroovyEditor = new GroovyEditorComponent( new StartScriptGroovyEditorModel(), null );
230       return startGroovyEditor;
231    }
232 
233    protected GroovyEditorComponent buildStopScriptPanel()
234    {
235       stopGroovyEditor = new GroovyEditorComponent( new StopScriptGroovyEditorModel(), null );
236       return stopGroovyEditor;
237    }
238 
239    protected GroovyEditorComponent buildOnRequestScriptPanel()
240    {
241       onRequestGroovyEditor = new GroovyEditorComponent( new OnRequestScriptGroovyEditorModel(), null );
242       return onRequestGroovyEditor;
243    }
244 
245    protected GroovyEditorComponent buildAfterRequestScriptPanel()
246    {
247       afterRequestGroovyEditor = new GroovyEditorComponent( new AfterRequestScriptGroovyEditorModel(), null );
248       return afterRequestGroovyEditor;
249    }
250 
251    protected JPanel buildDescriptionPanel()
252    {
253       JPanel panel = new JPanel( new BorderLayout() );
254       descriptionArea = new JUndoableTextArea( getModelItem().getDescription() );
255       descriptionArea.getDocument().addDocumentListener( new DocumentListenerAdapter()
256       {
257          public void update( Document document )
258          {
259             getModelItem().setDescription( descriptionArea.getText() );
260          }
261       } );
262 
263       panel.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2 ) );
264       UISupport.addTitledBorder( panel, "MockService Description" );
265       panel.add( new JScrollPane( descriptionArea ), BorderLayout.CENTER );
266 
267       return panel;
268    }
269 
270    protected JComponent buildLog()
271    {
272       JPanel panel = new JPanel( new BorderLayout() );
273       JXToolBar builder = UISupport.createToolbar();
274 
275       enableLogCheckBox = new JCheckBox( " ", true );
276       enableLogCheckBox.addActionListener( new ActionListener()
277       {
278 
279          public void actionPerformed( ActionEvent arg0 )
280          {
281             testLogList.setEnabled( enableLogCheckBox.isSelected() );
282             if( mockRunner != null )
283                mockRunner.setLogEnabled( enableLogCheckBox.isSelected() );
284 
285             // border needs to be repainted..
286             logScrollPane.repaint();
287          }
288       } );
289       enableLogCheckBox.setOpaque( false );
290 
291       builder.addFixed( enableLogCheckBox );
292       builder.addRelatedGap();
293       builder.addFixed( new JLabel( "Enable" ) );
294       builder.addRelatedGap();
295       addLogActions( builder );
296 
297       builder.addGlue();
298       builder.setBorder( BorderFactory.createEmptyBorder( 2, 3, 3, 3 ) );
299 
300       panel.add( builder, BorderLayout.NORTH );
301 
302       logListModel = new LogListModel();
303       testLogList = new JList( logListModel );
304       testLogList.setCellRenderer( new LogCellRenderer() );
305       testLogList.setPrototypeCellValue( "Testing 123" );
306       testLogList.setFixedCellWidth( -1 );
307       testLogList.addMouseListener( new LogListMouseListener() );
308       testLogList.setBorder( BorderFactory.createLineBorder( Color.GRAY ) );
309 
310       logScrollPane = new JScrollPane( testLogList );
311 
312       panel.add( logScrollPane, BorderLayout.CENTER );
313 
314       return panel;
315    }
316 
317    protected void addLogActions( JXToolBar builder )
318    {
319       builder.addFixed( UISupport.createToolbarButton( new ClearLogAction() ) );
320       builder.addRelatedGap();
321       builder.addFixed( UISupport.createToolbarButton( new SetLogOptionsAction() ) );
322    }
323 
324    protected JXToolBar buildToolbar()
325    {
326       JXToolBar toolbar = UISupport.createToolbar();
327 
328       runButton = createActionButton( new RunMockServiceAction(), true );
329       stopButton = createActionButton( new StopMockServiceAction(), false );
330       optionsButton = createActionButton( SwingActionDelegate.createDelegate(
331               new MockServiceOptionsAction(), getModelItem(), null, "/options.gif" ), true );
332       showWsdlButton = createActionButton( new ShowWsdlAction(), false );
333 
334       toolbar.addFixed( runButton );
335       toolbar.addFixed( stopButton );
336       toolbar.addFixed( showWsdlButton );
337       toolbar.addFixed( optionsButton );
338 
339       toolbar.addGlue();
340 
341       runInfoLabel = new JLabel( "", SwingConstants.RIGHT );
342       toolbar.addFixed( UISupport.setFixedSize( runInfoLabel, 200, 20 ) );
343       toolbar.addRelatedGap();
344 
345       progressBar = new JProgressBar();
346       JPanel progressBarPanel = UISupport.createProgressBarPanel( progressBar, 2, false );
347       progressBarPanel.setPreferredSize( new Dimension( 60, 20 ) );
348 
349       toolbar.addFixed( progressBarPanel );
350       toolbar.addRelatedGap();
351 
352       toolbar.addFixed( createActionButton( new ShowOnlineHelpAction( HelpUrls.MOCKSERVICE_HELP_URL ), true ) );
353 
354       return toolbar;
355    }
356 
357    public void startMockService()
358    {
359       if( ( mockRunner != null && mockRunner.isRunning() ) || SoapUI.getMockEngine().hasRunningMock( getModelItem() ) )
360       {
361          UISupport.showErrorMessage( "MockService is already running" );
362       }
363       else
364       {
365          if( mockRunner != null )
366             mockRunner.release();
367 
368          try
369          {
370             getModelItem().start();
371          }
372          catch( Exception e )
373          {
374             UISupport.showErrorMessage( e );
375             return;
376          }
377       }
378    }
379 
380    private final class InternalMockRunListener extends MockRunListenerAdapter
381    {
382       @Override
383       public void onMockRunnerStart( MockRunner runner )
384       {
385          mockRunner = (WsdlMockRunner) runner;
386          mockRunner.setMaxResults( logListModel.getMaxSize() );
387          mockRunner.setLogEnabled( enableLogCheckBox.isSelected() );
388 
389          progressBar.setIndeterminate( true );
390 
391          runButton.setEnabled( false );
392          stopButton.setEnabled( true );
393          optionsButton.setEnabled( false );
394          showWsdlButton.setEnabled( true );
395 
396          runInfoLabel.setText( "running on port " + getModelItem().getPort() );
397       }
398 
399       @Override
400       public void onMockRunnerStop( MockRunner mockRunner )
401       {
402          progressBar.setIndeterminate( false );
403 
404          runButton.setEnabled( true );
405          stopButton.setEnabled( false );
406          optionsButton.setEnabled( true );
407          showWsdlButton.setEnabled( false );
408 
409          runInfoLabel.setText( "" );
410       }
411 
412       public void onMockResult( MockResult result )
413       {
414          if( logIsEnabled() )
415          {
416             logListModel.addElement( result );
417          }
418       }
419    }
420 
421    public class OperationListModel extends AbstractListModel implements ListModel, MockServiceListener, PropertyChangeListener
422    {
423       private List<WsdlMockOperation> operations = new ArrayList<WsdlMockOperation>();
424 
425       public OperationListModel()
426       {
427          for( int c = 0; c < getModelItem().getMockOperationCount(); c++ )
428          {
429             WsdlMockOperation mockOperation = getModelItem().getMockOperationAt( c );
430             mockOperation.addPropertyChangeListener( this );
431 
432             operations.add( mockOperation );
433          }
434 
435          getModelItem().addMockServiceListener( this );
436       }
437 
438       public Object getElementAt( int arg0 )
439       {
440          return operations.get( arg0 );
441       }
442 
443       public int getSize()
444       {
445          return operations.size();
446       }
447 
448       public void mockOperationAdded( MockOperation operation )
449       {
450          operations.add( (WsdlMockOperation) operation );
451          operation.addPropertyChangeListener( this );
452          fireIntervalAdded( this, operations.size() - 1, operations.size() - 1 );
453       }
454 
455       public void mockOperationRemoved( MockOperation operation )
456       {
457          int ix = operations.indexOf( operation );
458          operations.remove( ix );
459          operation.removePropertyChangeListener( this );
460          fireIntervalRemoved( this, ix, ix );
461       }
462 
463       public void mockResponseAdded( MockResponse request )
464       {
465       }
466 
467       public void mockResponseRemoved( MockResponse request )
468       {
469       }
470 
471       public void propertyChange( PropertyChangeEvent arg0 )
472       {
473          if( arg0.getPropertyName().equals( WsdlMockOperation.NAME_PROPERTY ) )
474          {
475             int ix = operations.indexOf( arg0.getSource() );
476             fireContentsChanged( this, ix, ix );
477          }
478       }
479 
480       public void release()
481       {
482          for( WsdlMockOperation operation : operations )
483          {
484             operation.removePropertyChangeListener( this );
485          }
486 
487          getModelItem().removeMockServiceListener( this );
488       }
489    }
490 
491    private final static class OperationListCellRenderer extends JLabel implements ListCellRenderer
492    {
493       public Component getListCellRendererComponent(
494               JList list, Object value, int index, boolean isSelected,
495               boolean cellHasFocus
496       )
497       {
498          MockOperation testStep = (MockOperation) value;
499          setText( testStep.getName() );
500          setIcon( testStep.getIcon() );
501 
502          if( isSelected )
503          {
504             setBackground( list.getSelectionBackground() );
505             setForeground( list.getSelectionForeground() );
506          }
507          else
508          {
509             setBackground( list.getBackground() );
510             setForeground( list.getForeground() );
511          }
512 
513          setEnabled( list.isEnabled() );
514          setFont( list.getFont() );
515          setOpaque( true );
516          setBorder( BorderFactory.createEmptyBorder( 3, 3, 3, 3 ) );
517 
518          return this;
519       }
520    }
521 
522    public class RunMockServiceAction extends AbstractAction
523    {
524       public RunMockServiceAction()
525       {
526          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/submit_request.gif" ) );
527          putValue( Action.SHORT_DESCRIPTION, "Starts this MockService on the specified port and endpoint" );
528          putValue( Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "alt ENTER" ) );
529       }
530 
531       public void actionPerformed( ActionEvent arg0 )
532       {
533          startMockService();
534       }
535    }
536 
537    public class ShowWsdlAction extends AbstractAction
538    {
539       public ShowWsdlAction()
540       {
541          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/interface.gif" ) );
542          putValue( Action.SHORT_DESCRIPTION, "Opens the root WSDL page in a browser" );
543       }
544 
545       public void actionPerformed( ActionEvent arg0 )
546       {
547          WsdlMockService mockService = getModelItem();
548          Tools.openURL( mockService.getLocalEndpoint() + "?WSDL" );
549       }
550    }
551 
552    public class StopMockServiceAction extends AbstractAction
553    {
554       public StopMockServiceAction()
555       {
556          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/cancel_request.gif" ) );
557          putValue( Action.SHORT_DESCRIPTION, "Stops this MockService on the specified port and endpoint" );
558       }
559 
560       public void actionPerformed( ActionEvent arg0 )
561       {
562          if( mockRunner == null )
563          {
564             UISupport.showErrorMessage( "MockService is not running" );
565          }
566          else
567          {
568             mockRunner.stop();
569             mockRunner.release();
570             mockRunner = null;
571          }
572       }
573    }
574 
575    private static final class LogCellRenderer extends JLabel implements ListCellRenderer
576    {
577       private SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSS" );
578 
579       public LogCellRenderer()
580       {
581          setOpaque( true );
582          setBorder( BorderFactory.createEmptyBorder( 3, 3, 3, 3 ) );
583       }
584 
585       public Component getListCellRendererComponent(
586               JList list, Object value, int index, boolean isSelected,
587               boolean cellHasFocus
588       )
589       {
590          if( value instanceof String )
591          {
592             setText( value.toString() );
593          }
594          else if( value instanceof MockResult )
595          {
596             MockResult result = (MockResult) value;
597             String msg = dateFormat.format( new Date( result.getTimestamp() ) );
598             MockResponse mockResponse = result.getMockResponse();
599 
600             if( mockResponse == null )
601             {
602                msg += ": [dispatch error; missing response]";
603             }
604             else
605             {
606                try
607                {
608                   msg += ": [" + mockResponse.getMockOperation().getName();
609                }
610                catch( Throwable e )
611                {
612                   msg += ": [removed operation?]";
613                }
614 
615                msg += "] " + result.getTimeTaken() + "ms";
616             }
617 
618             setText( msg );
619          }
620 
621          if( isSelected )
622          {
623             setBackground( list.getSelectionBackground() );
624             setForeground( list.getSelectionForeground() );
625          }
626          else
627          {
628             setBackground( list.getBackground() );
629             setForeground( list.getForeground() );
630          }
631 
632          setEnabled( list.isEnabled() );
633 
634          return this;
635       }
636    }
637 
638    private long getDefaultMaxSize()
639    {
640       return getModelItem().getSettings().getLong( LogListModel.class.getName() + "@maxSize", 100 );
641    }
642 
643    protected long getMaxLogSize()
644    {
645       if( logListModel != null )
646          return logListModel.getMaxSize();
647       else
648          return getDefaultMaxSize();
649    }
650 
651    protected void setMaxLogSize( long size )
652    {
653       logListModel.setMaxSize( size );
654       if( mockRunner != null )
655          mockRunner.setMaxResults( logListModel.getMaxSize() );
656    }
657 
658    private class LogListModel extends AbstractListModel
659    {
660       private List<MockResult> elements = Collections.synchronizedList( new LinkedList<MockResult>() );
661       private long maxSize;
662 
663       public LogListModel()
664       {
665          maxSize = getDefaultMaxSize();
666       }
667 
668       public void addElement( MockResult result )
669       {
670          elements.add( result );
671          fireIntervalAdded( this, elements.size() - 1, elements.size() - 1 );
672 
673          synchronized( this )
674          {
675             while( elements.size() > maxSize )
676             {
677                removeElementAt( 0 );
678             }
679          }
680       }
681 
682       public Object getElementAt( int index )
683       {
684          synchronized( this )
685          {
686             return elements.get( index );
687          }
688       }
689 
690       public void removeElementAt( int index )
691       {
692          elements.remove( index );
693          fireIntervalRemoved( this, index, index );
694       }
695 
696       public void clear()
697       {
698          synchronized( this )
699          {
700             int sz = elements.size();
701             if( sz > 0 )
702             {
703                elements.clear();
704                fireIntervalRemoved( this, 0, sz - 1 );
705             }
706          }
707       }
708 
709       public int getSize()
710       {
711          return elements.size();
712       }
713 
714       public long getMaxSize()
715       {
716          return maxSize;
717       }
718 
719       public synchronized void setMaxSize( long l )
720       {
721          this.maxSize = l;
722 
723          while( elements.size() > 0 && elements.size() > maxSize )
724          {
725             removeElementAt( 0 );
726          }
727 
728          getModelItem().getSettings().setLong( LogListModel.class.getName() + "@maxSize", maxSize );
729       }
730    }
731 
732    private class SetLogOptionsAction extends AbstractAction
733    {
734       public SetLogOptionsAction()
735       {
736          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/options.gif" ) );
737          putValue( Action.SHORT_DESCRIPTION, "Sets MockService Log Options" );
738       }
739 
740       public void actionPerformed( ActionEvent e )
741       {
742          String s = UISupport.prompt( "Enter maximum number of rows for MockService Log", "Log Options", String.valueOf( logListModel.getMaxSize() ) );
743          if( s != null )
744          {
745             try
746             {
747                long newMaxSize = Long.parseLong( s );
748                if( newMaxSize > 0 )
749                   setMaxLogSize( newMaxSize );
750             }
751             catch( NumberFormatException e1 )
752             {
753             }
754          }
755       }
756    }
757 
758    private class ClearLogAction extends AbstractAction
759    {
760       public ClearLogAction()
761       {
762          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/clear_loadtest.gif" ) );
763          putValue( Action.SHORT_DESCRIPTION, "Clears the MockService Log" );
764       }
765 
766       public void actionPerformed( ActionEvent e )
767       {
768          logListModel.clear();
769          if( mockRunner != null )
770             mockRunner.clearResults();
771       }
772    }
773 
774    /***
775     * Mouse Listener for triggering default action and showing popup for log list items
776     *
777     * @author Ole.Matzura
778     */
779 
780    private final class LogListMouseListener extends AbstractListMouseListener
781    {
782       @Override
783       protected ActionList getActionsForRow( JList list, int row )
784       {
785          MockResult result = (MockResult) logListModel.getElementAt( row );
786          return result == null ? null : result.getActions();
787       }
788    }
789 
790    private class StartScriptGroovyEditorModel extends AbstractGroovyEditorModel
791    {
792       public StartScriptGroovyEditorModel()
793       {
794          super( new String[]{"log", "context", "mockRunner"}, getModelItem().getSettings(), "Start" );
795       }
796 
797       public String getScript()
798       {
799          return getModelItem().getStartScript();
800       }
801 
802       public void setScript( String text )
803       {
804          getModelItem().setStartScript( text );
805       }
806 
807       @Override
808       public Action createRunAction()
809       {
810          return new AbstractAction()
811          {
812 
813             public void actionPerformed( ActionEvent e )
814             {
815                try
816                {
817                   WsdlMockRunContext context = mockRunner == null ? new WsdlMockRunContext( getModelItem(), null ) : mockRunner.getMockContext();
818                   getModelItem().runStartScript( context, mockRunner );
819                }
820                catch( Exception e1 )
821                {
822                   UISupport.showErrorMessage( e1 );
823                }
824             }
825          };
826       }
827    }
828 
829    private class StopScriptGroovyEditorModel extends AbstractGroovyEditorModel
830    {
831       public StopScriptGroovyEditorModel()
832       {
833          super( new String[]{"log", "context", "mockRunner"}, getModelItem().getSettings(), "Stop" );
834       }
835 
836       public String getScript()
837       {
838          return getModelItem().getStopScript();
839       }
840 
841       public void setScript( String text )
842       {
843          getModelItem().setStopScript( text );
844       }
845 
846       @Override
847       public Action createRunAction()
848       {
849          return new AbstractAction()
850          {
851 
852             public void actionPerformed( ActionEvent e )
853             {
854                try
855                {
856                   WsdlMockRunContext context = mockRunner == null ? new WsdlMockRunContext( getModelItem(), null ) : mockRunner.getMockContext();
857                   getModelItem().runStopScript( context, mockRunner );
858                }
859                catch( Exception e1 )
860                {
861                   UISupport.showErrorMessage( e1 );
862                }
863             }
864          };
865       }
866    }
867 
868    private class OnRequestScriptGroovyEditorModel extends AbstractGroovyEditorModel
869    {
870       public OnRequestScriptGroovyEditorModel()
871       {
872          super( new String[]{"log", "context", "mockRequest", "mockRunner"}, getModelItem().getSettings(), "OnRequest" );
873       }
874 
875       public String getScript()
876       {
877          return getModelItem().getOnRequestScript();
878       }
879 
880       public void setScript( String text )
881       {
882          getModelItem().setOnRequestScript( text );
883       }
884 
885       @Override
886       public Action createRunAction()
887       {
888          return new AbstractAction()
889          {
890 
891             public void actionPerformed( ActionEvent e )
892             {
893                try
894                {
895                   WsdlMockRunContext context = mockRunner == null ? new WsdlMockRunContext( getModelItem(), null ) : mockRunner.getMockContext();
896                   getModelItem().runOnRequestScript( context, mockRunner, null );
897                }
898                catch( Exception e1 )
899                {
900                   UISupport.showErrorMessage( e1 );
901                }
902             }
903          };
904       }
905    }
906 
907    private class AfterRequestScriptGroovyEditorModel extends AbstractGroovyEditorModel
908    {
909       public AfterRequestScriptGroovyEditorModel()
910       {
911          super( new String[]{"log", "context", "mockResult", "mockRunner"}, getModelItem().getSettings(), "AfterRequest" );
912       }
913 
914       public String getScript()
915       {
916          return getModelItem().getAfterRequestScript();
917       }
918 
919       public void setScript( String text )
920       {
921          getModelItem().setAfterRequestScript( text );
922       }
923 
924       @Override
925       public Action createRunAction()
926       {
927          return new AbstractAction()
928          {
929 
930             public void actionPerformed( ActionEvent e )
931             {
932                try
933                {
934                   WsdlMockRunContext context = mockRunner == null ? new WsdlMockRunContext( getModelItem(), null ) : mockRunner.getMockContext();
935                   getModelItem().runAfterRequestScript( context, mockRunner, null );
936                }
937                catch( Exception e1 )
938                {
939                   UISupport.showErrorMessage( e1 );
940                }
941             }
942          };
943       }
944 	}
945 }