/*
* 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.testcase;
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.config.TestStepConfig;
import com.eviware.soapui.impl.wsdl.actions.teststep.RunFromTestStepAction;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep;
import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestStepFactory;
import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestStepRegistry;
import com.eviware.soapui.model.ModelItem;
import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
import com.eviware.soapui.model.testsuite.TestStep;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.action.swing.ActionListBuilder;
import com.eviware.soapui.support.action.swing.ActionSupport;
import com.eviware.soapui.support.action.swing.SwingActionDelegate;
import com.eviware.soapui.support.swing.AutoscrollSupport;
import com.eviware.soapui.support.swing.ModelItemListKeyListener;
import com.eviware.soapui.support.swing.ModelItemListMouseListener;
import javax.swing.AbstractAction;
import javax.swing.AbstractListModel;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSeparator;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Insets;
import java.awt.Point;
import java.awt.dnd.Autoscroll;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
/**
* Panel for displaying and editing a list of TestSteps
*
* @author Ole.Matzura
*/
public class JTestStepList extends JPanel {
private TestStepListModel testStepListModel;
private JList testStepList;
private JPopupMenu testListPopup;
private JMenu appendStepMenu;
private final WsdlTestCase testCase;
public JTestStepList(WsdlTestCase testCase) {
super(new BorderLayout());
setDoubleBuffered(true);
this.testCase = testCase;
buildUI();
}
public JList getTestStepList() {
return testStepList;
}
private void buildUI() {
testStepListModel = new TestStepListModel();
testStepList = new TestStepJList(testStepListModel);
testStepList.setCellRenderer(new TestStepCellRenderer());
testStepList.setFixedCellHeight(22);
testStepList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
testStepList.addKeyListener(new TestStepListKeyHandler());
testStepList.addMouseListener(new ModelItemListMouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
int row = testStepList.locationToIndex(e.getPoint());
if (row != -1) {
ModelItem item = (ModelItem) testStepList.getModel().getElementAt(row);
if (item != null) {
UISupport.select(item);
}
}
super.mouseClicked(e);
}
});
testListPopup = new JPopupMenu();
testListPopup.addSeparator();
appendStepMenu = new JMenu("Append Step");
WsdlTestStepRegistry registry = WsdlTestStepRegistry.getInstance();
WsdlTestStepFactory[] factories = (WsdlTestStepFactory[]) registry.getFactories();
for (int c = 0; c < factories.length; c++) {
if (factories[c].canCreate()) {
appendStepMenu.add(new InsertTestStepAction(factories[c]));
}
}
testListPopup.add(appendStepMenu);
testListPopup.addPopupMenuListener(new StepListPopupMenuListener(testCase));
testStepList.setComponentPopupMenu(testListPopup);
add(testStepList, BorderLayout.CENTER);
}
public void setEnabled(boolean enabled) {
testStepList.setEnabled(enabled);
super.setEnabled(enabled);
}
private final class TestStepListKeyHandler extends ModelItemListKeyListener {
@Override
public ModelItem getModelItemAt(int ix) {
return testCase.getTestStepAt(ix);
}
}
private final class StepListPopupMenuListener implements PopupMenuListener {
private StepListPopupMenuListener(WsdlTestCase case1) {
super();
}
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
testListPopup.removeAll();
if (SoapUI.getTestMonitor().hasRunningLoadTest(testCase)) {
testListPopup.add("<disabled during LoadTest>").setEnabled(false);
return;
}
if (SoapUI.getTestMonitor().hasRunningSecurityTest(testCase)) {
testListPopup.add("<disabled during SecurityTest>").setEnabled(false);
return;
}
Point location = testStepList.getMousePosition();
int ix = -1;
if (location != null) {
int index = testStepList.locationToIndex(location);
if (index != -1 && !testStepList.isSelectedIndex(index)
&& testStepList.getCellBounds(index, index).contains(location)) {
testStepList.addSelectionInterval(index, index);
ix = index;
} else if (index != -1 && testStepList.isSelectedIndex(index)
&& testStepList.getCellBounds(index, index).contains(location)) {
ix = index;
}
}
if (ix >= 0) {
int[] indices = testStepList.getSelectedIndices();
if (indices.length == 1) {
WsdlTestStep testStep = testCase.getTestStepAt(ix);
ActionSupport.addActions(ActionListBuilder.buildActions(testStep), testListPopup);
testListPopup.insert(SwingActionDelegate.createDelegate(new RunFromTestStepAction(), testStep), 0);
testListPopup.insert(new JSeparator(), 1);
} else {
ModelItem[] modelItems = new ModelItem[indices.length];
for (int c = 0; c < indices.length; c++) {
modelItems[c] = testCase.getTestStepAt(indices[c]).getModelItem();
}
ActionSupport.addActions(ActionListBuilder.buildMultiActions(modelItems), testListPopup);
}
} else {
testStepList.clearSelection();
testListPopup.add(appendStepMenu);
}
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
}
public void popupMenuCanceled(PopupMenuEvent e) {
}
}
// private final class StepListMouseListener extends MouseAdapter
// {
// public void mouseClicked(MouseEvent e)
// {
// if (e.getClickCount() < 2)
// {
// return;
// }
//
// ModelItem modelItem = (ModelItem) testStepList.getSelectedValue();
// if (modelItem == null)
// return;
//
// Action defaultAction = ActionListBuilder.buildActions( modelItem
// ).getDefaultAction();
// if( defaultAction != null )
// defaultAction.actionPerformed( new ActionEvent( TestStepList.this, 0, null
// ));
// }
// }
/**
* Renderer which sets icon and wider border for teststeps
*
* @author Ole.Matzura
*/
private final static class TestStepCellRenderer extends JLabel implements ListCellRenderer {
public TestStepCellRenderer() {
setOpaque(true);
setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
}
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
boolean cellHasFocus) {
WsdlTestStep testStep = (WsdlTestStep) value;
setText(testStep.getLabel());
setIcon(testStep.getIcon());
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
setEnabled(list.isEnabled() && !testStep.isDisabled());
String toolTipText = list.getToolTipText();
if (toolTipText == null) {
setToolTipText(testStep.getDescription());
} else {
setToolTipText(toolTipText.length() == 0 ? null : toolTipText);
}
return this;
}
}
private class TestStepListModel extends AbstractListModel implements PropertyChangeListener {
private TestStepListTestSuiteListener testStepListTestSuiteListener = new TestStepListTestSuiteListener();
public TestStepListModel() {
for (int c = 0; c < getSize(); c++) {
testCase.getTestStepAt(c).addPropertyChangeListener(this);
}
testCase.getTestSuite().addTestSuiteListener(testStepListTestSuiteListener);
}
public int getSize() {
return testCase.getTestStepCount();
}
public Object getElementAt(int index) {
return testCase.getTestStepAt(index);
}
public synchronized void propertyChange(PropertyChangeEvent arg0) {
final int ix = testCase.getIndexOfTestStep((TestStep) arg0.getSource());
if (ix == -1) {
return;
}
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
fireContentsChanged(this, ix, ix);
}
});
} else {
fireContentsChanged(this, ix, ix);
}
}
public void release() {
testCase.getTestSuite().removeTestSuiteListener(testStepListTestSuiteListener);
for (int c = 0; c < getSize(); c++) {
testCase.getTestStepAt(c).removePropertyChangeListener(this);
}
}
private class TestStepListTestSuiteListener extends TestSuiteListenerAdapter {
public void testStepAdded(TestStep testStep, int ix) {
if (testStep.getTestCase() == testCase) {
testStep.addPropertyChangeListener(TestStepListModel.this);
// setSelectedValue( testStep, true );
fireIntervalAdded(TestStepListModel.this, ix, ix);
}
}
public void testStepRemoved(TestStep testStep, int ix) {
if (testStep.getTestCase() == testCase) {
testStep.removePropertyChangeListener(TestStepListModel.this);
fireIntervalRemoved(TestStepListModel.this, ix, ix);
}
}
@Override
public void testStepMoved(TestStep testStep, int fromIndex, int offset) {
if (testStep.getTestCase() == testCase) {
fireContentsChanged(TestStepListModel.this, fromIndex, fromIndex + offset);
int selectedIndex = testStepList.getSelectedIndex();
if (selectedIndex == fromIndex) {
testStepList.setSelectedIndex(fromIndex + offset);
} else if (selectedIndex < fromIndex && selectedIndex >= fromIndex + offset) {
testStepList.setSelectedIndex(selectedIndex + 1);
} else if (selectedIndex > fromIndex && selectedIndex <= fromIndex + offset) {
testStepList.setSelectedIndex(selectedIndex - 1);
}
}
}
}
}
public class InsertTestStepAction extends AbstractAction {
private final WsdlTestStepFactory factory;
public InsertTestStepAction(WsdlTestStepFactory factory) {
super(factory.getTestStepName());
putValue(Action.SHORT_DESCRIPTION, factory.getTestStepDescription());
putValue(Action.SMALL_ICON, UISupport.createImageIcon(factory.getTestStepIconPath()));
this.factory = factory;
}
public void actionPerformed(ActionEvent e) {
if (!factory.canAddTestStepToTestCase(testCase)) {
return;
}
String name = UISupport.prompt("Specify name for new step", "Insert Step", factory.getTestStepName());
if (name != null) {
TestStepConfig newTestStepConfig = factory.createNewTestStep(testCase, name);
if (newTestStepConfig != null) {
WsdlTestStep testStep = testCase.addTestStep(newTestStepConfig);
UISupport.selectAndShow(testStep);
}
}
}
}
public void setSelectedIndex(int i) {
testStepList.setSelectedIndex(i);
}
public void setSelectedValue(TestStep testStep, boolean b) {
try {
testStepList.setSelectedValue(testStep, true);
} catch (RuntimeException e) {
e.printStackTrace();
}
}
public void release() {
testStepListModel.release();
}
private static class TestStepJList extends JList implements Autoscroll {
private AutoscrollSupport autoscrollSupport;
public TestStepJList(TestStepListModel testStepListModel) {
super(testStepListModel);
autoscrollSupport = new AutoscrollSupport(this, new Insets(10, 10, 10, 10));
}
public void autoscroll(Point cursorLoc) {
autoscrollSupport.autoscroll(cursorLoc);
}
public Insets getAutoscrollInsets() {
return autoscrollSupport.getAutoscrollInsets();
}
}
}