View Javadoc

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