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