View Javadoc

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