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