This project has retired. For details please refer to its Attic page.
TckDialog xref

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.chemistry.opencmis.workbench;
20  
21  import java.awt.BorderLayout;
22  import java.awt.Color;
23  import java.awt.Component;
24  import java.awt.Dimension;
25  import java.awt.Frame;
26  import java.awt.Insets;
27  import java.awt.Rectangle;
28  import java.awt.event.ActionEvent;
29  import java.awt.event.ActionListener;
30  import java.awt.event.ItemEvent;
31  import java.awt.event.ItemListener;
32  import java.awt.event.MouseAdapter;
33  import java.awt.event.MouseEvent;
34  import java.io.Writer;
35  import java.util.HashMap;
36  import java.util.List;
37  import java.util.Map;
38  
39  import javax.swing.AbstractCellEditor;
40  import javax.swing.BorderFactory;
41  import javax.swing.Box;
42  import javax.swing.BoxLayout;
43  import javax.swing.JButton;
44  import javax.swing.JCheckBox;
45  import javax.swing.JComboBox;
46  import javax.swing.JDialog;
47  import javax.swing.JFrame;
48  import javax.swing.JLabel;
49  import javax.swing.JMenuItem;
50  import javax.swing.JOptionPane;
51  import javax.swing.JPanel;
52  import javax.swing.JPopupMenu;
53  import javax.swing.JProgressBar;
54  import javax.swing.JScrollPane;
55  import javax.swing.JTextField;
56  import javax.swing.JTree;
57  import javax.swing.SwingWorker;
58  import javax.swing.ToolTipManager;
59  import javax.swing.UIManager;
60  import javax.swing.border.EmptyBorder;
61  import javax.swing.tree.DefaultMutableTreeNode;
62  import javax.swing.tree.DefaultTreeModel;
63  import javax.swing.tree.TreeCellEditor;
64  import javax.swing.tree.TreeCellRenderer;
65  import javax.swing.tree.TreeNode;
66  
67  import org.apache.chemistry.opencmis.client.api.ObjectType;
68  import org.apache.chemistry.opencmis.commons.SessionParameter;
69  import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
70  import org.apache.chemistry.opencmis.tck.CmisTest;
71  import org.apache.chemistry.opencmis.tck.CmisTestGroup;
72  import org.apache.chemistry.opencmis.tck.CmisTestProgressMonitor;
73  import org.apache.chemistry.opencmis.tck.CmisTestResult;
74  import org.apache.chemistry.opencmis.tck.CmisTestResultStatus;
75  import org.apache.chemistry.opencmis.tck.impl.TestParameters;
76  import org.apache.chemistry.opencmis.tck.runner.AbstractRunner;
77  import org.apache.chemistry.opencmis.workbench.checks.SwingReport;
78  import org.apache.chemistry.opencmis.workbench.model.ClientModel;
79  
80  /**
81   * TCK dialog and runner.
82   */
83  public class TckDialog {
84  
85      private final Frame owner;
86      private final ClientModel model;
87      private final TckDialogRunner runner;
88  
89      private Map<CmisTestResultStatus, Integer> status;
90  
91      private JProgressBar groupsProgressBar;
92      private JProgressBar testsProgressBar;
93      private JLabel statusLabel;
94  
95      public TckDialog(Frame owner, ClientModel model) {
96          this.owner = owner;
97          this.model = model;
98          this.runner = new TckDialogRunner(model, this);
99  
100         status = new HashMap<CmisTestResultStatus, Integer>();
101         status.put(CmisTestResultStatus.INFO, 0);
102         status.put(CmisTestResultStatus.SKIPPED, 0);
103         status.put(CmisTestResultStatus.OK, 0);
104         status.put(CmisTestResultStatus.WARNING, 0);
105         status.put(CmisTestResultStatus.FAILURE, 0);
106         status.put(CmisTestResultStatus.UNEXPECTED_EXCEPTION, 0);
107 
108         try {
109             runner.loadDefaultTckGroups();
110         } catch (Exception e) {
111             JOptionPane.showMessageDialog(owner, "Error: " + e.getMessage(), "TCK Error", JOptionPane.ERROR_MESSAGE);
112             return;
113         }
114 
115         new TckSelectDialog();
116     }
117 
118     private class TckSelectDialog extends JDialog {
119         private static final long serialVersionUID = 1L;
120 
121         public TckSelectDialog() {
122             super(owner, "TCK", true);
123 
124             createGUI();
125         }
126 
127         private void createGUI() {
128             setPreferredSize(new Dimension(600, 500));
129             setMinimumSize(new Dimension(600, 500));
130 
131             setLayout(new BorderLayout());
132 
133             // tree
134             final DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Groups");
135             final JTree groupTree = new JTree(rootNode);
136 
137             for (CmisTestGroup group : runner.getGroups()) {
138                 final TestTreeNode groupNode = new TestTreeNode(groupTree, group);
139                 rootNode.add(groupNode);
140                 for (CmisTest test : group.getTests()) {
141                     final TestTreeNode testNode = new TestTreeNode(groupTree, test);
142                     groupNode.add(testNode);
143                 }
144             }
145 
146             ((DefaultTreeModel) groupTree.getModel()).reload();
147 
148             groupTree.setRootVisible(false);
149             groupTree.setCellRenderer(new TestTreeNodeRender());
150             groupTree.setCellEditor(new TestTreeNodeEditor());
151             groupTree.setEditable(true);
152             ToolTipManager.sharedInstance().registerComponent(groupTree);
153 
154             for (int i = 0; i < groupTree.getRowCount(); i++) {
155                 groupTree.expandRow(i);
156             }
157 
158             final JPopupMenu treePopup = new JPopupMenu();
159 
160             final JMenuItem selectItem = new JMenuItem("Select all");
161             selectItem.addActionListener(new ActionListener() {
162                 public void actionPerformed(ActionEvent e) {
163                     selectAll(groupTree, true);
164                 }
165             });
166             treePopup.add(selectItem);
167 
168             final JMenuItem deselectItem = new JMenuItem("Deselect all");
169             deselectItem.addActionListener(new ActionListener() {
170                 public void actionPerformed(ActionEvent e) {
171                     selectAll(groupTree, false);
172                 }
173             });
174             treePopup.add(deselectItem);
175 
176             groupTree.addMouseListener(new MouseAdapter() {
177                 public void mousePressed(MouseEvent e) {
178                     maybeShowPopup(e);
179                 }
180 
181                 public void mouseReleased(MouseEvent e) {
182                     maybeShowPopup(e);
183                 }
184 
185                 private void maybeShowPopup(MouseEvent e) {
186                     if (e.isPopupTrigger()) {
187                         treePopup.show(e.getComponent(), e.getX(), e.getY());
188                     }
189                 }
190             });
191 
192             // config panel
193             final JPanel configPanel = new JPanel();
194             configPanel.setLayout(new BoxLayout(configPanel, BoxLayout.PAGE_AXIS));
195             configPanel.setPreferredSize(new Dimension(getWidth() / 2, 500));
196             configPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
197 
198             final JComboBox folderComboBox = addComboBox(configPanel, "Test folder type:",
199                     BaseTypeId.CMIS_FOLDER.value(), TestParameters.DEFAULT_FOLDER_TYPE_VALUE);
200             configPanel.add(Box.createRigidArea(new Dimension(1, 10)));
201 
202             final JComboBox documentComboBox = addComboBox(configPanel, "Test document type:",
203                     BaseTypeId.CMIS_DOCUMENT.value(), TestParameters.DEFAULT_DOCUMENT_TYPE_VALUE);
204             configPanel.add(Box.createRigidArea(new Dimension(1, 10)));
205 
206             final JComboBox relationshipComboBox = addComboBox(configPanel, "Test relationship type:",
207                     BaseTypeId.CMIS_RELATIONSHIP.value(), TestParameters.DEFAULT_RELATIONSHIP_TYPE_VALUE);
208             configPanel.add(Box.createRigidArea(new Dimension(1, 10)));
209 
210             configPanel.add(new JLabel("Test folder path:"));
211             final JTextField testParentFolderField = new JTextField(TestParameters.DEFAULT_TEST_FOLDER_PARENT_VALUE);
212             testParentFolderField.setMaximumSize(new Dimension(Short.MAX_VALUE, 10));
213             testParentFolderField.setAlignmentX(Component.LEFT_ALIGNMENT);
214             configPanel.add(testParentFolderField);
215 
216             configPanel.add(Box.createVerticalGlue());
217 
218             add(configPanel);
219 
220             final JPanel mainPanel = new JPanel(new BorderLayout());
221             mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
222             mainPanel.add(new JScrollPane(groupTree), BorderLayout.CENTER);
223             mainPanel.add(configPanel, BorderLayout.LINE_END);
224             add(mainPanel, BorderLayout.CENTER);
225 
226             final JButton runButton = new JButton("Run TCK");
227             runButton.setDefaultCapable(true);
228             runButton.addActionListener(new ActionListener() {
229                 public void actionPerformed(ActionEvent event) {
230                     int answer = JOptionPane
231                             .showConfirmDialog(
232                                     owner,
233                                     "Running the TCK may take a long time and may add, remove and alter data in the repository!\n"
234                                             + "It also puts at a strain on the repository, performing several thousand calls!\n"
235                                             + "\nAre you sure you want to proceed?", "TCK", JOptionPane.YES_NO_OPTION,
236                                     JOptionPane.WARNING_MESSAGE);
237 
238                     if (answer == JOptionPane.YES_OPTION) {
239                         Map<String, String> parameters = runner.getParameters();
240                         parameters.put(TestParameters.DEFAULT_FOLDER_TYPE, (String) folderComboBox.getSelectedItem());
241                         parameters.put(TestParameters.DEFAULT_DOCUMENT_TYPE,
242                                 (String) documentComboBox.getSelectedItem());
243                         if (relationshipComboBox.isEnabled()) {
244                             parameters.put(TestParameters.DEFAULT_RELATIONSHIP_TYPE,
245                                     (String) relationshipComboBox.getSelectedItem());
246                         }
247                         parameters.put(TestParameters.DEFAULT_TEST_FOLDER_PARENT, testParentFolderField.getText());
248 
249                         runner.setParameters(parameters);
250 
251                         dispose();
252                         new TckRunDialog();
253                     }
254                 }
255             });
256 
257             final JPanel runButtonPanel = new JPanel();
258             runButtonPanel.setLayout(new BoxLayout(runButtonPanel, BoxLayout.PAGE_AXIS));
259             runButtonPanel.setBorder(BorderFactory.createEmptyBorder(0, 3, 3, 3));
260             runButton.setMaximumSize(new Dimension(Short.MAX_VALUE, 30));
261             runButtonPanel.add(runButton);
262 
263             add(runButtonPanel, BorderLayout.PAGE_END);
264 
265             getRootPane().setDefaultButton(runButton);
266 
267             ClientHelper.installEscapeBinding(this, getRootPane(), true);
268 
269             setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
270             pack();
271             setLocationRelativeTo(null);
272             setVisible(true);
273         }
274 
275         private void selectAll(final JTree tree, boolean select) {
276             for (CmisTestGroup group : runner.getGroups()) {
277                 group.setEnabled(select);
278                 for (CmisTest test : group.getTests()) {
279                     test.setEnabled(select);
280                 }
281             }
282 
283             DefaultTreeModel model = ((DefaultTreeModel) tree.getModel());
284             model.nodeChanged((TreeNode) model.getRoot());
285         }
286 
287         private JComboBox addComboBox(JPanel panel, String title, String rootTypeId, String defaultTypeId) {
288             final JLabel label = new JLabel(title);
289             label.setAlignmentX(Component.LEFT_ALIGNMENT);
290             panel.add(label);
291 
292             List<ObjectType> types = model.getCreateableTypes(rootTypeId);
293             String[] typeIds = new String[types.size()];
294 
295             int i = 0;
296             for (ObjectType type : types) {
297                 typeIds[i++] = type.getId();
298             }
299 
300             final JComboBox comboBox = new JComboBox(typeIds);
301             comboBox.setSelectedItem(defaultTypeId);
302             comboBox.setAlignmentX(Component.LEFT_ALIGNMENT);
303             comboBox.setMaximumSize(new Dimension(Short.MAX_VALUE, 10));
304             comboBox.setEnabled(typeIds.length > 0);
305             panel.add(comboBox);
306 
307             return comboBox;
308         }
309     }
310 
311     private class TestTreeNode extends DefaultMutableTreeNode {
312         private static final long serialVersionUID = 1L;
313 
314         private final JTree tree;
315         private final CmisTestGroup group;
316         private final CmisTest test;
317 
318         public TestTreeNode(JTree tree, CmisTestGroup group) {
319             this.tree = tree;
320             this.group = group;
321             this.test = null;
322         }
323 
324         public TestTreeNode(JTree tree, CmisTest test) {
325             this.tree = tree;
326             this.test = test;
327             this.group = null;
328         }
329 
330         public CmisTestGroup getGroup() {
331             return group;
332         }
333 
334         public String getName() {
335             if (group != null) {
336                 return group.getName();
337             }
338 
339             return test.getName();
340         }
341 
342         public String getDescription() {
343             if (group != null) {
344                 return group.getDescription();
345             }
346 
347             return test.getDescription();
348         }
349 
350         public boolean isEnabled() {
351             if (group != null) {
352                 return group.isEnabled();
353             }
354 
355             return test.isEnabled();
356         }
357 
358         public void setEnabled(boolean enabled) {
359             DefaultTreeModel model = ((DefaultTreeModel) tree.getModel());
360 
361             if (group != null) {
362                 group.setEnabled(enabled);
363 
364                 for (int i = 0; i < getChildCount(); i++) {
365                     TestTreeNode node = (TestTreeNode) getChildAt(i);
366                     node.setEnabled(enabled);
367                     model.nodeChanged(node);
368                 }
369 
370                 return;
371             }
372 
373             test.setEnabled(enabled);
374 
375             if (enabled) {
376                 TestTreeNode node = (TestTreeNode) getParent();
377                 node.getGroup().setEnabled(true);
378                 model.nodeChanged(node);
379             }
380         }
381     }
382 
383     private class TestTreeNodeRender extends JCheckBox implements TreeCellRenderer {
384         private static final long serialVersionUID = 1L;
385 
386         private final Color textSelectionColor;
387         private final Color textNonSelectionColor;
388         private final Color backgroundSelectionColor;
389         private final Color backgroundNonSelectionColor;
390 
391         public TestTreeNodeRender() {
392             textSelectionColor = UIManager.getDefaults().getColor("Tree.selectionForeground");
393             textNonSelectionColor = UIManager.getDefaults().getColor("Tree.textForeground");
394             backgroundSelectionColor = UIManager.getDefaults().getColor("Tree.selectionBackground");
395             backgroundNonSelectionColor = UIManager.getDefaults().getColor("Tree.textBackground");
396 
397             Insets margins = UIManager.getDefaults().getInsets("Tree.rendererMargins");
398             if (margins != null) {
399                 setBorder(new EmptyBorder(margins.top, margins.left, margins.bottom, margins.right));
400             }
401         }
402 
403         public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded,
404                 boolean leaf, int row, boolean hasFocus) {
405 
406             if (sel) {
407                 setForeground(textSelectionColor);
408                 setBackground(backgroundSelectionColor);
409             } else {
410                 setForeground(textNonSelectionColor);
411                 setBackground(backgroundNonSelectionColor);
412             }
413 
414             if (value instanceof TestTreeNode) {
415                 TestTreeNode node = (TestTreeNode) value;
416                 setText(node.getName());
417                 setSelected(node.isEnabled());
418                 setToolTipText(node.getDescription());
419             } else {
420                 setText(value == null ? "" : value.toString());
421                 setToolTipText(null);
422             }
423 
424             return this;
425         }
426 
427         public void validate() {
428         }
429 
430         public void invalidate() {
431         }
432 
433         public void revalidate() {
434         }
435 
436         public void repaint(long tm, int x, int y, int width, int height) {
437         }
438 
439         public void repaint(Rectangle r) {
440         }
441 
442         public void repaint() {
443         }
444     }
445 
446     private class TestTreeNodeEditor extends AbstractCellEditor implements TreeCellEditor {
447         private static final long serialVersionUID = 1L;
448 
449         private TestTreeNodeRender lastObject;
450 
451         @Override
452         public Object getCellEditorValue() {
453             return lastObject;
454         }
455 
456         @Override
457         public Component getTreeCellEditorComponent(JTree tree, final Object value, boolean isSelected,
458                 boolean expanded, boolean leaf, int row) {
459 
460             lastObject = new TestTreeNodeRender();
461             lastObject.getTreeCellRendererComponent(tree, value, true, expanded, leaf, row, false);
462             lastObject.addItemListener(new ItemListener() {
463                 public void itemStateChanged(ItemEvent itemEvent) {
464                     ((TestTreeNode) value).setEnabled(((JCheckBox) itemEvent.getItem()).isSelected());
465                     fireEditingStopped();
466                 }
467             });
468 
469             return lastObject;
470         }
471     }
472 
473     private class TckRunDialog extends JDialog {
474         private static final long serialVersionUID = 1L;
475 
476         private final TckTask task;
477 
478         public TckRunDialog() {
479             super(owner, "TCK");
480 
481             createGUI();
482 
483             task = new TckTask(this, runner);
484             task.execute();
485         }
486 
487         private void createGUI() {
488             setPreferredSize(new Dimension(500, 200));
489             setMinimumSize(new Dimension(500, 200));
490 
491             setLayout(new BorderLayout());
492 
493             JPanel progressPanel = new JPanel();
494             progressPanel.setLayout(new BoxLayout(progressPanel, BoxLayout.Y_AXIS));
495             progressPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
496 
497             progressPanel.add(Box.createRigidArea(new Dimension(0, 10)));
498 
499             JLabel groupsLabel = new JLabel("Groups:");
500             groupsLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
501             progressPanel.add(groupsLabel);
502 
503             groupsProgressBar = new JProgressBar();
504             groupsProgressBar.setMinimumSize(new Dimension(500, 30));
505             groupsProgressBar.setPreferredSize(new Dimension(500, 30));
506             groupsProgressBar.setMaximumSize(new Dimension(Short.MAX_VALUE, 30));
507             groupsProgressBar.setAlignmentX(Component.LEFT_ALIGNMENT);
508             groupsProgressBar.setAlignmentY(Component.CENTER_ALIGNMENT);
509             progressPanel.add(groupsProgressBar);
510 
511             progressPanel.add(Box.createRigidArea(new Dimension(0, 10)));
512 
513             JLabel testsLabel = new JLabel("Tests:");
514             testsLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
515             progressPanel.add(testsLabel);
516 
517             testsProgressBar = new JProgressBar();
518             testsProgressBar.setMinimumSize(new Dimension(500, 30));
519             testsProgressBar.setPreferredSize(new Dimension(500, 30));
520             testsProgressBar.setMaximumSize(new Dimension(Short.MAX_VALUE, 30));
521             testsProgressBar.setAlignmentX(Component.LEFT_ALIGNMENT);
522             testsProgressBar.setAlignmentY(Component.CENTER_ALIGNMENT);
523             progressPanel.add(testsProgressBar);
524 
525             progressPanel.add(Box.createRigidArea(new Dimension(0, 10)));
526 
527             statusLabel = new JLabel();
528             progressPanel.add(statusLabel);
529 
530             add(progressPanel, BorderLayout.CENTER);
531 
532             JButton cancelButton = new JButton("Cancel");
533             cancelButton.setDefaultCapable(true);
534             cancelButton.addActionListener(new ActionListener() {
535                 public void actionPerformed(ActionEvent event) {
536                     task.cancel(true);
537                 }
538             });
539 
540             final JPanel cancelButtonPanel = new JPanel();
541             cancelButtonPanel.setLayout(new BoxLayout(cancelButtonPanel, BoxLayout.PAGE_AXIS));
542             cancelButtonPanel.setBorder(BorderFactory.createEmptyBorder(0, 3, 3, 3));
543             cancelButton.setMaximumSize(new Dimension(Short.MAX_VALUE, 30));
544             cancelButtonPanel.add(cancelButton);
545 
546             add(cancelButtonPanel, BorderLayout.PAGE_END);
547 
548             getRootPane().setDefaultButton(cancelButton);
549 
550             setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
551             pack();
552             setLocationRelativeTo(null);
553             setVisible(true);
554         }
555     }
556 
557     private static class TckDialogRunner extends AbstractRunner {
558         public TckDialogRunner(ClientModel model, TckDialog tckDialog) {
559             Map<String, String> parameters = new HashMap<String, String>(model.getClientSession()
560                     .getSessionParameters());
561             parameters.put(SessionParameter.REPOSITORY_ID, model.getClientSession().getSession().getRepositoryInfo()
562                     .getId());
563 
564             setParameters(parameters);
565         }
566     }
567 
568     private class DialogProgressMonitor implements CmisTestProgressMonitor {
569 
570         public DialogProgressMonitor(int numberOfGroups) {
571             groupsProgressBar.setStringPainted(true);
572             groupsProgressBar.setMinimum(0);
573             groupsProgressBar.setMaximum(numberOfGroups);
574             groupsProgressBar.setValue(0);
575         }
576 
577         public void startGroup(CmisTestGroup group) {
578             groupsProgressBar.setString(group.getName());
579 
580             testsProgressBar.setStringPainted(true);
581             testsProgressBar.setMinimum(0);
582             testsProgressBar.setMaximum(group.getTests().size());
583             testsProgressBar.setValue(0);
584         }
585 
586         public void endGroup(CmisTestGroup group) {
587             groupsProgressBar.setString("");
588             groupsProgressBar.setValue(groupsProgressBar.getValue() + 1);
589         }
590 
591         public void startTest(CmisTest test) {
592             testsProgressBar.setString(test.getName());
593         }
594 
595         public void endTest(CmisTest test) {
596             testsProgressBar.setString("");
597             testsProgressBar.setValue(testsProgressBar.getValue() + 1);
598 
599             for (CmisTestResult tr : test.getResults()) {
600                 int x = status.get(tr.getStatus());
601                 status.put(tr.getStatus(), x + 1);
602             }
603 
604             StringBuilder sb = new StringBuilder("<html>");
605             int x;
606 
607             x = status.get(CmisTestResultStatus.INFO);
608             if (x > 0) {
609                 sb.append("<font color='#000000'>[Info: " + x + "]</font>  ");
610             }
611 
612             x = status.get(CmisTestResultStatus.SKIPPED);
613             if (x > 0) {
614                 sb.append("<font color='#444444'>[Skipped: " + x + "]</font>  ");
615             }
616 
617             x = status.get(CmisTestResultStatus.OK);
618             if (x > 0) {
619                 sb.append("<font color='#009900'>[Ok: " + x + "]</font>  ");
620             }
621 
622             x = status.get(CmisTestResultStatus.WARNING);
623             if (x > 0) {
624                 sb.append("<font color='#999900'>[Warning: " + x + "]</font>  ");
625             }
626 
627             x = status.get(CmisTestResultStatus.FAILURE);
628             if (x > 0) {
629                 sb.append("<font color='#996000'>[Failure: " + x + "]</font>  ");
630             }
631 
632             x = status.get(CmisTestResultStatus.UNEXPECTED_EXCEPTION);
633             if (x > 0) {
634                 sb.append("<font color='#990000'>[Exception: " + x + "]</font>  ");
635             }
636 
637             sb.append("</html>");
638 
639             statusLabel.setText(sb.toString());
640         }
641 
642         public void message(String msg) {
643         }
644     }
645 
646     class TckTask extends SwingWorker<Void, Void> {
647         private final JDialog dialog;
648         private final TckDialogRunner runner;
649 
650         public TckTask(JDialog dialog, TckDialogRunner runner) {
651             this.dialog = dialog;
652             this.runner = runner;
653         }
654 
655         @Override
656         public Void doInBackground() {
657             try {
658                 runner.run(new DialogProgressMonitor(runner.getGroups().size()));
659             } catch (InterruptedException ie) {
660                 runner.cancel();
661             } catch (Exception e) {
662                 JOptionPane
663                         .showMessageDialog(owner, "Error: " + e.getMessage(), "TCK Error", JOptionPane.ERROR_MESSAGE);
664             }
665 
666             return null;
667         }
668 
669         @Override
670         public void done() {
671             try {
672                 SwingReport report = new SwingReport(null, 700, 500);
673                 report.createReport(runner.getParameters(), runner.getGroups(), (Writer) null);
674             } catch (Exception e) {
675                 JOptionPane.showMessageDialog(owner, "Error: " + e.getMessage(), "Report Error",
676                         JOptionPane.ERROR_MESSAGE);
677             } finally {
678                 dialog.dispose();
679             }
680         }
681     }
682 }