/*
* SoapUI, Copyright (C) 2004-2016 SmartBear Software
*
* Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent
* versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl
*
* Unless required by applicable law or agreed to in writing, software distributed under the Licence is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the Licence for the specific language governing permissions and limitations
* under the Licence.
*/
package com.eviware.soapui.impl.wsdl.panels.teststeps;
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.impl.support.components.ModelItemXmlEditor;
import com.eviware.soapui.impl.wsdl.WsdlOperation;
import com.eviware.soapui.impl.wsdl.panels.mockoperation.AbstractWsdlMockResponseDesktopPanel;
import com.eviware.soapui.impl.wsdl.teststeps.WsdlMockResponseTestStep;
import com.eviware.soapui.model.ModelItem;
import com.eviware.soapui.model.mock.MockResult;
import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
import com.eviware.soapui.model.support.TestRunListenerAdapter;
import com.eviware.soapui.model.testsuite.Assertable;
import com.eviware.soapui.model.testsuite.AssertionError;
import com.eviware.soapui.model.testsuite.AssertionsListener;
import com.eviware.soapui.model.testsuite.LoadTestRunner;
import com.eviware.soapui.model.testsuite.TestAssertion;
import com.eviware.soapui.model.testsuite.TestCaseRunContext;
import com.eviware.soapui.model.testsuite.TestCaseRunner;
import com.eviware.soapui.model.testsuite.TestStep;
import com.eviware.soapui.model.testsuite.TestStepResult;
import com.eviware.soapui.monitor.support.TestMonitorListenerAdapter;
import com.eviware.soapui.security.SecurityTestRunner;
import com.eviware.soapui.support.DocumentListenerAdapter;
import com.eviware.soapui.support.ModelItemPropertyEditorModel;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.components.JComponentInspector;
import com.eviware.soapui.support.components.JInspectorPanel;
import com.eviware.soapui.support.components.JInspectorPanelFactory;
import com.eviware.soapui.support.components.JXToolBar;
import com.eviware.soapui.support.xml.XmlUtils;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.text.Document;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.util.Date;
public class WsdlMockResponseStepDesktopPanel extends AbstractWsdlMockResponseDesktopPanel<WsdlMockResponseTestStep> {
private JTextArea logArea;
private AssertionsPanel assertionsPanel;
private JTextField portField;
private JTextField pathField;
private InternalTestRunListener testRunListener;
private InternalTestMonitorListener testMonitorListener = new InternalTestMonitorListener();
private InternalAssertionsListener assertionsListener = new InternalAssertionsListener();
private JInspectorPanel inspectorPanel;
private JComponentInspector<JComponent> assertionInspector;
private JComponentInspector<JComponent> logInspector;
private ModelItemPropertyEditorModel<WsdlMockResponseTestStep> queryEditorModel;
private ModelItemPropertyEditorModel<WsdlMockResponseTestStep> matchEditorModel;
public WsdlMockResponseStepDesktopPanel(WsdlMockResponseTestStep mockResponseStep) {
super(mockResponseStep);
init(mockResponseStep.getMockResponse());
testRunListener = new InternalTestRunListener();
mockResponseStep.getTestCase().addTestRunListener(testRunListener);
SoapUI.getTestMonitor().addTestMonitorListener(testMonitorListener);
setEnabled(!SoapUI.getTestMonitor().hasRunningTest(mockResponseStep.getTestCase()));
mockResponseStep.addAssertionsListener(assertionsListener);
}
@Override
protected JComponent buildContent() {
inspectorPanel = JInspectorPanelFactory.build(super.buildContent());
assertionsPanel = buildAssertionsPanel();
assertionInspector = new JComponentInspector<JComponent>(assertionsPanel, "Assertions ("
+ getModelItem().getAssertionCount() + ")", "Assertions for this Request", true);
inspectorPanel.addInspector(assertionInspector);
logInspector = new JComponentInspector<JComponent>(buildLogPanel(), "Request Log (0)", "Log of requests", true);
inspectorPanel.addInspector(logInspector);
inspectorPanel.addInspector(new JComponentInspector<JComponent>(buildQueryMatchPanel(), "Query/Match",
"Query/Match configuration", true));
inspectorPanel.setDefaultDividerLocation(0.6F);
inspectorPanel.setCurrentInspector("Assertions");
updateStatusIcon();
return inspectorPanel.getComponent();
}
private void updateStatusIcon() {
Assertable.AssertionStatus status = getModelItem().getAssertionStatus();
switch (status) {
case FAILED: {
assertionInspector.setIcon(UISupport.createImageIcon("/failed_assertion.gif"));
inspectorPanel.activate(assertionInspector);
break;
}
case UNKNOWN: {
assertionInspector.setIcon(UISupport.createImageIcon("/unknown_assertion.png"));
break;
}
case VALID: {
assertionInspector.setIcon(UISupport.createImageIcon("/valid_assertion.gif"));
inspectorPanel.deactivate();
break;
}
}
}
private JComponent buildLogPanel() {
logArea = new JTextArea();
logArea.setEditable(false);
logArea.setToolTipText("Response Log");
JPanel panel = new JPanel(new BorderLayout());
panel.add(new JScrollPane(logArea), BorderLayout.CENTER);
return panel;
}
public void setContent(JComponent content) {
inspectorPanel.setContentComponent(content);
}
public void removeContent(JComponent content) {
inspectorPanel.setContentComponent(null);
}
@Override
protected void createToolbar(JXToolBar toolbar) {
toolbar.addUnrelatedGap();
toolbar.addFixed(new JLabel("Path"));
toolbar.addRelatedGap();
pathField = new JTextField(getModelItem().getPath(), 15);
pathField.getDocument().addDocumentListener(new DocumentListenerAdapter() {
@Override
public void update(Document document) {
getModelItem().setPath(pathField.getText());
}
});
toolbar.addFixed(pathField);
toolbar.addUnrelatedGap();
toolbar.addFixed(new JLabel("Port"));
toolbar.addRelatedGap();
portField = new JTextField(String.valueOf(getModelItem().getPort()), 5);
portField.getDocument().addDocumentListener(new DocumentListenerAdapter() {
@Override
public void update(Document document) {
try {
getModelItem().setPort(Integer.parseInt(portField.getText()));
} catch (NumberFormatException e) {
}
}
});
toolbar.addFixed(portField);
}
private JComponent buildQueryMatchPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.add(buildQueryMatchToolbar(), BorderLayout.NORTH);
JSplitPane splitPane = UISupport.createHorizontalSplit(buildQueryEditor(), buildMatchEditor());
panel.add(splitPane, BorderLayout.CENTER);
splitPane.setDividerLocation(200);
return panel;
}
private Component buildMatchEditor() {
JPanel panel = new JPanel(new BorderLayout());
matchEditorModel = new ModelItemPropertyEditorModel<WsdlMockResponseTestStep>(getModelItem(), "match");
panel.add(UISupport.getEditorFactory().buildXmlEditor(matchEditorModel), BorderLayout.CENTER);
UISupport.addTitledBorder(panel, "Matching Value");
return panel;
}
private Component buildQueryEditor() {
JPanel panel = new JPanel(new BorderLayout());
queryEditorModel = new ModelItemPropertyEditorModel<WsdlMockResponseTestStep>(getModelItem(), "query");
panel.add(UISupport.getEditorFactory().buildXPathEditor(queryEditorModel), BorderLayout.CENTER);
UISupport.addTitledBorder(panel, "XPath Query");
return panel;
}
protected JXToolBar buildQueryMatchToolbar() {
JXToolBar toolBar = UISupport.createSmallToolbar();
toolBar.addFixed(new JButton(new SelectFromCurrentAction()));
return toolBar;
}
public class SelectFromCurrentAction extends AbstractAction {
public SelectFromCurrentAction() {
super("Select from current");
putValue(Action.SHORT_DESCRIPTION, "Selects the Query XPath expression from the last request Match field");
}
public void actionPerformed(ActionEvent arg0) {
if (getModelItem().getLastResult() != null && getModelItem().getLastResult().getMockRequest() != null
&& StringUtils.hasContent(getModelItem().getQuery())) {
getModelItem().setMatch(
XmlUtils.getXPathValue(getModelItem().getLastResult().getMockRequest().getRequestContent(),
PropertyExpander.expandProperties(getModelItem(), getModelItem().getQuery())));
}
}
}
private AssertionsPanel buildAssertionsPanel() {
assertionsPanel = new AssertionsPanel(getModelItem()) {
protected void selectError(AssertionError error) {
ModelItemXmlEditor<?, ?> editor = getResponseEditor();
editor.requestFocus();
}
};
return assertionsPanel;
}
@Override
public boolean onClose(boolean canCancel) {
getModelItem().getTestCase().removeTestRunListener(testRunListener);
SoapUI.getTestMonitor().removeTestMonitorListener(testMonitorListener);
assertionsPanel.release();
queryEditorModel.release();
matchEditorModel.release();
inspectorPanel.release();
getModelItem().removeAssertionsListener(assertionsListener);
return super.onClose(canCancel);
}
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
pathField.setEnabled(enabled);
portField.setEnabled(enabled);
}
public boolean dependsOn(ModelItem modelItem) {
return modelItem == getModelItem() || modelItem == getModelItem().getTestCase()
|| modelItem == getModelItem().getOperation() || modelItem == getModelItem().getOperation().getInterface()
|| modelItem == getModelItem().getTestCase().getTestSuite()
|| modelItem == getModelItem().getTestCase().getTestSuite().getProject();
}
public class InternalTestRunListener extends TestRunListenerAdapter {
@Override
public void afterRun(TestCaseRunner testRunner, TestCaseRunContext runContext) {
setEnabled(true);
}
@Override
public void beforeRun(TestCaseRunner testRunner, TestCaseRunContext runContext) {
setEnabled(false);
}
@Override
public void beforeStep(TestCaseRunner testRunner, TestCaseRunContext runContext, TestStep testStep) {
if (testStep == getModelItem()) {
logArea.setText(logArea.getText() + new Date(System.currentTimeMillis()).toString()
+ ": Waiting for request on http://127.0.0.1:" + getModelItem().getPort() + getModelItem().getPath()
+ "\r\n");
}
}
@Override
public void afterStep(TestCaseRunner testRunner, TestCaseRunContext runContext, TestStepResult result) {
if (result.getTestStep() == getModelItem()) {
String msg = new Date(result.getTimeStamp()).toString() + ": Handled request in " + result.getTimeTaken()
+ "ms";
logArea.setText(logArea.getText() + msg + "\r\n");
}
}
}
private class InternalTestMonitorListener extends TestMonitorListenerAdapter {
public void loadTestFinished(LoadTestRunner runner) {
setEnabled(!SoapUI.getTestMonitor().hasRunningTest(getModelItem().getTestCase()));
}
public void loadTestStarted(LoadTestRunner runner) {
if (runner.getLoadTest().getTestCase() == getModelItem().getTestCase()) {
setEnabled(false);
}
}
public void securityTestFinished(SecurityTestRunner runner) {
setEnabled(!SoapUI.getTestMonitor().hasRunningTest(getModelItem().getTestCase()));
}
public void securityTestStarted(SecurityTestRunner runner) {
if (runner.getSecurityTest().getTestCase() == getModelItem().getTestCase()) {
setEnabled(false);
}
}
public void testCaseFinished(TestCaseRunner runner) {
setEnabled(!SoapUI.getTestMonitor().hasRunningTest(getModelItem().getTestCase()));
}
public void testCaseStarted(TestCaseRunner runner) {
if (runner.getTestCase() == getModelItem().getTestCase()) {
setEnabled(false);
}
}
}
public void propertyChange(PropertyChangeEvent evt) {
super.propertyChange(evt);
if (evt.getPropertyName().equals(WsdlMockResponseTestStep.STATUS_PROPERTY)) {
updateStatusIcon();
}
}
@SuppressWarnings("unused")
private final class DeclareNamespacesAction extends AbstractAction {
public DeclareNamespacesAction() {
putValue(Action.SMALL_ICON, UISupport.createImageIcon("/declareNs.gif"));
putValue(Action.SHORT_DESCRIPTION,
"Declare available response/request namespaces in source/target expressions");
}
public void actionPerformed(ActionEvent e) {
try {
MockResult lastResult = getMockResponse().getMockResult();
String content = null;
if (lastResult == null) {
if (!UISupport.confirm("Missing last result, declare from default request instead?",
"Declare Namespaces")) {
return;
}
content = ((WsdlOperation) getMockResponse().getMockOperation().getOperation()).createRequest(true);
} else {
content = lastResult.getMockRequest().getRequestContent();
}
String path = getModelItem().getQuery();
if (path == null) {
path = "";
}
getModelItem().setQuery(XmlUtils.declareXPathNamespaces(content) + path);
} catch (Exception e1) {
UISupport.showErrorMessage(e1);
}
}
}
private final class InternalAssertionsListener implements AssertionsListener {
public void assertionAdded(TestAssertion assertion) {
assertionInspector.setTitle("Assertions (" + getModelItem().getAssertionCount() + ")");
}
public void assertionRemoved(TestAssertion assertion) {
assertionInspector.setTitle("Assertions (" + getModelItem().getAssertionCount() + ")");
}
public void assertionMoved(TestAssertion assertion, int ix, int offset) {
assertionInspector.setTitle("Assertions (" + getModelItem().getAssertionCount() + ")");
}
}
}