View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 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.project;
14  
15  import java.awt.BorderLayout;
16  import java.awt.Component;
17  import java.awt.Dimension;
18  import java.awt.event.ActionEvent;
19  import java.util.HashSet;
20  import java.util.Set;
21  
22  import javax.swing.AbstractAction;
23  import javax.swing.Action;
24  import javax.swing.BorderFactory;
25  import javax.swing.JComponent;
26  import javax.swing.JPanel;
27  import javax.swing.JScrollPane;
28  import javax.swing.JTabbedPane;
29  import javax.swing.event.TreeModelEvent;
30  import javax.swing.event.TreeModelListener;
31  import javax.swing.text.Document;
32  
33  import com.eviware.soapui.SoapUI;
34  import com.eviware.soapui.impl.rest.RestService;
35  import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
36  import com.eviware.soapui.impl.wsdl.WsdlInterface;
37  import com.eviware.soapui.impl.wsdl.WsdlProject;
38  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.AbstractGroovyEditorModel;
39  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.PropertyHolderTable;
40  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
41  import com.eviware.soapui.model.ModelItem;
42  import com.eviware.soapui.model.iface.Interface;
43  import com.eviware.soapui.model.mock.MockOperation;
44  import com.eviware.soapui.model.mock.MockResponse;
45  import com.eviware.soapui.model.mock.MockService;
46  import com.eviware.soapui.model.project.Project;
47  import com.eviware.soapui.model.testsuite.Assertable;
48  import com.eviware.soapui.model.testsuite.LoadTest;
49  import com.eviware.soapui.model.testsuite.TestAssertion;
50  import com.eviware.soapui.model.testsuite.TestCase;
51  import com.eviware.soapui.model.testsuite.TestStep;
52  import com.eviware.soapui.model.testsuite.TestSuite;
53  import com.eviware.soapui.model.util.ModelItemIconFactory;
54  import com.eviware.soapui.settings.UISettings;
55  import com.eviware.soapui.support.DocumentListenerAdapter;
56  import com.eviware.soapui.support.StringUtils;
57  import com.eviware.soapui.support.UISupport;
58  import com.eviware.soapui.support.components.GroovyEditorComponent;
59  import com.eviware.soapui.support.components.GroovyEditorInspector;
60  import com.eviware.soapui.support.components.JComponentInspector;
61  import com.eviware.soapui.support.components.JFocusableComponentInspector;
62  import com.eviware.soapui.support.components.JInspectorPanel;
63  import com.eviware.soapui.support.components.JInspectorPanelFactory;
64  import com.eviware.soapui.support.components.JUndoableTextArea;
65  import com.eviware.soapui.support.components.JXToolBar;
66  import com.eviware.soapui.support.components.MetricsPanel;
67  import com.eviware.soapui.support.components.MetricsPanel.MetricType;
68  import com.eviware.soapui.support.components.MetricsPanel.MetricsSection;
69  import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
70  
71  public class WsdlProjectDesktopPanel extends ModelItemDesktopPanel<WsdlProject>
72  {
73  	protected static final String MOCKRESPONSES_STATISTICS = "MockResponses";
74  	protected static final String MOCKOPERATIONS_STATISTICS = "MockOperations";
75  	protected static final String MOCKSERVICES_STATISTICS = "MockServices";
76  	protected static final String LOADTESTS_STATISTICS = "LoadTests";
77  	protected static final String ASSERTIONS_STATISTICS = "Assertions";
78  	protected static final String TESTSTEPS_STATISTICS = "TestSteps";
79  	protected static final String TESTCASES_STATISTICS = "TestCases";
80  	protected static final String TESTSUITES_STATISTICS = "TestSuites";
81  	private PropertyHolderTable propertiesTable;
82  	private JUndoableTextArea descriptionArea;
83  	private InternalTreeModelListener treeModelListener;
84  	private Set<String> interfaceNameSet = new HashSet<String>();
85  	private WSSTabPanel wssTabPanel;
86  	protected MetricsPanel metrics;
87  	private GroovyEditorComponent loadScriptGroovyEditor;
88  	private GroovyEditorComponent saveScriptGroovyEditor;
89  	private JInspectorPanel inspectorPanel;
90  	private WsdlProjectTestSuitesTabPanel testSuitesPanel;
91  
92  	public WsdlProjectDesktopPanel( WsdlProject modelItem )
93  	{
94  		super( modelItem );
95  
96  		add( buildTabbedPane(), BorderLayout.CENTER );
97  
98  		setPreferredSize( new Dimension( 600, 600 ) );
99  	}
100 
101 	private Component buildTabbedPane()
102 	{
103 		JTabbedPane mainTabs = new JTabbedPane();
104 		addTabs( mainTabs );
105 		return UISupport.createTabPanel( mainTabs, true );
106 	}
107 
108 	protected void addTabs( JTabbedPane mainTabs )
109 	{
110 		mainTabs.addTab( "Overview", null, buildOverviewTab(), "Shows General Project information and metrics" );
111 		mainTabs.addTab( "TestSuites", null, testSuitesPanel = buildTestSuitesTab(),
112 				"Shows and runs all TestSuites in project" );
113 		mainTabs.addTab( "Security Configurations", null, buildWSSTab(), "Manages Security-related configurations" );
114 	}
115 
116 	protected WsdlProjectTestSuitesTabPanel buildTestSuitesTab()
117 	{
118 		return new WsdlProjectTestSuitesTabPanel( getModelItem() );
119 	}
120 
121 	protected Component buildWSSTab()
122 	{
123 		wssTabPanel = new WSSTabPanel( getModelItem().getWssContainer() );
124 		return wssTabPanel;
125 	}
126 
127 	protected Component buildOverviewTab()
128 	{
129 		inspectorPanel = JInspectorPanelFactory.build( buildProjectOverview() );
130 
131 		addOverviewInspectors( inspectorPanel );
132 
133 		inspectorPanel.setCurrentInspector( "Properties" );
134 
135 		if( StringUtils.hasContent( getModelItem().getDescription() )
136 				&& getModelItem().getSettings().getBoolean( UISettings.SHOW_DESCRIPTIONS ) )
137 		{
138 			inspectorPanel.setCurrentInspector( "Description" );
139 		}
140 
141 		treeModelListener = new InternalTreeModelListener();
142 		SoapUI.getNavigator().getMainTree().getModel().addTreeModelListener( treeModelListener );
143 
144 		updateStatistics();
145 
146 		return inspectorPanel.getComponent();
147 	}
148 
149 	protected void addOverviewInspectors(JInspectorPanel inspectorPanel )
150 	{
151 		inspectorPanel.addInspector( new JFocusableComponentInspector<JPanel>( buildDescriptionPanel(), descriptionArea,
152 				"Description", "Project description", true ) );
153 		inspectorPanel.addInspector( new JComponentInspector<JComponent>( buildPropertiesPanel(), "Properties",
154 				"Project level properties", true ) );
155 		inspectorPanel.addInspector( new GroovyEditorInspector( buildLoadScriptPanel(), "Load Script",
156 				"Script to run after loading the project" ) );
157 		inspectorPanel.addInspector( new GroovyEditorInspector( buildSaveScriptPanel(), "Save Script",
158 				"Script to run before saving the project" ) );
159 	}
160 
161 	private void updateStatistics()
162 	{
163 		metrics.setMetric( "File Path", getModelItem().getPath() );
164 
165 		Set<String> newNames = new HashSet<String>();
166 		boolean rebuilt = false;
167 		for( Interface iface : getModelItem().getInterfaceList() )
168 		{
169 			if( !metrics.hasMetric( iface.getName() ) )
170 			{
171 				MetricsSection section = metrics.getSection( "Interface Summary" );
172 				buildInterfaceSummary( section.clear() );
173 				rebuilt = true;
174 				break;
175 			}
176 
177 			newNames.add( iface.getName() );
178 			interfaceNameSet.remove( iface.getName() );
179 		}
180 
181 		if( !rebuilt )
182 		{
183 			if( !interfaceNameSet.isEmpty() )
184 			{
185 				MetricsSection section = metrics.getSection( "Interface Summary" );
186 				buildInterfaceSummary( section.clear() );
187 			}
188 
189 			interfaceNameSet = newNames;
190 		}
191 
192 		metrics.setMetric( TESTSUITES_STATISTICS, getModelItem().getTestSuiteCount() );
193 
194 		int testCaseCount = 0;
195 		int testStepsCount = 0;
196 		int assertionsCount = 0;
197 		int loadTestsCount = 0;
198 
199 		for( TestSuite testSuite : getModelItem().getTestSuiteList() )
200 		{
201 			testCaseCount += testSuite.getTestCaseCount();
202 
203 			for( TestCase testCase : testSuite.getTestCaseList() )
204 			{
205 				testStepsCount += testCase.getTestStepCount();
206 				loadTestsCount += testCase.getLoadTestCount();
207 
208 				for( TestStep testStep : testCase.getTestStepList() )
209 				{
210 					if( testStep instanceof Assertable )
211 					{
212 						assertionsCount += ( ( Assertable )testStep ).getAssertionCount();
213 					}
214 				}
215 			}
216 		}
217 
218 		metrics.setMetric( TESTCASES_STATISTICS, testCaseCount );
219 		metrics.setMetric( TESTSTEPS_STATISTICS, testStepsCount );
220 		metrics.setMetric( ASSERTIONS_STATISTICS, assertionsCount );
221 		metrics.setMetric( LOADTESTS_STATISTICS, loadTestsCount );
222 
223 		int mockOperationCount = 0;
224 		int mockResponseCount = 0;
225 
226 		for( MockService testSuite : getModelItem().getMockServiceList() )
227 		{
228 			mockOperationCount += testSuite.getMockOperationCount();
229 
230 			for( MockOperation testCase : testSuite.getMockOperationList() )
231 			{
232 				mockResponseCount += testCase.getMockResponseCount();
233 			}
234 		}
235 
236 		metrics.setMetric( MOCKSERVICES_STATISTICS, getModelItem().getMockServiceCount() );
237 		metrics.setMetric( MOCKOPERATIONS_STATISTICS, mockOperationCount );
238 		metrics.setMetric( MOCKRESPONSES_STATISTICS, mockResponseCount );
239 	}
240 
241 	private JComponent buildProjectOverview()
242 	{
243 		metrics = new MetricsPanel();
244 
245 		JXToolBar toolbar = buildOverviewToolbar();
246 		metrics.add( toolbar, BorderLayout.NORTH );
247 
248 		MetricsSection section = metrics.addSection( "Project Summary" );
249 		section.addMetric( ModelItemIconFactory.getIcon( Project.class ), "File Path", MetricType.URL );
250 		section.finish();
251 
252 		section = metrics.addSection( "Interface Summary" );
253 		buildInterfaceSummary( section );
254 
255 		section = metrics.addSection( "Test Summary" );
256 		section.addMetric( ModelItemIconFactory.getIcon( TestSuite.class ), TESTSUITES_STATISTICS );
257 		section.addMetric( ModelItemIconFactory.getIcon( TestCase.class ), TESTCASES_STATISTICS );
258 		section.addMetric( ModelItemIconFactory.getIcon( TestStep.class ), TESTSTEPS_STATISTICS );
259 		section.addMetric( ModelItemIconFactory.getIcon( TestAssertion.class ), ASSERTIONS_STATISTICS );
260 		section.addMetric( ModelItemIconFactory.getIcon( LoadTest.class ), LOADTESTS_STATISTICS );
261 		section.finish();
262 
263 		section = metrics.addSection( "Mock Summary" );
264 		section.addMetric( ModelItemIconFactory.getIcon( MockService.class ), MOCKSERVICES_STATISTICS );
265 		section.addMetric( ModelItemIconFactory.getIcon( MockOperation.class ), MOCKOPERATIONS_STATISTICS );
266 		section.addMetric( ModelItemIconFactory.getIcon( MockResponse.class ), MOCKRESPONSES_STATISTICS );
267 		section.finish();
268 		return new JScrollPane( metrics );
269 	}
270 
271 	protected JXToolBar buildOverviewToolbar()
272 	{
273 		JXToolBar toolbar = UISupport.createSmallToolbar();
274 		toolbar.addGlue();
275 		toolbar
276 				.addFixed( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.PROJECT_OVERVIEW_HELP_URL ) ) );
277 		return toolbar;
278 	}
279 
280 	protected void buildInterfaceSummary( MetricsSection section )
281 	{
282 		interfaceNameSet.clear();
283 		for( Interface ic : getModelItem().getInterfaceList() )
284 		{
285 			if( ic instanceof WsdlInterface )
286 			{
287 				WsdlInterface iface = ( WsdlInterface )ic;
288 				section.addMetric( iface.getIcon(), iface.getName(), MetricType.URL ).set( iface.getDefinition() );
289 			}
290 			else if( ic instanceof RestService )
291 			{
292 				RestService iface = ( RestService )ic;
293 				section.addMetric( iface.getIcon(), iface.getName(), MetricType.URL ).set( iface.getWadlUrl() );
294 			}
295 
296 			interfaceNameSet.add( ic.getName() );
297 		}
298 
299 		section.finish();
300 	}
301 
302 	private JPanel buildDescriptionPanel()
303 	{
304 		JPanel panel = new JPanel( new BorderLayout() );
305 		descriptionArea = new JUndoableTextArea( getModelItem().getDescription() );
306 		descriptionArea.getDocument().addDocumentListener( new DocumentListenerAdapter()
307 		{
308 			@Override
309 			public void update( Document document )
310 			{
311 				getModelItem().setDescription( descriptionArea.getText() );
312 			}
313 		} );
314 
315 		panel.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2 ) );
316 		panel.add( new JScrollPane( descriptionArea ), BorderLayout.CENTER );
317 		UISupport.addTitledBorder( panel, "Project Description" );
318 
319 		return panel;
320 	}
321 
322 	protected GroovyEditorComponent buildLoadScriptPanel()
323 	{
324 		loadScriptGroovyEditor = new GroovyEditorComponent( new LoadScriptGroovyEditorModel(), null );
325 		return loadScriptGroovyEditor;
326 	}
327 
328 	protected GroovyEditorComponent buildSaveScriptPanel()
329 	{
330 		saveScriptGroovyEditor = new GroovyEditorComponent( new SaveScriptGroovyEditorModel(), null );
331 		return saveScriptGroovyEditor;
332 	}
333 
334 	private JComponent buildPropertiesPanel()
335 	{
336 		JPanel panel = new JPanel( new BorderLayout() );
337 		propertiesTable = new PropertyHolderTable( getModelItem() );
338 		panel.add( new JScrollPane( propertiesTable ), BorderLayout.CENTER );
339 		return panel;
340 	}
341 
342 	@Override
343 	public boolean dependsOn( ModelItem modelItem )
344 	{
345 		return modelItem == getModelItem();
346 	}
347 
348 	public boolean onClose( boolean canCancel )
349 	{
350 		propertiesTable.release();
351 		loadScriptGroovyEditor.getEditor().release();
352 		saveScriptGroovyEditor.getEditor().release();
353 
354 		SoapUI.getNavigator().getMainTree().getModel().removeTreeModelListener( treeModelListener );
355 		wssTabPanel.release();
356 
357 		inspectorPanel.release();
358 		testSuitesPanel.release();
359 		return release();
360 	}
361 
362 	private final class InternalTreeModelListener implements TreeModelListener
363 	{
364 		public void treeNodesChanged( TreeModelEvent e )
365 		{
366 			updateStatistics();
367 		}
368 
369 		public void treeNodesInserted( TreeModelEvent e )
370 		{
371 			updateStatistics();
372 		}
373 
374 		public void treeNodesRemoved( TreeModelEvent e )
375 		{
376 			updateStatistics();
377 		}
378 
379 		public void treeStructureChanged( TreeModelEvent e )
380 		{
381 			updateStatistics();
382 		}
383 	}
384 
385 	private class LoadScriptGroovyEditorModel extends AbstractGroovyEditorModel
386 	{
387 		public LoadScriptGroovyEditorModel()
388 		{
389 			super( new String[] { "log", "project" }, WsdlProjectDesktopPanel.this.getModelItem(), "Load" );
390 		}
391 
392 		@Override
393 		public String getScript()
394 		{
395 			return WsdlProjectDesktopPanel.this.getModelItem().getAfterLoadScript();
396 		}
397 
398 		@Override
399 		public void setScript( String text )
400 		{
401 			WsdlProjectDesktopPanel.this.getModelItem().setAfterLoadScript( text );
402 		}
403 
404 		@Override
405 		public Action getRunAction()
406 		{
407 			return new AfterLoadScriptRunAction();
408 		}
409 
410 		private final class AfterLoadScriptRunAction extends AbstractAction
411 		{
412 			public AfterLoadScriptRunAction()
413 			{
414 				putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_groovy_script.gif" ) );
415 				putValue( SHORT_DESCRIPTION, "Runs this script" );
416 			}
417 
418 			public void actionPerformed( ActionEvent e )
419 			{
420 				try
421 				{
422 					WsdlProjectDesktopPanel.this.getModelItem().runAfterLoadScript();
423 				}
424 				catch( Exception e1 )
425 				{
426 					UISupport.showErrorMessage( e1 );
427 				}
428 			}
429 		}
430 	}
431 
432 	private class SaveScriptGroovyEditorModel extends AbstractGroovyEditorModel
433 	{
434 		public SaveScriptGroovyEditorModel()
435 		{
436 			super( new String[] { "log", "project" }, WsdlProjectDesktopPanel.this.getModelItem(), "Save" );
437 		}
438 
439 		@Override
440 		public String getScript()
441 		{
442 			return WsdlProjectDesktopPanel.this.getModelItem().getBeforeSaveScript();
443 		}
444 
445 		@Override
446 		public void setScript( String text )
447 		{
448 			WsdlProjectDesktopPanel.this.getModelItem().setBeforeSaveScript( text );
449 		}
450 
451 		@Override
452 		public Action getRunAction()
453 		{
454 			return new BeforeSaveScriptRunAction();
455 		}
456 
457 		private final class BeforeSaveScriptRunAction extends AbstractAction
458 		{
459 			public BeforeSaveScriptRunAction()
460 			{
461 				putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_groovy_script.gif" ) );
462 				putValue( SHORT_DESCRIPTION, "Runs this script" );
463 			}
464 
465 			public void actionPerformed( ActionEvent e )
466 			{
467 				try
468 				{
469 					WsdlProjectDesktopPanel.this.getModelItem().runBeforeSaveScript();
470 				}
471 				catch( Exception e1 )
472 				{
473 					UISupport.showErrorMessage( e1 );
474 				}
475 			}
476 		}
477 	}
478 
479 }