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.testcase;
14  
15  import java.awt.BorderLayout;
16  import java.awt.Component;
17  import java.awt.Dimension;
18  import java.awt.dnd.DnDConstants;
19  import java.awt.dnd.DragSource;
20  import java.awt.event.ActionEvent;
21  import java.text.SimpleDateFormat;
22  import java.util.Date;
23  
24  import javax.swing.AbstractAction;
25  import javax.swing.Action;
26  import javax.swing.BorderFactory;
27  import javax.swing.Box;
28  import javax.swing.JButton;
29  import javax.swing.JComponent;
30  import javax.swing.JList;
31  import javax.swing.JPanel;
32  import javax.swing.JProgressBar;
33  import javax.swing.JScrollPane;
34  import javax.swing.JTabbedPane;
35  import javax.swing.JTextArea;
36  import javax.swing.JToggleButton;
37  import javax.swing.JToolBar;
38  import javax.swing.ListModel;
39  import javax.swing.SwingConstants;
40  import javax.swing.SwingUtilities;
41  import javax.swing.text.Document;
42  
43  import com.eviware.soapui.SoapUI;
44  import com.eviware.soapui.config.TestStepConfig;
45  import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
46  import com.eviware.soapui.impl.wsdl.actions.testcase.TestCaseOptionsAction;
47  import com.eviware.soapui.impl.wsdl.panels.support.MockTestRunContext;
48  import com.eviware.soapui.impl.wsdl.panels.support.MockTestRunner;
49  import com.eviware.soapui.impl.wsdl.panels.support.ProgressBarTestCaseAdapter;
50  import com.eviware.soapui.impl.wsdl.panels.testcase.actions.SetCredentialsAction;
51  import com.eviware.soapui.impl.wsdl.panels.testcase.actions.SetEndpointAction;
52  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.AbstractGroovyEditorModel;
53  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.PropertyHolderTable;
54  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
55  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
56  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner;
57  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep;
58  import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestStepFactory;
59  import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestStepRegistry;
60  import com.eviware.soapui.model.ModelItem;
61  import com.eviware.soapui.model.support.TestRunListenerAdapter;
62  import com.eviware.soapui.model.testsuite.LoadTestRunner;
63  import com.eviware.soapui.model.testsuite.TestRunContext;
64  import com.eviware.soapui.model.testsuite.TestRunner;
65  import com.eviware.soapui.model.testsuite.TestStep;
66  import com.eviware.soapui.model.testsuite.TestStepResult;
67  import com.eviware.soapui.monitor.support.TestMonitorListenerAdapter;
68  import com.eviware.soapui.support.DocumentListenerAdapter;
69  import com.eviware.soapui.support.UISupport;
70  import com.eviware.soapui.support.action.swing.SwingActionDelegate;
71  import com.eviware.soapui.support.components.GroovyEditorComponent;
72  import com.eviware.soapui.support.components.GroovyEditorInspector;
73  import com.eviware.soapui.support.components.JComponentInspector;
74  import com.eviware.soapui.support.components.JFocusableComponentInspector;
75  import com.eviware.soapui.support.components.JInspectorPanel;
76  import com.eviware.soapui.support.components.JUndoableTextArea;
77  import com.eviware.soapui.support.components.JXToolBar;
78  import com.eviware.soapui.support.dnd.DropType;
79  import com.eviware.soapui.support.dnd.JListDragAndDropable;
80  import com.eviware.soapui.support.dnd.SoapUIDragAndDropHandler;
81  import com.eviware.soapui.support.swing.ComponentBag;
82  import com.eviware.soapui.support.types.StringToObjectMap;
83  import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
84  
85  /***
86   * WsdlTestCase desktop panel
87   * 
88   * @author Ole.Matzura
89   */
90  
91  public class WsdlTestCaseDesktopPanel extends ModelItemDesktopPanel<WsdlTestCase>
92  {
93  	private JProgressBar progressBar;
94  	private TestStepList testStepList;
95  	private InternalTestRunListener testRunListener = new InternalTestRunListener();
96  	private JButton runButton;
97  	private JButton cancelButton;
98  	private TestRunner runner;
99  	private JButton setEndpointButton;
100 	private JButton setCredentialsButton;
101 	private JButton optionsButton;
102 	private ComponentBag stateDependantComponents = new ComponentBag();
103 	private TestRunLog testCaseLog;
104 	private JToggleButton loopButton;
105 	@SuppressWarnings( "unused" )
106 	private ProgressBarTestCaseAdapter progressBarAdapter;
107 	private InternalTestMonitorListener testMonitorListener;
108 	public boolean canceled;
109 	private JTextArea descriptionArea;
110 	private PropertyHolderTable propertiesTable;
111 	private GroovyEditorComponent tearDownGroovyEditor;
112 	private GroovyEditorComponent setupGroovyEditor;
113 
114 	public WsdlTestCaseDesktopPanel( WsdlTestCase testCase )
115 	{
116 		super( testCase );
117 
118 		buildUI();
119 
120 		setPreferredSize( new Dimension( 400, 550 ) );
121 		setRunningState();
122 
123 		testCase.addTestRunListener( testRunListener );
124 		progressBarAdapter = new ProgressBarTestCaseAdapter( progressBar, testCase );
125 		testMonitorListener = new InternalTestMonitorListener();
126 
127 		SoapUI.getTestMonitor().addTestMonitorListener( testMonitorListener );
128 		
129 		DragSource dragSource = DragSource.getDefaultDragSource();
130 		SoapUIDragAndDropHandler dragAndDropHandler = new SoapUIDragAndDropHandler( 
131 					new ModelItemListDragAndDropable( getTestStepList().getTestStepList(), testCase ), DropType.BEFORE_AND_AFTER );
132 		
133 		dragSource.createDefaultDragGestureRecognizer( getTestStepList().getTestStepList(), DnDConstants.ACTION_COPY_OR_MOVE,
134 					dragAndDropHandler );
135 	}
136 
137 	/***
138 	 * There are three states: - enabled, no testcases or testschedules running -
139 	 * enabled, standalone testcase running - disabled, testschedule is running
140 	 */
141 
142 	private void setRunningState()
143 	{
144 		stateDependantComponents.setEnabled( !SoapUI.getTestMonitor().hasRunningLoadTest( getModelItem() ) );
145 	}
146 
147 	private void buildUI()
148 	{
149 		JPanel panel = new JPanel( new BorderLayout() );
150 
151 		panel.add( buildToolbar(), BorderLayout.PAGE_START );
152 		panel.add( buildRunnerBar(), BorderLayout.CENTER );
153 
154 		add( panel, BorderLayout.NORTH );
155 
156 		JInspectorPanel inspectorPanel = new JInspectorPanel( buildContent() );
157 		inspectorPanel.addInspector( new JComponentInspector( buildTestLog(), "TestCase Log", "TestCase Execution Log", true ) );
158 		inspectorPanel.setDefaultDividerLocation( 0.7F );
159 		inspectorPanel.setCurrentInspector( "TestCase Log" );
160 		
161 		add( inspectorPanel, BorderLayout.CENTER );
162 	}
163 
164 	protected TestStepList getTestStepList()
165 	{
166 		return testStepList;
167 	}
168 
169 	private JComponent buildTestLog()
170 	{
171 		testCaseLog = new TestCaseTestRunLog(getModelItem());
172 		stateDependantComponents.add( testCaseLog );
173 		return testCaseLog;
174 	}
175 
176 	private JComponent buildContent()
177 	{
178 		JTabbedPane tabs = new JTabbedPane( JTabbedPane.TOP );
179 		JInspectorPanel inspectorPanel = new JInspectorPanel( buildTestStepList(),
180 					SwingConstants.BOTTOM);
181 		
182 		tabs.addTab( "TestSteps", inspectorPanel );
183 		
184 		addTabs( tabs, inspectorPanel );
185 		tabs.setTabLayoutPolicy( JTabbedPane.SCROLL_TAB_LAYOUT );
186 
187 		return UISupport.createTabPanel( tabs, true );
188 	}
189 
190 	protected JComponent buildTestStepList()
191 	{
192 		JPanel p = new JPanel( new BorderLayout() );
193 		JXToolBar toolbar = UISupport.createToolbar();
194 		
195 		WsdlTestStepFactory[] factories = WsdlTestStepRegistry.getInstance().getFactories();
196 		for( WsdlTestStepFactory factory : factories )
197 		{
198 			toolbar.addFixed( UISupport.createToolbarButton( new AddWsdlTestStepAction( factory ) ) );
199 		}
200 		
201 		p.add( toolbar, BorderLayout.NORTH );
202 		testStepList = new TestStepList( getModelItem() );
203 		stateDependantComponents.add( testStepList );
204 		
205 		p.add( new JScrollPane( testStepList ), BorderLayout.CENTER );
206 		
207 		return p;
208 	}
209 
210 	protected void addTabs( JTabbedPane tabs, JInspectorPanel inspectorPanel )
211 	{
212 		inspectorPanel.addInspector( new JFocusableComponentInspector<JPanel>( buildDescriptionPanel(), 
213 					descriptionArea, "Description", "TestCase Description", true ) );
214 		inspectorPanel.addInspector( new JComponentInspector( buildPropertiesPanel(), "Properties", "TestCase level properties", true ) );
215 		inspectorPanel.addInspector( new GroovyEditorInspector( buildSetupScriptPanel(), "Setup Script", "Script to run before tunning a TestCase" ) );
216 		inspectorPanel.addInspector( new GroovyEditorInspector( buildTearDownScriptPanel(), "TearDown Script", "Script to run after a TestCase Run" ) );
217 	}
218 
219 	protected GroovyEditorComponent buildTearDownScriptPanel()
220 	{
221 		tearDownGroovyEditor = new GroovyEditorComponent( new TearDownScriptGroovyEditorModel(), null );
222 		return tearDownGroovyEditor;
223 	}
224 
225 	protected GroovyEditorComponent buildSetupScriptPanel()
226 	{
227 		setupGroovyEditor = new GroovyEditorComponent( new SetupScriptGroovyEditorModel(), null );
228 		return setupGroovyEditor;
229 	}
230 
231 	protected JComponent buildPropertiesPanel()
232 	{
233 		JPanel panel = new JPanel( new BorderLayout() );
234 		propertiesTable = buildPropertiesTable();
235 		panel.add( new JScrollPane( propertiesTable ), BorderLayout.CENTER );
236 		return panel;
237 	}
238 
239 	protected PropertyHolderTable buildPropertiesTable()
240 	{
241 		return new PropertyHolderTable( getModelItem() );
242 	}
243 
244 	private JPanel buildDescriptionPanel()
245 	{
246 		JPanel panel = new JPanel( new BorderLayout() );
247 		descriptionArea = new JUndoableTextArea( getModelItem().getDescription() );
248 		descriptionArea.getDocument().addDocumentListener( new DocumentListenerAdapter()
249 		{
250 			public void update( Document document )
251 			{
252 				getModelItem().setDescription( descriptionArea.getText() );
253 			}
254 		} );
255 
256 		panel.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2 ) );
257 		panel.add( new JScrollPane( descriptionArea ), BorderLayout.CENTER );
258 		UISupport.addTitledBorder( panel, "TestCase Description" );
259 		
260 		return panel;
261 	}
262 
263 	private Component buildToolbar()
264 	{
265 		JToolBar toolbar = UISupport.createToolbar();
266 
267 		runButton = UISupport.createToolbarButton( new RunTestCaseAction() );
268 		optionsButton = UISupport.createToolbarButton( SwingActionDelegate.createDelegate(
269 					TestCaseOptionsAction.SOAPUI_ACTION_ID, getModelItem(), null, "/options.gif" ) );
270 		optionsButton.setText( null );
271 		cancelButton = UISupport.createToolbarButton( new CancelRunTestCaseAction(), false );
272 
273 		loopButton = new JToggleButton( UISupport.createImageIcon( "/loop.gif" ) );
274 		loopButton.setPreferredSize( UISupport.getPreferredButtonSize() );
275 		loopButton.setToolTipText( "Loop TestCase continuously" );
276 
277 		setCredentialsButton = UISupport.createToolbarButton( new SetCredentialsAction( getModelItem() ) );
278 		setEndpointButton = UISupport.createToolbarButton( new SetEndpointAction( getModelItem() ) );
279 
280 		stateDependantComponents.add( runButton );
281 		stateDependantComponents.add( optionsButton );
282 		stateDependantComponents.add( cancelButton );
283 		stateDependantComponents.add( setCredentialsButton );
284 		stateDependantComponents.add( setEndpointButton );
285 
286 		addToolbarActions( toolbar );
287 		
288 		toolbar.add( Box.createHorizontalGlue() );
289 		toolbar.add( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.TESTCASEEDITOR_HELP_URL ) ) );
290 
291 		return toolbar;
292 	}
293 
294 	protected void addToolbarActions( JToolBar toolbar )
295 	{
296 		toolbar.add( runButton );
297 		toolbar.add( cancelButton );
298 		toolbar.add( loopButton );
299 		toolbar.add( setCredentialsButton );
300 		toolbar.add( setEndpointButton );
301 		toolbar.add( optionsButton );
302 	}
303 
304 	private Component buildRunnerBar()
305 	{
306 		progressBar = new JProgressBar( 0, getModelItem().getTestStepCount() );
307 		return UISupport.createProgressBarPanel( progressBar, 10, false );
308 	}
309 
310 	private final class InternalTestMonitorListener extends TestMonitorListenerAdapter
311 	{
312 		public void loadTestStarted( LoadTestRunner runner )
313 		{
314 			setRunningState();
315 		}
316 
317 		public void loadTestFinished( LoadTestRunner runner )
318 		{
319 			setRunningState();
320 		}
321 	}
322 
323 	public class InternalTestRunListener extends TestRunListenerAdapter
324 	{
325 		private SimpleDateFormat dateFormat;
326 
327 		public InternalTestRunListener()
328 		{
329 			dateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSS" );
330 		}
331 
332 		public void beforeRun( TestRunner testRunner, TestRunContext runContext )
333 		{
334 			if( SoapUI.getTestMonitor().hasRunningLoadTest( getModelItem() ) )
335 				return;
336 
337 			runButton.setEnabled( false );
338 			cancelButton.setEnabled( true );
339 			testStepList.setEnabled( false );
340 			testStepList.setSelectedIndex( -1 );
341 			testCaseLog.clear();
342 
343 			testCaseLog.addText( "Test started at " + dateFormat.format( new Date() ) );
344 			
345 			WsdlTestCaseDesktopPanel.this.beforeRun();
346 		}
347 
348 		public void beforeStep( TestRunner testRunner, TestRunContext runContext )
349 		{
350 			if( SoapUI.getTestMonitor().hasRunningLoadTest( getModelItem() ) )
351 				return;
352 
353 			TestStep testStep = runContext.getCurrentStep();
354 			testStepList.setSelectedValue( testStep, true );
355 		}
356 
357 		public void afterRun( TestRunner testRunner, TestRunContext runContext )
358 		{
359 			if( SoapUI.getTestMonitor().hasRunningLoadTest( getModelItem() ) )
360 				return;
361 
362 			WsdlTestCaseRunner wsdlRunner = ( WsdlTestCaseRunner ) testRunner;
363 
364 			if( testRunner.getStatus() == TestRunner.Status.CANCELED )
365 				testCaseLog.addText( "TestCase canceled [" + testRunner.getReason() + "], time taken = "
366 							+ wsdlRunner.getTimeTaken() );
367 			else if( testRunner.getStatus() == TestRunner.Status.FAILED )
368 			{
369 				String msg = wsdlRunner.getReason();
370 				if(  wsdlRunner.getError() != null )
371 				{
372 					if( msg != null )
373 						msg += ":";
374 				
375 					msg += wsdlRunner.getError();
376 				}
377 				
378 				testCaseLog.addText( "TestCase failed [" + msg + "], time taken = "
379 							+ wsdlRunner.getTimeTaken() );
380 			}
381 			else 
382 				testCaseLog.addText( "TestCase finished with status [" + testRunner.getStatus() + "], time taken = " + wsdlRunner.getTimeTaken() );
383 
384 			runner = null;
385 
386 			JToggleButton loopButton = ( JToggleButton ) runContext.getProperty( "loopButton" );
387 			if( loopButton != null && loopButton.isSelected() && testRunner.getStatus() == TestRunner.Status.FINISHED )
388 			{
389 				SwingUtilities.invokeLater( new Runnable()
390 				{
391 					public void run()
392 					{
393 						runTestCase();
394 					}
395 				} );
396 			}
397 			else
398 			{
399 				WsdlTestCaseDesktopPanel.this.afterRun();
400 			}
401 		}
402 
403 		public void afterStep( TestRunner testRunner, TestRunContext runContext, TestStepResult stepResult )
404 		{
405 			if( SoapUI.getTestMonitor().hasRunningLoadTest( getModelItem() ) )
406 				return;
407 
408 			testCaseLog.addTestStepResult( stepResult );
409 		}
410 	}
411 
412 	protected void runTestCase()
413 	{
414 		if( canceled )
415 		{
416 			// make sure state is correct
417 			runButton.setEnabled( true );
418 			cancelButton.setEnabled( false );
419 			testStepList.setEnabled( true );
420 			return;
421 		}
422 
423 		StringToObjectMap properties = new StringToObjectMap();
424 		properties.put( "loopButton", loopButton );
425 		runner = getModelItem().run( properties, true );
426 	}
427 
428    public class RunTestCaseAction extends AbstractAction
429 	{
430 		public RunTestCaseAction()
431 		{
432 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_testcase.gif" ) );
433 			putValue( Action.SHORT_DESCRIPTION, "Runs this testcase" );
434 		}
435 
436 		public void actionPerformed( ActionEvent e )
437 		{
438 			canceled = false;
439 			runTestCase();
440 		}
441 	}
442 
443 	public class CancelRunTestCaseAction extends AbstractAction
444 	{
445 		public CancelRunTestCaseAction()
446 		{
447 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/stop_testcase.gif" ) );
448 			putValue( Action.SHORT_DESCRIPTION, "Stops running this testcase" );
449 		}
450 
451 		public void actionPerformed( ActionEvent e )
452 		{
453 			if( runner != null )
454 				runner.cancel( "canceled in UI" );
455 
456 			canceled = true;
457 		}
458 	}
459 
460 	public boolean onClose( boolean canCancel )
461 	{
462 		if( canCancel )
463 		{
464 			if( runner != null && runner.getStatus() == TestRunner.Status.RUNNING )
465 			{
466 				Boolean retval = UISupport.confirmOrCancel( "Cancel running TestCase?", "Cancel Run" );
467 
468 				if( retval == null )
469 					return false;
470 				if( retval.booleanValue() )
471 				{
472 					runner.cancel( null );
473 				}
474 			}
475 		}
476 		else
477 		{
478 			if( runner != null && runner.getStatus() == TestRunner.Status.RUNNING )
479 			{
480 				runner.cancel( null );
481 			}
482 		}
483 
484 		SoapUI.getTestMonitor().removeTestMonitorListener( testMonitorListener );
485 		getModelItem().removeTestRunListener( testRunListener );
486 		testStepList.release();
487 		progressBarAdapter.release();
488 		propertiesTable.release();
489 		
490 		setupGroovyEditor.getEditor().release();
491 		tearDownGroovyEditor.getEditor().release();
492 		
493 		testCaseLog.release();
494 		
495 		return release();
496 	}
497 
498 	public boolean dependsOn( ModelItem modelItem )
499 	{
500 		return modelItem == getModelItem() || modelItem == getModelItem().getTestSuite()
501 					|| modelItem == getModelItem().getTestSuite().getProject();
502 	}
503 
504    protected void beforeRun()
505    {
506    }
507 
508 	protected void afterRun()
509 	{
510 		runButton.setEnabled( true );
511 		cancelButton.setEnabled( false );
512 		testStepList.setEnabled( true );
513 	}
514 	
515 	private class SetupScriptGroovyEditorModel extends AbstractGroovyEditorModel
516 	{
517 		@Override
518 		public Action createRunAction()
519 		{
520 			return new AbstractAction(){
521 
522 				public void actionPerformed( ActionEvent e )
523 				{
524 					try
525 					{
526 						MockTestRunner mockTestRunner = new MockTestRunner( getModelItem(), SoapUI.ensureGroovyLog() );
527 						getModelItem().runSetupScript( new MockTestRunContext(mockTestRunner,null), mockTestRunner );
528 					}
529 					catch( Exception e1 )
530 					{
531 						UISupport.showErrorMessage( e1 );
532 					}
533 				}};
534 		}
535 
536 		public SetupScriptGroovyEditorModel()
537 		{
538 			super( new String[] {"log", "context", "testRunner" }, getModelItem().getSettings(), "Setup" );
539 		}
540 		
541 		public String getScript()
542 		{
543 			return getModelItem().getSetupScript();
544 		}
545 
546 		public void setScript( String text )
547 		{
548 			getModelItem().setSetupScript( text );
549 		}
550 	}
551 	
552 	private class TearDownScriptGroovyEditorModel extends AbstractGroovyEditorModel
553 	{
554 		@Override
555 		public Action createRunAction()
556 		{
557 			return new AbstractAction(){
558 
559 				public void actionPerformed( ActionEvent e )
560 				{
561 					try
562 					{
563 						MockTestRunner mockTestRunner = new MockTestRunner( getModelItem(), SoapUI.ensureGroovyLog() );
564 						getModelItem().runTearDownScript( new MockTestRunContext(mockTestRunner,null), mockTestRunner );
565 					}
566 					catch( Exception e1 )
567 					{
568 						UISupport.showErrorMessage( e1 );
569 					}
570 				}};
571 		}
572 		
573 		public TearDownScriptGroovyEditorModel()
574 		{
575 			super( new String[] {"log", "context", "testRunner" }, getModelItem().getSettings(), "TearDown" );
576 		}
577 		
578 		public String getScript()
579 		{
580 			return getModelItem().getTearDownScript();
581 		}
582 
583 		public void setScript( String text )
584 		{
585 			getModelItem().setTearDownScript( text );
586 		}
587 	}
588 	
589 	private class AddWsdlTestStepAction extends AbstractAction
590 	{
591 		private final WsdlTestStepFactory factory;
592 
593 		public AddWsdlTestStepAction( WsdlTestStepFactory factory )
594 		{
595 			this.factory = factory;
596 			putValue( SMALL_ICON, UISupport.createImageIcon( factory.getTestStepIconPath() ));
597 			putValue( SHORT_DESCRIPTION, "Create a new " + factory.getTestStepName() + " TestStep");
598 		}
599 
600 		public void actionPerformed( ActionEvent e )
601 		{
602 			int ix = testStepList.getTestStepList().getSelectedIndex();
603 			
604 			String name = UISupport.prompt( "Specify name for new step", ix == -1 ? "Add Step" : "Insert Step", factory.getTestStepName());
605 			if( name != null )
606 			{
607 				TestStepConfig newTestStepConfig = factory.createNewTestStep(getModelItem(), name);
608 				if( newTestStepConfig != null )
609 				{
610 					WsdlTestStep testStep = getModelItem().insertTestStep(newTestStepConfig, ix);
611 					UISupport.selectAndShow( testStep );
612 				}
613 			}
614 			
615 		}
616 	}
617 	
618 	public static class ModelItemListDragAndDropable extends JListDragAndDropable<JList>
619 	{
620 		public ModelItemListDragAndDropable( JList list, WsdlTestCase testCase )
621 		{
622 			super( list, testCase );
623 		}
624 
625 		@Override
626 		public ModelItem getModelItemAtRow( int row )
627 		{
628 			return ( ModelItem ) getList().getModel().getElementAt( row );
629 		}
630 
631 		@Override
632 		public int getModelItemRow( ModelItem modelItem )
633 		{
634 			ListModel model = getList().getModel();
635 			
636 			for( int c = 0; c < model.getSize(); c++ )
637 			{
638 				if( model.getElementAt( c ) == modelItem )
639 					return c;
640 			}
641 			
642 			return -1;
643 		}
644 
645 		public Component getRenderer( ModelItem modelItem )
646 		{
647 			return getList().getCellRenderer().getListCellRendererComponent( getList(), modelItem, 
648 						getModelItemRow( modelItem ), true, true );
649 		}
650 
651 		@Override
652 		public void setDragInfo( String dropInfo )
653 		{
654 			super.setDragInfo( dropInfo == null || dropInfo.length() == 0 ? null : dropInfo );
655 		}
656 	}
657 }