001: package abbot.editor;
002:
003: import java.awt.*;
004: import java.awt.event.*;
005: import java.util.*;
006: import java.util.List;
007:
008: import javax.swing.*;
009: import javax.swing.border.EmptyBorder;
010: import javax.swing.event.*;
011:
012: import junit.runner.*;
013: import abbot.Log;
014: import abbot.i18n.Strings;
015: import abbot.util.PathClassLoader;
016: import abbot.editor.widgets.ArrayEditor;
017: import junit.extensions.abbot.ScriptTestCollector;
018:
019: /**
020: * A test class selector. A simple dialog to pick the name of a test suite.
021: * Allows user to set the class path searched for script suite classes.
022: * Thanks to JUnit for this code.
023: */
024: public class TestSelector extends JDialog {
025: /** If the selected item is this value, then use no test case class. */
026: public static final String TEST_NONE = "<None>";
027:
028: private JList fList;
029: private ArrayEditor pathEditor;
030: private JButton fOk;
031: private String fSelectedItem;
032:
033: /**
034: * Renders TestFailures in a JList
035: */
036: static class TestCellRenderer extends DefaultListCellRenderer {
037: Icon fLeafIcon;
038: Icon fSuiteIcon;
039:
040: public TestCellRenderer() {
041: fLeafIcon = UIManager.getIcon("Tree.leafIcon");
042: fSuiteIcon = UIManager.getIcon("Tree.closedIcon");
043: }
044:
045: public Component getListCellRendererComponent(JList list,
046: Object value, int modelIndex, boolean isSelected,
047: boolean cellHasFocus) {
048: Component c = super .getListCellRendererComponent(list,
049: value, modelIndex, isSelected, cellHasFocus);
050: String displayString = displayString((String) value);
051:
052: if (displayString.startsWith("AllTests"))
053: setIcon(fSuiteIcon);
054: else
055: setIcon(fLeafIcon);
056:
057: setText(displayString);
058: return c;
059: }
060:
061: public static String displayString(String className) {
062: int typeIndex = className.lastIndexOf('.');
063: if (typeIndex < 0)
064: return className;
065: return className.substring(typeIndex + 1) + " - "
066: + className.substring(0, typeIndex);
067: }
068:
069: public static boolean matchesKey(String s, char ch) {
070: return ch == Character.toUpperCase(s.charAt(typeIndex(s)));
071: }
072:
073: private static int typeIndex(String s) {
074: int typeIndex = s.lastIndexOf('.');
075: int i = 0;
076: if (typeIndex > 0)
077: i = typeIndex + 1;
078: return i;
079: }
080: }
081:
082: protected class DoubleClickListener extends MouseAdapter {
083: public void mouseClicked(MouseEvent e) {
084: if (e.getClickCount() == 2) {
085: okSelected();
086: }
087: }
088: }
089:
090: protected class KeySelectListener extends KeyAdapter {
091: public void keyTyped(KeyEvent e) {
092: keySelectTestClass(e.getKeyChar());
093: }
094: }
095:
096: public TestSelector(Frame parent, String classPath) {
097: super (parent, true);
098: setSize(350, 300);
099: setResizable(false);
100: setLocationRelativeTo(parent);
101: setTitle(Strings.get("TestSelector.title"));
102:
103: fList = new JList();
104: fList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
105: fList.setCellRenderer(new TestCellRenderer());
106: setCollector(classPath);
107: JScrollPane listScroll = new JScrollPane(fList);
108:
109: String[] paths = PathClassLoader
110: .convertPathToFilenames(classPath);
111: pathEditor = new ArrayEditor(paths);
112:
113: JScrollPane scroll = new JScrollPane(pathEditor);
114: JPanel path = new JPanel(new BorderLayout());
115: JLabel label = new JLabel(Strings.get("selector.classpath"));
116: path.add(label, BorderLayout.NORTH);
117: path.add(scroll, BorderLayout.CENTER);
118:
119: JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
120: listScroll, path);
121: split.setBorder(null);
122:
123: JButton cancel = new JButton(UIManager
124: .getString("OptionPane.cancelButtonText"));
125: JButton none = new JButton(Strings.get("None"));
126: JLabel desc = new JLabel(Strings.get("SelectTest"));
127: fOk = new JButton(UIManager
128: .getString("OptionPane.okButtonText"));
129: fOk.setEnabled(false);
130: getRootPane().setDefaultButton(fOk);
131:
132: defineLayout(desc, split, fOk, none, cancel);
133: addListeners(fOk, none, cancel);
134: }
135:
136: public void setCollector(String classPath) {
137: // Ensure abbot.jar is always in the class path
138: String fallback = System.getProperty("java.class.path");
139: if (fallback.indexOf("abbot.jar") == -1) {
140: fallback = System.getProperty("abbot.class.path");
141: if (fallback.indexOf("abbot.jar") == -1) {
142: Log.warn("abbot.jar not found in classpath");
143: }
144: }
145: classPath += System.getProperty("path.separator") + fallback;
146:
147: ClassLoader cl = new PathClassLoader(classPath);
148: TestCollector collector = new ScriptTestCollector(cl);
149: final Object[] list = createTestList(collector).toArray();
150: setTestList(list);
151: }
152:
153: private void setTestList(final Object[] list) {
154: if (!SwingUtilities.isEventDispatchThread()) {
155: SwingUtilities.invokeLater(new Runnable() {
156: public void run() {
157: setTestList(list);
158: }
159: });
160: return;
161: }
162: try {
163: getParent().setCursor(
164: Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
165: fList.setModel(new AbstractListModel() {
166: public int getSize() {
167: return list.length;
168: }
169:
170: public Object getElementAt(int i) {
171: return list[i];
172: }
173: });
174: } finally {
175: getParent().setCursor(Cursor.getDefaultCursor());
176: }
177: }
178:
179: private void addListeners(final JButton ok, JButton none,
180: JButton cancel) {
181: cancel.addActionListener(new ActionListener() {
182: public void actionPerformed(ActionEvent e) {
183: dispose();
184: }
185: });
186:
187: none.addActionListener(new ActionListener() {
188: public void actionPerformed(ActionEvent e) {
189: fSelectedItem = TEST_NONE;
190: dispose();
191: }
192: });
193: ok.addActionListener(new ActionListener() {
194: public void actionPerformed(ActionEvent e) {
195: okSelected();
196: }
197: });
198:
199: fList.addMouseListener(new DoubleClickListener());
200: fList.addKeyListener(new KeySelectListener());
201: fList.addListSelectionListener(new ListSelectionListener() {
202: public void valueChanged(ListSelectionEvent e) {
203: checkEnableOK(e);
204: }
205: });
206:
207: addWindowListener(new WindowAdapter() {
208: public void windowClosing(WindowEvent e) {
209: dispose();
210: }
211: });
212:
213: pathEditor.addActionListener(new ActionListener() {
214: public void actionPerformed(ActionEvent e) {
215: Object[] values = pathEditor.getValues();
216: final StringBuffer buf = new StringBuffer();
217: for (int i = 0; i < values.length; i++) {
218: buf.append(values[i]);
219: buf.append(System.getProperty("path.separator"));
220: }
221: new Thread("Available classes loader") {
222: public void run() {
223: setCollector(buf.toString());
224: }
225: }.start();
226: }
227: });
228: }
229:
230: private void defineLayout(Component desc, Component center,
231: Component ok, Component none, Component cancel) {
232: getContentPane().setLayout(new BorderLayout());
233: ((JPanel) getContentPane()).setBorder(new EmptyBorder(4, 4, 4,
234: 4));
235: getContentPane().add(desc, BorderLayout.NORTH);
236: getContentPane().add(center, BorderLayout.CENTER);
237:
238: JPanel buttons = new JPanel(new GridLayout(1, 0));
239: buttons.add(ok);
240: buttons.add(none);
241: buttons.add(cancel);
242: getContentPane().add(buttons, BorderLayout.SOUTH);
243: }
244:
245: public void checkEnableOK(ListSelectionEvent e) {
246: fOk.setEnabled(fList.getSelectedIndex() != -1);
247: }
248:
249: public void okSelected() {
250: fSelectedItem = (String) fList.getSelectedValue();
251: dispose();
252: }
253:
254: public boolean isEmpty() {
255: return fList.getModel().getSize() == 0;
256: }
257:
258: public void keySelectTestClass(char ch) {
259: ListModel model = fList.getModel();
260: if (!Character.isJavaIdentifierStart(ch))
261: return;
262: for (int i = 0; i < model.getSize(); i++) {
263: String s = (String) model.getElementAt(i);
264: if (TestCellRenderer.matchesKey(s, Character
265: .toUpperCase(ch))) {
266: fList.setSelectedIndex(i);
267: fList.ensureIndexIsVisible(i);
268: return;
269: }
270: }
271: Toolkit.getDefaultToolkit().beep();
272: }
273:
274: public String getSelectedItem() {
275: return fSelectedItem;
276: }
277:
278: private List createTestList(TestCollector collector) {
279: Enumeration each = collector.collectTests();
280: Vector v = new Vector();
281: Vector displayVector = new Vector();
282: while (each.hasMoreElements()) {
283: String s = (String) each.nextElement();
284: v.add(s);
285: displayVector.add(TestCellRenderer.displayString(s));
286: }
287: if (v.size() > 0)
288: Sorter.sortStrings(displayVector, 0,
289: displayVector.size() - 1, new ParallelSwapper(v));
290: return new ArrayList(v);
291: }
292:
293: private class ParallelSwapper implements Sorter.Swapper {
294: Vector fOther;
295:
296: ParallelSwapper(Vector other) {
297: fOther = other;
298: }
299:
300: public void swap(Vector values, int left, int right) {
301: Object tmp = values.elementAt(left);
302: values.setElementAt(values.elementAt(right), left);
303: values.setElementAt(tmp, right);
304: Object tmp2 = fOther.elementAt(left);
305: fOther.setElementAt(fOther.elementAt(right), left);
306: fOther.setElementAt(tmp2, right);
307: }
308: }
309: }
|