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.teststeps;
14  
15  import java.awt.BorderLayout;
16  import java.awt.Dimension;
17  import java.awt.event.ItemEvent;
18  import java.awt.event.ItemListener;
19  import java.beans.PropertyChangeEvent;
20  import java.text.SimpleDateFormat;
21  import java.util.Date;
22  
23  import javax.swing.JButton;
24  import javax.swing.JComboBox;
25  import javax.swing.JComponent;
26  import javax.swing.JPanel;
27  import javax.swing.ListModel;
28  import javax.swing.text.Document;
29  
30  import com.eviware.soapui.SoapUI;
31  import com.eviware.soapui.impl.rest.RestRequestInterface;
32  import com.eviware.soapui.impl.support.AbstractHttpRequest;
33  import com.eviware.soapui.impl.support.components.ModelItemXmlEditor;
34  import com.eviware.soapui.impl.support.panels.AbstractHttpXmlRequestDesktopPanel;
35  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
36  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
37  import com.eviware.soapui.impl.wsdl.teststeps.HttpTestRequestInterface;
38  import com.eviware.soapui.impl.wsdl.teststeps.HttpTestRequestStepInterface;
39  import com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestInterface;
40  import com.eviware.soapui.impl.wsdl.teststeps.actions.AddAssertionAction;
41  import com.eviware.soapui.model.ModelItem;
42  import com.eviware.soapui.model.iface.Submit;
43  import com.eviware.soapui.model.iface.SubmitContext;
44  import com.eviware.soapui.model.iface.Request.SubmitException;
45  import com.eviware.soapui.model.support.ModelSupport;
46  import com.eviware.soapui.model.testsuite.AssertionError;
47  import com.eviware.soapui.model.testsuite.AssertionsListener;
48  import com.eviware.soapui.model.testsuite.LoadTestRunner;
49  import com.eviware.soapui.model.testsuite.TestAssertion;
50  import com.eviware.soapui.model.testsuite.TestCaseRunner;
51  import com.eviware.soapui.model.testsuite.Assertable.AssertionStatus;
52  import com.eviware.soapui.monitor.support.TestMonitorListenerAdapter;
53  import com.eviware.soapui.support.DocumentListenerAdapter;
54  import com.eviware.soapui.support.ListDataChangeListener;
55  import com.eviware.soapui.support.StringUtils;
56  import com.eviware.soapui.support.UISupport;
57  import com.eviware.soapui.support.components.JComponentInspector;
58  import com.eviware.soapui.support.components.JInspectorPanel;
59  import com.eviware.soapui.support.components.JInspectorPanelFactory;
60  import com.eviware.soapui.support.components.JUndoableTextField;
61  import com.eviware.soapui.support.components.JXToolBar;
62  import com.eviware.soapui.support.log.JLogList;
63  
64  public class HttpTestRequestDesktopPanel extends
65  		AbstractHttpXmlRequestDesktopPanel<HttpTestRequestStepInterface, HttpTestRequestInterface<?>>
66  {
67  	private JLogList logArea;
68  	private InternalTestMonitorListener testMonitorListener = new InternalTestMonitorListener();
69  	private JButton addAssertionButton;
70  	protected boolean updatingRequest;
71  	private AssertionsPanel assertionsPanel;
72  	private JInspectorPanel inspectorPanel;
73  	private JComponentInspector<?> assertionInspector;
74  	private JComponentInspector<?> logInspector;
75  	private InternalAssertionsListener assertionsListener = new InternalAssertionsListener();
76  	private long startTime;
77  	private SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
78  	private boolean updating;
79  	private JUndoableTextField pathTextField;
80  	private JComboBox methodCombo;
81  
82  	public HttpTestRequestDesktopPanel( HttpTestRequestStepInterface testStep )
83  	{
84  		super( testStep, testStep.getTestRequest() );
85  
86  		SoapUI.getTestMonitor().addTestMonitorListener( testMonitorListener );
87  		setEnabled( !SoapUI.getTestMonitor().hasRunningTest( testStep.getTestCase() ) );
88  
89  		testStep.getTestRequest().addAssertionsListener( assertionsListener );
90  
91  		getSubmitButton().setEnabled( getSubmit() == null && StringUtils.hasContent( getRequest().getEndpoint() ) );
92  	}
93  
94  	protected JComponent buildLogPanel()
95  	{
96  		logArea = new JLogList( "Request Log" );
97  
98  		logArea.getLogList().getModel().addListDataListener( new ListDataChangeListener()
99  		{
100 			public void dataChanged( ListModel model )
101 			{
102 				logInspector.setTitle( "Request Log (" + model.getSize() + ")" );
103 			}
104 		} );
105 
106 		return logArea;
107 	}
108 
109 	protected AssertionsPanel buildAssertionsPanel()
110 	{
111 		return new AssertionsPanel( getRequest() )
112 		{
113 			protected void selectError( AssertionError error )
114 			{
115 				ModelItemXmlEditor<?, ?> editor = ( ModelItemXmlEditor<?, ?> )getResponseEditor();
116 				editor.requestFocus();
117 			}
118 		};
119 	}
120 
121 	public void setContent( JComponent content )
122 	{
123 		inspectorPanel.setContentComponent( content );
124 	}
125 
126 	public void removeContent( JComponent content )
127 	{
128 		inspectorPanel.setContentComponent( null );
129 	}
130 
131 	protected String getHelpUrl()
132 	{
133 		return HelpUrls.TESTREQUESTEDITOR_HELP_URL;
134 	}
135 
136 	protected JComponent buildContent()
137 	{
138 		JComponent component = super.buildContent();
139 
140 		inspectorPanel = JInspectorPanelFactory.build( component );
141 		assertionsPanel = buildAssertionsPanel();
142 
143 		assertionInspector = new JComponentInspector<JComponent>( assertionsPanel, "Assertions ("
144 				+ getModelItem().getAssertionCount() + ")", "Assertions for this Test Request", true );
145 
146 		inspectorPanel.addInspector( assertionInspector );
147 
148 		logInspector = new JComponentInspector<JComponent>( buildLogPanel(), "Request Log (0)", "Log of requests", true );
149 		inspectorPanel.addInspector( logInspector );
150 		inspectorPanel.setDefaultDividerLocation( 0.6F );
151 		inspectorPanel.setCurrentInspector( "Assertions" );
152 
153 		updateStatusIcon();
154 
155 		getSubmitButton().setEnabled( getSubmit() == null && StringUtils.hasContent( getRequest().getEndpoint() ) );
156 
157 		return inspectorPanel.getComponent();
158 	}
159 
160 	protected JComponent buildEndpointComponent()
161 	{
162 		return null;
163 	}
164 
165 	private void updateStatusIcon()
166 	{
167 		AssertionStatus status = getModelItem().getTestRequest().getAssertionStatus();
168 		switch( status )
169 		{
170 		case FAILED :
171 		{
172 			assertionInspector.setIcon( UISupport.createImageIcon( "/failed_assertion.gif" ) );
173 			inspectorPanel.activate( assertionInspector );
174 			break;
175 		}
176 		case UNKNOWN :
177 		{
178 			assertionInspector.setIcon( UISupport.createImageIcon( "/unknown_assertion.gif" ) );
179 			break;
180 		}
181 		case VALID :
182 		{
183 			assertionInspector.setIcon( UISupport.createImageIcon( "/valid_assertion.gif" ) );
184 			inspectorPanel.deactivate();
185 			break;
186 		}
187 		}
188 	}
189 
190 	protected void addMethodCombo( JXToolBar toolbar )
191 	{
192 		methodCombo = new JComboBox( RestRequestInterface.RequestMethod.getMethods() );
193 
194 		methodCombo.setSelectedItem( getRequest().getMethod() );
195 		methodCombo.setToolTipText( "Set desired HTTP method" );
196 		methodCombo.addItemListener( new ItemListener()
197 		{
198 			public void itemStateChanged( ItemEvent e )
199 			{
200 				updatingRequest = true;
201 				getRequest().setMethod( ( RestRequestInterface.RequestMethod )methodCombo.getSelectedItem() );
202 				updatingRequest = false;
203 			}
204 		} );
205 
206 		toolbar.addLabeledFixed( "Method", methodCombo );
207 		toolbar.addSeparator();
208 	}
209 
210 	protected void addToolbarComponents( JXToolBar toolbar )
211 	{
212 		toolbar.addSeparator();
213 		addMethodCombo( toolbar );
214 
215 		pathTextField = new JUndoableTextField();
216 		pathTextField.setPreferredSize( new Dimension( 300, 20 ) );
217 		pathTextField.setText( getRequest().getEndpoint() );
218 		pathTextField.setToolTipText( pathTextField.getText() );
219 		pathTextField.getDocument().addDocumentListener( new DocumentListenerAdapter()
220 		{
221 			@Override
222 			public void update( Document document )
223 			{
224 				if( updating )
225 					return;
226 
227 				updating = true;
228 				getRequest().setEndpoint( pathTextField.getText() );
229 				updating = false;
230 			}
231 		} );
232 
233 		toolbar.addLabeledFixed( "Request URL:", pathTextField );
234 
235 		toolbar.addSeparator();
236 	}
237 
238 	@Override
239 	protected JComponent buildToolbar()
240 	{
241 		addAssertionButton = createActionButton( new AddAssertionAction( getRequest() ), true );
242 
243 		JPanel panel = new JPanel( new BorderLayout() );
244 		panel.add( super.buildToolbar(), BorderLayout.NORTH );
245 
246 		JXToolBar toolbar = UISupport.createToolbar();
247 		addToolbarComponents( toolbar );
248 
249 		panel.add( toolbar, BorderLayout.SOUTH );
250 		return panel;
251 
252 	}
253 
254 	protected void insertButtons( JXToolBar toolbar )
255 	{
256 		toolbar.add( addAssertionButton );
257 	}
258 
259 	public void setEnabled( boolean enabled )
260 	{
261 		if( enabled == true )
262 			enabled = !SoapUI.getTestMonitor().hasRunningLoadTest( getModelItem().getTestCase() );
263 
264 		super.setEnabled( enabled );
265 		addAssertionButton.setEnabled( enabled );
266 		assertionsPanel.setEnabled( enabled );
267 
268 		if( SoapUI.getTestMonitor().hasRunningLoadTest( getRequest().getTestCase() ) )
269 		{
270 			getRequest().removeSubmitListener( this );
271 		}
272 		else
273 		{
274 			getRequest().addSubmitListener( this );
275 		}
276 	}
277 
278 	protected Submit doSubmit() throws SubmitException
279 	{
280 		return getRequest().submit( new WsdlTestRunContext( getModelItem() ), true );
281 	}
282 
283 	private final class InternalAssertionsListener implements AssertionsListener
284 	{
285 		public void assertionAdded( TestAssertion assertion )
286 		{
287 			assertionInspector.setTitle( "Assertions (" + getModelItem().getAssertionCount() + ")" );
288 		}
289 
290 		public void assertionRemoved( TestAssertion assertion )
291 		{
292 			assertionInspector.setTitle( "Assertions (" + getModelItem().getAssertionCount() + ")" );
293 		}
294 
295 		public void assertionMoved( TestAssertion assertion, int ix, int offset )
296 		{
297 			assertionInspector.setTitle( "Assertions (" + getModelItem().getAssertionCount() + ")" );
298 		}
299 	}
300 
301 	public boolean beforeSubmit( Submit submit, SubmitContext context )
302 	{
303 		boolean result = super.beforeSubmit( submit, context );
304 		startTime = System.currentTimeMillis();
305 		return result;
306 	}
307 
308 	protected void logMessages( String message, String infoMessage )
309 	{
310 		super.logMessages( message, infoMessage );
311 		logArea.addLine( sdf.format( new Date( startTime ) ) + " - " + message );
312 	}
313 
314 	@Override
315 	public void afterSubmit( Submit submit, SubmitContext context )
316 	{
317 		super.afterSubmit( submit, context );
318 		if( !isHasClosed() )
319 			updateStatusIcon();
320 	}
321 
322 	public boolean onClose( boolean canCancel )
323 	{
324 		if( super.onClose( canCancel ) )
325 		{
326 			assertionsPanel.release();
327 			inspectorPanel.release();
328 			SoapUI.getTestMonitor().removeTestMonitorListener( testMonitorListener );
329 			logArea.release();
330 			getModelItem().getTestRequest().removeAssertionsListener( assertionsListener );
331 			return true;
332 		}
333 
334 		return false;
335 	}
336 
337 	public boolean dependsOn( ModelItem modelItem )
338 	{
339 		if( getRequest().getOperation() == null )
340 			return modelItem == getRequest() || modelItem == getModelItem()
341 					|| ModelSupport.getModelItemProject( getRequest() ) == modelItem
342 					|| modelItem == getModelItem().getTestCase() || modelItem == getModelItem().getTestCase().getTestSuite();
343 		else
344 			return modelItem == getRequest() || modelItem == getModelItem() || modelItem == getRequest().getOperation()
345 					|| modelItem == getRequest().getOperation().getInterface()
346 					|| modelItem == getRequest().getOperation().getInterface().getProject()
347 					|| modelItem == getModelItem().getTestCase() || modelItem == getModelItem().getTestCase().getTestSuite();
348 	}
349 
350 	private class InternalTestMonitorListener extends TestMonitorListenerAdapter
351 	{
352 		public void loadTestFinished( LoadTestRunner runner )
353 		{
354 			setEnabled( !SoapUI.getTestMonitor().hasRunningTest( getModelItem().getTestCase() ) );
355 		}
356 
357 		public void loadTestStarted( LoadTestRunner runner )
358 		{
359 			if( runner.getLoadTest().getTestCase() == getModelItem().getTestCase() )
360 				setEnabled( false );
361 		}
362 
363 		public void testCaseFinished( TestCaseRunner runner )
364 		{
365 			setEnabled( !SoapUI.getTestMonitor().hasRunningTest( getModelItem().getTestCase() ) );
366 		}
367 
368 		public void testCaseStarted( TestCaseRunner runner )
369 		{
370 			if( runner.getTestCase() == getModelItem().getTestCase() )
371 				setEnabled( false );
372 		}
373 	}
374 
375 	public void propertyChange( PropertyChangeEvent evt )
376 	{
377 		if( evt.getPropertyName().equals( RestTestRequestInterface.STATUS_PROPERTY ) )
378 		{
379 			updateStatusIcon();
380 		}
381 		else if( evt.getPropertyName().equals( "path" ) )
382 		{
383 			getSubmitButton().setEnabled( getSubmit() == null && StringUtils.hasContent( getRequest().getEndpoint() ) );
384 		}
385 		else if( evt.getPropertyName().equals( AbstractHttpRequest.ENDPOINT_PROPERTY ))
386 		{
387 			updating = true;
388 			pathTextField.setText( String.valueOf( evt.getNewValue()) );
389 			updating = false;
390 		}
391 
392 		super.propertyChange( evt );
393 	}
394 
395 }