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