001: /*
002: * soapUI, copyright (C) 2004-2007 eviware.com
003: *
004: * soapUI is free software; you can redistribute it and/or modify it under the
005: * terms of version 2.1 of the GNU Lesser General Public License as published by
006: * the Free Software Foundation.
007: *
008: * soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009: * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
010: * See the GNU Lesser General Public License for more details at gnu.org.
011: */
012:
013: package com.eviware.soapui.impl.wsdl.teststeps.assertions;
014:
015: import java.awt.BorderLayout;
016: import java.awt.Component;
017: import java.awt.Dimension;
018: import java.awt.event.ActionEvent;
019: import java.awt.event.MouseAdapter;
020: import java.awt.event.MouseEvent;
021:
022: import javax.swing.AbstractAction;
023: import javax.swing.Action;
024: import javax.swing.BorderFactory;
025: import javax.swing.Box;
026: import javax.swing.JButton;
027: import javax.swing.JComponent;
028: import javax.swing.JDialog;
029: import javax.swing.JLabel;
030: import javax.swing.JPanel;
031: import javax.swing.JScrollPane;
032: import javax.swing.JSplitPane;
033:
034: import org.apache.log4j.Logger;
035: import org.apache.xmlbeans.XmlObject;
036:
037: import com.eviware.soapui.SoapUI;
038: import com.eviware.soapui.config.RequestAssertionConfig;
039: import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
040: import com.eviware.soapui.impl.wsdl.panels.teststeps.support.GroovyEditor;
041: import com.eviware.soapui.impl.wsdl.panels.teststeps.support.GroovyEditorModel;
042: import com.eviware.soapui.impl.wsdl.submit.WsdlMessageExchange;
043: import com.eviware.soapui.impl.wsdl.support.HelpUrls;
044: import com.eviware.soapui.impl.wsdl.support.assertions.Assertable;
045: import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
046: import com.eviware.soapui.impl.wsdl.teststeps.WsdlMessageAssertion;
047: import com.eviware.soapui.impl.wsdl.teststeps.WsdlResponseMessageExchange;
048: import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep;
049: import com.eviware.soapui.model.iface.SubmitContext;
050: import com.eviware.soapui.model.settings.Settings;
051: import com.eviware.soapui.model.testsuite.TestStep;
052: import com.eviware.soapui.support.UISupport;
053: import com.eviware.soapui.support.components.JXToolBar;
054: import com.eviware.soapui.support.log.JLogList;
055: import com.eviware.soapui.support.scripting.SoapUIScriptEngine;
056: import com.eviware.soapui.support.scripting.SoapUIScriptEngineRegistry;
057: import com.eviware.soapui.support.xml.XmlObjectConfigurationBuilder;
058: import com.eviware.soapui.support.xml.XmlObjectConfigurationReader;
059: import com.jgoodies.forms.builder.ButtonBarBuilder;
060:
061: /**
062: * Assertion performed by a custom Grooy Script
063: *
064: * @author ole.matzura
065: */
066:
067: public class GroovyScriptAssertion extends WsdlMessageAssertion
068: implements RequestAssertion, ResponseAssertion {
069: public static final String ID = "GroovyScriptAssertion";
070: public static final String LABEL = "Script Assertion";
071: private String scriptText;
072: private SoapUIScriptEngine scriptEngine;
073: private JDialog dialog;
074: private GroovyScriptAssertionPanel groovyScriptAssertionPanel;
075:
076: public GroovyScriptAssertion(
077: RequestAssertionConfig assertionConfig, Assertable modelItem) {
078: super (assertionConfig, modelItem, true, true);
079:
080: XmlObjectConfigurationReader reader = new XmlObjectConfigurationReader(
081: getConfiguration());
082: scriptText = reader.readString("scriptText", "");
083:
084: scriptEngine = SoapUIScriptEngineRegistry.create(
085: SoapUIScriptEngineRegistry.GROOVY_ID, this );
086: scriptEngine.setScript(scriptText);
087: }
088:
089: @Override
090: protected String internalAssertRequest(
091: WsdlMessageExchange messageExchange, SubmitContext context)
092: throws AssertionException {
093: return assertScript(messageExchange, context, SoapUI
094: .ensureGroovyLog());
095: }
096:
097: private String assertScript(WsdlMessageExchange messageExchange,
098: SubmitContext context, Logger log)
099: throws AssertionException {
100: try {
101: scriptEngine.setVariable("context", context);
102: scriptEngine
103: .setVariable("messageExchange", messageExchange);
104: scriptEngine.setVariable("log", log);
105:
106: Object result = scriptEngine.run();
107: return result == null ? null : result.toString();
108: } catch (Throwable e) {
109: throw new AssertionException(new AssertionError(e
110: .getMessage()));
111: } finally {
112: scriptEngine.clearVariables();
113: }
114: }
115:
116: @Override
117: protected String internalAssertResponse(
118: WsdlMessageExchange messageExchange, SubmitContext context)
119: throws AssertionException {
120: return assertScript(messageExchange, context, SoapUI
121: .ensureGroovyLog());
122: }
123:
124: @Override
125: public boolean configure() {
126: if (dialog == null) {
127: dialog = new JDialog(UISupport.getMainFrame(),
128: "Script Assertion", true);
129: groovyScriptAssertionPanel = new GroovyScriptAssertionPanel();
130: dialog.setContentPane(groovyScriptAssertionPanel);
131: dialog.pack();
132: }
133:
134: dialog.setVisible(true);
135:
136: setConfiguration(createConfiguration());
137: return true;
138: }
139:
140: protected XmlObject createConfiguration() {
141: XmlObjectConfigurationBuilder builder = new XmlObjectConfigurationBuilder();
142: builder.add("scriptText", scriptText);
143: return builder.finish();
144: }
145:
146: private class GroovyScriptAssertionPanel extends JPanel {
147: private GroovyEditor editor;
148: private JSplitPane mainSplit;
149: private JLogList logArea;
150: private RunAction runAction = new RunAction();
151: private Logger logger;
152:
153: public GroovyScriptAssertionPanel() {
154: super (new BorderLayout());
155:
156: buildUI();
157: setPreferredSize(new Dimension(600, 440));
158:
159: logger = Logger.getLogger("ScriptAssertion." + getName());
160: editor.requestFocusInWindow();
161: }
162:
163: public void release() {
164: logArea.release();
165: logger = null;
166: }
167:
168: private void buildUI() {
169: editor = new GroovyEditor(new ScriptStepGroovyEditorModel());
170:
171: logArea = new JLogList("Groovy Test Log");
172: logArea.addLogger("ScriptAssertion." + getName(), true);
173: logArea.getLogList().addMouseListener(new MouseAdapter() {
174:
175: public void mouseClicked(MouseEvent e) {
176: if (e.getClickCount() < 2)
177: return;
178:
179: String value = logArea.getLogList()
180: .getSelectedValue().toString();
181: if (value == null)
182: return;
183:
184: editor.selectError(value);
185: }
186: });
187:
188: JScrollPane scrollPane = new JScrollPane(editor);
189: scrollPane.setBorder(BorderFactory.createCompoundBorder(
190: BorderFactory.createEmptyBorder(0, 3, 0, 3),
191: scrollPane.getBorder()));
192:
193: mainSplit = UISupport.createVerticalSplit(scrollPane,
194: logArea);
195: mainSplit.setDividerLocation(280);
196: mainSplit.setResizeWeight(0.8);
197: add(mainSplit, BorderLayout.CENTER);
198: add(buildToolbar(), BorderLayout.NORTH);
199: add(buildStatusBar(), BorderLayout.SOUTH);
200: }
201:
202: private Component buildStatusBar() {
203: ButtonBarBuilder builder = new ButtonBarBuilder();
204:
205: builder.addFixed(UISupport
206: .createToolbarButton(new ShowOnlineHelpAction(
207: HelpUrls.GROOVYASSERTION_HELP_URL)));
208: builder.addGlue();
209: builder.addFixed(new JButton(new OkAction()));
210: builder.setBorder(BorderFactory.createEmptyBorder(0, 3, 3,
211: 3));
212: return builder.getPanel();
213: }
214:
215: private JComponent buildToolbar() {
216: JXToolBar toolBar = UISupport.createToolbar();
217: JButton runButton = UISupport
218: .createToolbarButton(runAction);
219: toolBar.add(runButton);
220: toolBar.add(Box.createHorizontalGlue());
221: JLabel label = new JLabel(
222: "<html>Script is invoked with <code>log</code>, <code>context</code> "
223: + "and <code>messageExchange</code> variables</html>");
224: label.setToolTipText(label.getText());
225: label.setMaximumSize(label.getPreferredSize());
226:
227: toolBar.addFixed(label);
228: toolBar.addSpace(3);
229:
230: return toolBar;
231: }
232:
233: private final class OkAction extends AbstractAction {
234: public OkAction() {
235: super ("OK");
236: }
237:
238: public void actionPerformed(ActionEvent e) {
239: dialog.setVisible(false);
240: }
241: }
242:
243: private class ScriptStepGroovyEditorModel implements
244: GroovyEditorModel {
245: public String[] getKeywords() {
246: return new String[] { "log", "context",
247: "messageExchange" };
248: }
249:
250: public Action getRunAction() {
251: return runAction;
252: }
253:
254: public String getScript() {
255: return scriptText;
256: }
257:
258: public void setScript(String text) {
259: scriptText = text;
260: scriptEngine.setScript(scriptText);
261: }
262:
263: public Settings getSettings() {
264: return SoapUI.getSettings();
265: }
266: }
267:
268: private class RunAction extends AbstractAction {
269: public RunAction() {
270: putValue(Action.SMALL_ICON, UISupport
271: .createImageIcon("/run_groovy_script.gif"));
272: putValue(
273: Action.SHORT_DESCRIPTION,
274: "Runs this assertion script against the last messageExchange with a mock testContext");
275: }
276:
277: public void actionPerformed(ActionEvent e) {
278: TestStep testStep = getAssertable().getTestStep();
279: WsdlMessageExchange exchange = null;
280:
281: if (testStep instanceof WsdlTestRequestStep) {
282: WsdlTestRequestStep testRequestStep = (WsdlTestRequestStep) testStep;
283: exchange = new WsdlResponseMessageExchange(
284: testRequestStep.getTestRequest());
285: ((WsdlResponseMessageExchange) exchange)
286: .setResponse(testRequestStep
287: .getTestRequest().getResponse());
288: }
289:
290: try {
291: String result = assertScript(exchange,
292: new WsdlTestRunContext(testStep), logger);
293: UISupport.showInfoMessage("Script Assertion Passed"
294: + ((result == null) ? "" : ": [" + result
295: + "]"));
296: } catch (AssertionException e1) {
297: UISupport.showErrorMessage(e1.getMessage());
298: } catch (Throwable t) {
299: SoapUI.logError(t);
300: UISupport.showErrorMessage(t.getMessage());
301: }
302:
303: editor.requestFocusInWindow();
304: }
305: }
306: }
307:
308: @Override
309: public void release() {
310: super.release();
311:
312: scriptEngine.release();
313:
314: if (groovyScriptAssertionPanel != null)
315: groovyScriptAssertionPanel.release();
316: }
317: }
|