package abbot.editor;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.*;
import junit.runner.*;
import abbot.Log;
import abbot.i18n.Strings;
import abbot.util.PathClassLoader;
import abbot.editor.widgets.ArrayEditor;
import junit.extensions.abbot.ScriptTestCollector;
/**
* A test class selector. A simple dialog to pick the name of a test suite.
* Allows user to set the class path searched for script suite classes.
* Thanks to JUnit for this code.
*/
public class TestSelector extends JDialog {
/** If the selected item is this value, then use no test case class. */
public static final String TEST_NONE = "<None>";
private JList fList;
private ArrayEditor pathEditor;
private JButton fOk;
private String fSelectedItem;
/**
* Renders TestFailures in a JList
*/
static class TestCellRenderer extends DefaultListCellRenderer {
Icon fLeafIcon;
Icon fSuiteIcon;
public TestCellRenderer() {
fLeafIcon= UIManager.getIcon("Tree.leafIcon");
fSuiteIcon= UIManager.getIcon("Tree.closedIcon");
}
public Component getListCellRendererComponent(
JList list, Object value, int modelIndex,
boolean isSelected, boolean cellHasFocus) {
Component c= super.getListCellRendererComponent(list, value, modelIndex, isSelected, cellHasFocus);
String displayString= displayString((String)value);
if (displayString.startsWith("AllTests"))
setIcon(fSuiteIcon);
else
setIcon(fLeafIcon);
setText(displayString);
return c;
}
public static String displayString(String className) {
int typeIndex= className.lastIndexOf('.');
if (typeIndex < 0)
return className;
return className.substring(typeIndex+1) + " - " + className.substring(0, typeIndex);
}
public static boolean matchesKey(String s, char ch) {
return ch == Character.toUpperCase(s.charAt(typeIndex(s)));
}
private static int typeIndex(String s) {
int typeIndex= s.lastIndexOf('.');
int i= 0;
if (typeIndex > 0)
i= typeIndex+1;
return i;
}
}
protected class DoubleClickListener extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
okSelected();
}
}
}
protected class KeySelectListener extends KeyAdapter {
public void keyTyped(KeyEvent e) {
keySelectTestClass(e.getKeyChar());
}
}
public TestSelector(Frame parent, String classPath) {
super(parent, true);
setSize(350, 300);
setResizable(false);
setLocationRelativeTo(parent);
setTitle(Strings.get("TestSelector.title"));
fList= new JList();
fList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
fList.setCellRenderer(new TestCellRenderer());
setCollector(classPath);
JScrollPane listScroll = new JScrollPane(fList);
String[] paths = PathClassLoader.convertPathToFilenames(classPath);
pathEditor = new ArrayEditor(paths);
JScrollPane scroll = new JScrollPane(pathEditor);
JPanel path = new JPanel(new BorderLayout());
JLabel label = new JLabel(Strings.get("selector.classpath"));
path.add(label, BorderLayout.NORTH);
path.add(scroll, BorderLayout.CENTER);
JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
listScroll, path);
split.setBorder(null);
JButton cancel =
new JButton(UIManager.getString("OptionPane.cancelButtonText"));
JButton none = new JButton(Strings.get("None"));
JLabel desc = new JLabel(Strings.get("SelectTest"));
fOk = new JButton(UIManager.getString("OptionPane.okButtonText"));
fOk.setEnabled(false);
getRootPane().setDefaultButton(fOk);
defineLayout(desc, split, fOk, none, cancel);
addListeners(fOk, none, cancel);
}
public void setCollector(String classPath) {
// Ensure abbot.jar is always in the class path
String fallback = System.getProperty("java.class.path");
if (fallback.indexOf("abbot.jar") == -1) {
fallback = System.getProperty("abbot.class.path");
if (fallback.indexOf("abbot.jar") == -1) {
Log.warn("abbot.jar not found in classpath");
}
}
classPath += System.getProperty("path.separator") + fallback;
ClassLoader cl = new PathClassLoader(classPath);
TestCollector collector = new ScriptTestCollector(cl);
final Object[] list = createTestList(collector).toArray();
setTestList(list);
}
private void setTestList(final Object[] list) {
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
setTestList(list);
}
});
return;
}
try {
getParent().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
fList.setModel(new AbstractListModel() {
public int getSize() { return list.length; }
public Object getElementAt(int i) { return list[i]; }
});
} finally {
getParent().setCursor(Cursor.getDefaultCursor());
}
}
private void addListeners(final JButton ok, JButton none, JButton cancel) {
cancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
none.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fSelectedItem = TEST_NONE;
dispose();
}
});
ok.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
okSelected();
}
});
fList.addMouseListener(new DoubleClickListener());
fList.addKeyListener(new KeySelectListener());
fList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
checkEnableOK(e);
}
});
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
}
});
pathEditor.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Object[] values = pathEditor.getValues();
final StringBuffer buf = new StringBuffer();
for (int i=0;i < values.length;i++) {
buf.append(values[i]);
buf.append(System.getProperty("path.separator"));
}
new Thread("Available classes loader") {
public void run() {
setCollector(buf.toString());
}
}.start();
}
});
}
private void defineLayout(Component desc, Component center,
Component ok, Component none, Component cancel) {
getContentPane().setLayout(new BorderLayout());
((JPanel)getContentPane()).setBorder(new EmptyBorder(4,4,4,4));
getContentPane().add(desc, BorderLayout.NORTH);
getContentPane().add(center, BorderLayout.CENTER);
JPanel buttons = new JPanel(new GridLayout(1, 0));
buttons.add(ok);
buttons.add(none);
buttons.add(cancel);
getContentPane().add(buttons, BorderLayout.SOUTH);
}
public void checkEnableOK(ListSelectionEvent e) {
fOk.setEnabled(fList.getSelectedIndex() != -1);
}
public void okSelected() {
fSelectedItem= (String)fList.getSelectedValue();
dispose();
}
public boolean isEmpty() {
return fList.getModel().getSize() == 0;
}
public void keySelectTestClass(char ch) {
ListModel model= fList.getModel();
if (!Character.isJavaIdentifierStart(ch))
return;
for (int i= 0; i < model.getSize(); i++) {
String s= (String)model.getElementAt(i);
if (TestCellRenderer.matchesKey(s, Character.toUpperCase(ch))) {
fList.setSelectedIndex(i);
fList.ensureIndexIsVisible(i);
return;
}
}
Toolkit.getDefaultToolkit().beep();
}
public String getSelectedItem() {
return fSelectedItem;
}
private List createTestList(TestCollector collector) {
Enumeration each= collector.collectTests();
Vector v= new Vector();
Vector displayVector= new Vector();
while(each.hasMoreElements()) {
String s= (String)each.nextElement();
v.add(s);
displayVector.add(TestCellRenderer.displayString(s));
}
if (v.size() > 0)
Sorter.sortStrings(displayVector, 0,
displayVector.size()-1,
new ParallelSwapper(v));
return new ArrayList(v);
}
private class ParallelSwapper implements Sorter.Swapper {
Vector fOther;
ParallelSwapper(Vector other) {
fOther= other;
}
public void swap(Vector values, int left, int right) {
Object tmp= values.elementAt(left);
values.setElementAt(values.elementAt(right), left);
values.setElementAt(tmp, right);
Object tmp2= fOther.elementAt(left);
fOther.setElementAt(fOther.elementAt(right), left);
fOther.setElementAt(tmp2, right);
}
}
}