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.Component;
17  import java.awt.Dimension;
18  import java.awt.event.ActionEvent;
19  import java.awt.event.FocusAdapter;
20  import java.awt.event.FocusEvent;
21  import java.awt.event.MouseAdapter;
22  import java.awt.event.MouseEvent;
23  import java.beans.PropertyChangeEvent;
24  import java.beans.PropertyChangeListener;
25  
26  import javax.swing.AbstractAction;
27  import javax.swing.Action;
28  import javax.swing.Box;
29  import javax.swing.JButton;
30  import javax.swing.JComponent;
31  import javax.swing.JLabel;
32  import javax.swing.ListModel;
33  
34  import org.apache.commons.lang.StringUtils;
35  import org.apache.log4j.Logger;
36  
37  import com.eviware.soapui.SoapUI;
38  import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
39  import com.eviware.soapui.impl.wsdl.panels.support.MockTestRunContext;
40  import com.eviware.soapui.impl.wsdl.panels.support.MockTestRunner;
41  import com.eviware.soapui.impl.wsdl.panels.support.TestRunComponentEnabler;
42  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.GroovyEditor;
43  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.GroovyEditorModel;
44  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
45  import com.eviware.soapui.impl.wsdl.teststeps.WsdlGroovyScriptTestStep;
46  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStepResult;
47  import com.eviware.soapui.model.ModelItem;
48  import com.eviware.soapui.model.settings.Settings;
49  import com.eviware.soapui.model.settings.SettingsListener;
50  import com.eviware.soapui.support.ListDataChangeListener;
51  import com.eviware.soapui.support.UISupport;
52  import com.eviware.soapui.support.components.JComponentInspector;
53  import com.eviware.soapui.support.components.JEditorStatusBarWithProgress;
54  import com.eviware.soapui.support.components.JInspectorPanel;
55  import com.eviware.soapui.support.components.JInspectorPanelFactory;
56  import com.eviware.soapui.support.components.JXToolBar;
57  import com.eviware.soapui.support.log.JLogList;
58  import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
59  
60  /***
61   * DesktopPanel for WsdlGroovyTestSteps
62   * 
63   * @author Ole.Matzura
64   */
65  
66  public class GroovyScriptStepDesktopPanel extends ModelItemDesktopPanel<WsdlGroovyScriptTestStep> implements
67  		PropertyChangeListener
68  {
69  	private final WsdlGroovyScriptTestStep groovyStep;
70  	private GroovyEditor editor;
71  	private JLogList logArea;
72  	private Logger logger;
73  	private TestRunComponentEnabler componentEnabler;
74  	private RunAction runAction = new RunAction();
75  	private JEditorStatusBarWithProgress statusBar;
76  	private SettingsListener settingsListener;
77  	private JComponentInspector<JComponent> logInspector;
78  	public boolean updating;
79  	private JInspectorPanel inspectorPanel;
80  
81  	public GroovyScriptStepDesktopPanel( WsdlGroovyScriptTestStep groovyStep )
82  	{
83  		super( groovyStep );
84  		this.groovyStep = groovyStep;
85  		componentEnabler = new TestRunComponentEnabler( groovyStep.getTestCase() );
86  
87  		buildUI();
88  		setPreferredSize( new Dimension( 600, 440 ) );
89  
90  		logger = Logger.getLogger( groovyStep.getName() + "#" + hashCode() );
91  
92  		addFocusListener( new FocusAdapter()
93  		{
94  
95  			public void focusGained( FocusEvent e )
96  			{
97  				editor.requestFocusInWindow();
98  			}
99  
100 		} );
101 
102 		groovyStep.addPropertyChangeListener( this );
103 	}
104 
105 	protected GroovyEditor getEditor()
106 	{
107 		return editor;
108 	}
109 
110 	private void buildUI()
111 	{
112 		editor = new GroovyEditor( new ScriptStepGroovyEditorModel() );
113 
114 		logArea = new JLogList( "Groovy Test Log" );
115 		logArea.addLogger( groovyStep.getName() + "#" + hashCode(), true );
116 		logArea.getLogList().addMouseListener( new MouseAdapter()
117 		{
118 
119 			public void mouseClicked( MouseEvent e )
120 			{
121 				if( e.getClickCount() < 2 )
122 					return;
123 
124 				String value = logArea.getLogList().getSelectedValue().toString();
125 				if( value == null )
126 					return;
127 
128 				editor.selectError( value );
129 			}
130 		} );
131 
132 		logArea.getLogList().getModel().addListDataListener( new ListDataChangeListener()
133 		{
134 
135 			@Override
136 			public void dataChanged( ListModel model )
137 			{
138 				logInspector.setTitle( "Log Output (" + model.getSize() + ")" );
139 
140 			}
141 		} );
142 
143 		inspectorPanel = JInspectorPanelFactory.build( editor );
144 		logInspector = inspectorPanel.addInspector( new JComponentInspector<JComponent>( logArea, "Log Output (0)",
145 				"Groovy Log output for this script", true ) );
146 		inspectorPanel.setDefaultDividerLocation( 0.8F );
147 		inspectorPanel.activate( logInspector );
148 		add( inspectorPanel.getComponent(), BorderLayout.CENTER );
149 		add( buildToolbar(), BorderLayout.NORTH );
150 		add( buildStatusBar(), BorderLayout.SOUTH );
151 
152 		componentEnabler.add( editor );
153 	}
154 
155 	private Component buildStatusBar()
156 	{
157 		statusBar = new JEditorStatusBarWithProgress( editor );
158 		return statusBar;
159 	}
160 
161 	private JComponent buildToolbar()
162 	{
163 		JXToolBar toolBar = UISupport.createToolbar();
164 		JButton runButton = UISupport.createToolbarButton( runAction );
165 		toolBar.add( runButton );
166 		toolBar.add( Box.createHorizontalGlue() );
167 		JLabel label = new JLabel( "<html>Script is invoked with <code>log</code>, <code>context</code> "
168 				+ "and <code>testRunner</code> variables</html>" );
169 		label.setToolTipText( label.getText() );
170 		label.setMaximumSize( label.getPreferredSize() );
171 
172 		toolBar.add( label );
173 		toolBar.addRelatedGap();
174 		toolBar.add( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.GROOVYSTEPEDITOR_HELP_URL ) ) );
175 
176 		componentEnabler.add( runButton );
177 
178 		return toolBar;
179 	}
180 
181 	public boolean onClose( boolean canCancel )
182 	{
183 		componentEnabler.release();
184 		editor.release();
185 		SoapUI.getSettings().removeSettingsListener( settingsListener );
186 		logger.removeAllAppenders();
187 		logger = null;
188 		logArea.release();
189 		inspectorPanel.release();
190 		return super.release();
191 	}
192 
193 	public JComponent getComponent()
194 	{
195 		return this;
196 	}
197 
198 	public boolean dependsOn( ModelItem modelItem )
199 	{
200 		return modelItem == groovyStep || modelItem == groovyStep.getTestCase()
201 				|| modelItem == groovyStep.getTestCase().getTestSuite()
202 				|| modelItem == groovyStep.getTestCase().getTestSuite().getProject();
203 	}
204 
205 	private class ScriptStepGroovyEditorModel implements GroovyEditorModel
206 	{
207 		public String[] getKeywords()
208 		{
209 			return new String[] { "log", "context", "testRunner" };
210 		}
211 
212 		public Action getRunAction()
213 		{
214 			return runAction;
215 		}
216 
217 		public String getScript()
218 		{
219 			return groovyStep.getScript();
220 		}
221 
222 		public void setScript( String text )
223 		{
224 			if( updating )
225 				return;
226 
227 			updating = true;
228 			groovyStep.setScript( text );
229 			updating = false;
230 		}
231 
232 		public Settings getSettings()
233 		{
234 			return SoapUI.getSettings();
235 		}
236 
237 		public String getScriptName()
238 		{
239 			return null;
240 		}
241 
242 		public void addPropertyChangeListener( PropertyChangeListener listener )
243 		{
244 		}
245 
246 		public void removePropertyChangeListener( PropertyChangeListener listener )
247 		{
248 		}
249 
250 		public ModelItem getModelItem()
251 		{
252 			return groovyStep;
253 		}
254 	}
255 
256 	private class RunAction extends AbstractAction
257 	{
258 		public RunAction()
259 		{
260 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_groovy_script.gif" ) );
261 			putValue( Action.SHORT_DESCRIPTION, "Runs this script using a mock testRunner and testContext" );
262 		}
263 
264 		public void actionPerformed( ActionEvent e )
265 		{
266 			MockTestRunner mockTestRunner = new MockTestRunner( groovyStep.getTestCase(), logger );
267 			statusBar.setIndeterminate( true );
268 			WsdlTestStepResult result = ( WsdlTestStepResult )groovyStep.run( mockTestRunner, new MockTestRunContext(
269 					mockTestRunner, groovyStep ) );
270 			statusBar.setIndeterminate( false );
271 
272 			Throwable er = result.getError();
273 			if( er != null )
274 			{
275 				String message = er.getMessage();
276 
277 				// ugly...
278 				editor.selectError( message );
279 
280 				UISupport.showErrorMessage( er.toString() );
281 				editor.requestFocus();
282 			}
283 			else if( result.getMessages().length > 0 )
284 			{
285 				UISupport.showInfoMessage( StringUtils.join( result.getMessages(), "\n" ) );
286 			}
287 		}
288 	}
289 
290 	public void propertyChange( PropertyChangeEvent evt )
291 	{
292 		if( evt.getPropertyName().equals( "script" ) && !updating )
293 		{
294 			updating = true;
295 			editor.getEditArea().setText( ( String )evt.getNewValue() );
296 			updating = false;
297 		}
298 	}
299 }