View Javadoc

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