1 /* 2 * $Id$ 3 * 4 * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. 5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6 * 7 * This code is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2 only, as 9 * published by the Free Software Foundation. Oracle designates this 10 * particular file as subject to the "Classpath" exception as provided 11 * by Oracle in the LICENSE file that accompanied this code. 12 * 13 * This code is distributed in the hope that it will be useful, but WITHOUT 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 * version 2 for more details (a copy is included in the LICENSE file that 17 * accompanied this code). 18 * 19 * You should have received a copy of the GNU General Public License version 20 * 2 along with this work; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22 * 23 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 24 * or visit www.oracle.com if you need additional information or have any 25 * questions. 26 */ 27 package com.sun.javatest.exec; 28 29 import java.awt.AWTEvent; 30 import java.awt.BorderLayout; 31 import java.awt.Color; 32 import java.awt.Component; 33 import java.awt.Container; 34 import java.awt.Dimension; 35 import java.awt.Font; 36 import java.awt.GridBagConstraints; 37 import java.awt.GridBagLayout; 38 import java.awt.KeyboardFocusManager; 39 import java.awt.Window; 40 import java.awt.event.ActionEvent; 41 import java.awt.event.ActionListener; 42 import java.awt.event.KeyEvent; 43 import java.io.BufferedInputStream; 44 import java.io.File; 45 import java.io.FileNotFoundException; 46 import java.io.IOException; 47 import java.io.InputStream; 48 import java.io.FileInputStream; 49 import java.net.URL; 50 import java.util.Properties; 51 import java.util.Set; 52 import java.util.TreeSet; 53 import java.util.Vector; 54 import javax.swing.BorderFactory; 55 import javax.swing.ButtonGroup; 56 import javax.swing.Icon; 57 import javax.swing.ImageIcon; 58 import javax.swing.JButton; 59 import javax.swing.JCheckBox; 60 import javax.swing.JComboBox; 61 import javax.swing.JComponent; 62 import javax.swing.JDialog; 63 import javax.swing.JFileChooser; 64 import javax.swing.JInternalFrame; 65 import javax.swing.JLabel; 66 import javax.swing.JPanel; 67 import javax.swing.JRadioButton; 68 import javax.swing.JTextArea; 69 import javax.swing.JTextField; 70 import javax.swing.KeyStroke; 71 import javax.swing.event.AncestorEvent; 72 import javax.swing.event.AncestorListener; 73 import javax.swing.event.ChangeEvent; 74 import javax.swing.event.ChangeListener; 75 import javax.swing.event.DocumentEvent; 76 import javax.swing.event.DocumentListener; 77 78 import com.sun.interview.Interview; 79 import com.sun.javatest.Harness; 80 import com.sun.javatest.InterviewParameters; 81 import com.sun.javatest.ResourceLoader; 82 import com.sun.javatest.TemplateUtilities; 83 //import com.sun.javatest.TemplateUtilities; 84 import com.sun.javatest.TestSuite; 85 import com.sun.javatest.WorkDirectory; 86 import com.sun.javatest.tool.FileChooser; 87 import com.sun.javatest.tool.FileHistory; 88 import com.sun.javatest.tool.TestSuiteChooser; 89 import com.sun.javatest.tool.ToolDialog; 90 import com.sun.javatest.tool.UIFactory; 91 import com.sun.javatest.tool.WorkDirChooser; 92 93 94 class QuickStartWizard extends ToolDialog 95 { 96 QuickStartWizard(JComponent parent, Icon logoIcon, 97 QSW_Listener finisher, UIFactory uif) { 98 super(parent, uif, "qsw"); 99 this.logoIcon = logoIcon; 100 this.qswListener = finisher; 101 } 102 103 104 protected void initGUI() { 105 disableDefaultDisposeHandler(); 106 initDirs(); 107 initPanes(); 108 109 setHelp("qsw.window.csh"); 110 setI18NTitle("qsw.title"); 111 112 body = uif.createPanel("qsw.body", new BorderLayout(), false); 113 body.setBorder(BorderFactory.createLoweredBevelBorder()); 114 115 /* 116 * *-----------------------+ 117 * | | head | 118 * | +---------------| 119 * | | | 120 * | logo | question pane | 121 * | | | 122 * | +---------------| 123 * | | error | 124 * |-------+---------------+ 125 * | buttons | 126 * |-----------------------+ 127 */ 128 129 TestSuite ts; 130 try { 131 //System.err.println("QSG: installDirIsTestSuite=" + installDirIsTestSuite); 132 //System.err.println("QSG: installParentDirIsTestSuite=" + installParentDirIsTestSuite); 133 //System.err.println("QSG: userDirIsTestSuite=" + userDirIsTestSuite); 134 if (installDirIsTestSuite) 135 ts = TestSuite.open(installDir); 136 else if (installParentDirIsTestSuite) 137 ts = TestSuite.open(installParentDir); 138 else if (userDirIsTestSuite) 139 ts = TestSuite.open(userDir); 140 else 141 ts = null; 142 } 143 catch (Throwable e) { 144 ts = null; 145 } 146 147 // logo... 148 JLabel logo; 149 150 URL tsLogoURL = (ts == null ? null : ts.getLogo()); 151 //System.err.println("QSG: tsLogoURL=" + tsLogoURL); 152 if (tsLogoURL == null) { 153 logo = new JLabel(logoIcon); 154 logo.setName("qsw.jtlogo"); 155 logo.setBackground(uif.getI18NColor("qsw.jtlogo.bg")); 156 uif.setAccessibleInfo(logo, "qsw.jtlogo"); 157 } 158 else { 159 logo = new JLabel(new ImageIcon(tsLogoURL)); 160 logo.setName("qsw.tslogo"); 161 logo.setBackground(Color.white); 162 // the following comments are to keep the i18n checker happy 163 // getI18NString("qsw.tslogo.desc") 164 // getI18NString("qsw.tslogo.name") 165 uif.setAccessibleInfo(logo, "qsw.tslogo"); 166 } 167 logo.setOpaque(true); 168 logo.setFocusable(false); // mildly questionable, but it can't take/show focus 169 body.add(logo, BorderLayout.WEST); 170 171 main = uif.createPanel("qsw.main", new BorderLayout(), false); 172 main.setBorder(BorderFactory.createEmptyBorder(20, 20, 0, 11)); 173 head = uif.createOutputField("qsw.head"); 174 head.setBorder(null); 175 head.setFont(head.getFont().deriveFont(Font.BOLD)); 176 main.add(head, BorderLayout.NORTH); 177 178 foot = uif.createOutputField("qsw.foot"); 179 foot.setBorder(null); 180 foot.setFont(foot.getFont().deriveFont(Font.BOLD)); 181 foot.setForeground(uif.getI18NColor("qsw.foot")); 182 main.add(foot, BorderLayout.SOUTH); 183 184 body.add(main, BorderLayout.CENTER); 185 186 setBody(body); 187 188 backBtn = uif.createButton("qsw.back", listener); 189 nextBtn = uif.createButton("qsw.next", listener); 190 doneBtn = uif.createButton("qsw.done", listener); 191 JButton cancelBtn = uif.createCancelButton("qsw.cancel"); 192 cancelBtn.addActionListener(new ActionListener() { 193 public void actionPerformed(ActionEvent e) { 194 closeExecTool(e); 195 } 196 197 }); 198 setPane(taskPane); 199 setButtons(new JButton[] { backBtn, nextBtn, doneBtn, cancelBtn }, null); 200 setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); 201 202 } 203 204 private void closeExecTool(AWTEvent ev) { 205 206 Component src = (Component) ev.getSource(); 207 for (Container p = src.getParent(); p != null; p = p.getParent()) { 208 if (p instanceof JInternalFrame || p instanceof Window && p.getParent() != null) { 209 p.setVisible(false); 210 break; 211 } 212 } 213 qswListener.cancelQSW(); 214 // tool.getDesktop().removeTool(tool1); 215 // tool.dispose(); 216 } 217 218 private void initDirs() { 219 File classDir = Harness.getClassDir(); 220 installDir = (classDir == null ? null : classDir.getParentFile()); 221 installDirIsTestSuite = (installDir == null ? false : TestSuite.isTestSuite(installDir)); 222 installParentDir = (installDir == null ? null : installDir.getParentFile()); 223 installParentDirIsTestSuite = (installParentDir == null ? false : TestSuite.isTestSuite(installParentDir)); 224 225 userDir = new File(System.getProperty("user.dir")); 226 userDirIsTestSuite = (userDir == null ? false : TestSuite.isTestSuite(userDir)); 227 userDirIsWorkDirectory = (userDir == null ? false : WorkDirectory.isWorkDirectory(userDir)); 228 } 229 230 private void initPanes() { 231 taskPane = new TaskPane(); 232 configPane = new ConfigPane(); 233 testSuitePane = new TestSuitePane(); 234 newWorkDirPane = new CreateWorkDirPane(); 235 openWorkDirPane = new OpenWorkDirPane(); 236 endPane = new EndPane(); 237 } 238 239 private void setPane(Pane p) { 240 if (currPane != null) 241 main.remove(currPane); 242 243 p.update(); 244 head.setText(p.getHead()); 245 main.add(p, BorderLayout.CENTER); 246 showError(null); 247 backBtn.setEnabled(history.size() > 0); 248 p.updateNextButton(); 249 doneBtn.setEnabled(p == endPane); 250 currPane = p; 251 252 main.validate(); 253 main.repaint(); 254 } 255 256 private void showError(String key) { 257 if (key == null) { 258 foot.setText(""); 259 foot.setEnabled(false); 260 foot.setVisible(false); 261 } 262 else { 263 foot.setText(uif.getI18NString(key)); 264 foot.setEnabled(true); 265 foot.setVisible(true); 266 nextBtn.setEnabled(false); 267 } 268 } 269 270 private void doBack() { 271 int n = history.size(); 272 if (n > 0) { 273 Pane p = (Pane) (history.remove(n - 1)); 274 setPane(p); 275 } 276 } 277 278 private void doNext() { 279 Pane p = currPane.getNext(); 280 if (p != null) { 281 history.add(currPane); 282 setPane(p); 283 } 284 } 285 286 boolean checkSingleTestManager() { 287 /* 288 if (contextManager != null) { 289 ExecToolManager em = tool.getExecToolManager(); 290 Desktop d = em.getDesktop(); 291 if(!em.checkOpenNewTool(d, contextManager)) { 292 return false; 293 } 294 } 295 */ 296 return true; 297 298 } 299 300 private void doDone() { 301 setVisible(false); 302 if (config == null) 303 throw new IllegalStateException(); 304 305 if (workDir != null) 306 config.setWorkDirectory(workDir); 307 308 qswListener.finishQSW(testSuite, workDir, config, 309 showConfigEditorFlag, runTestsFlag); 310 311 /* 312 tool.setInterviewParameters(config); 313 314 if (showConfigEditorFlag) 315 tool.showConfigEditor(runTestsFlag); 316 else if (runTestsFlag) 317 tool.runTests(); 318 */ 319 } 320 321 322 //private ExecTool tool; 323 324 private Pane currPane; 325 private Pane taskPane; 326 private ConfigPane configPane; 327 private Pane testSuitePane; 328 private Pane newWorkDirPane; 329 private Pane openWorkDirPane; 330 private Pane endPane; 331 332 private int task; 333 private static final int UNSET = 0, NEW = 1, RESUME = 2, BROWSE = 3; 334 // indicates using jtm or jti templates 335 private boolean jtmTemplate = true; 336 337 private Properties configData; 338 private File configFile; 339 private Properties jtmData; 340 private File jtmFile; 341 342 private QSW_Listener qswListener; 343 private Icon logoIcon; 344 private InterviewParameters config; 345 private ContextManager contextManager; 346 private TestSuite testSuite; 347 private WorkDirectory workDir; 348 private boolean showConfigEditorFlag; 349 private boolean runTestsFlag; 350 351 private File installDir; 352 private File installParentDir; 353 private boolean installDirIsTestSuite; 354 private boolean installParentDirIsTestSuite; 355 private File userDir; 356 private boolean userDirIsTestSuite; 357 private boolean userDirIsWorkDirectory; 358 359 private JPanel body; 360 private JPanel main; 361 private JTextField head; 362 private JTextField foot; 363 private JButton backBtn; 364 private JButton nextBtn; 365 private JButton doneBtn; 366 private Listener listener = new Listener(); 367 private KeyStroke enterKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); 368 private Vector history = new Vector(); 369 private boolean allowConfigLoadOutsideDefault; 370 private File defaultConfigSavePath; 371 private boolean allowConfigSaveOutsideDefault; 372 private File defaultConfigLoadPath; 373 374 /** 375 * This is the name of system property to turn QuickStartWizard off. 376 * You should specify "true" value for this property to disable 377 * QuickStartWizard. 378 */ 379 static final String QSW_OFF_PROPERTY = "com.sun.javatest.qswDisabled"; 380 381 static final String QSW_OFF_FILE = "qswDisabled"; 382 383 private static final boolean qswDisabled = initQSWDisabled(); 384 385 static boolean isQswDisabled() { 386 return qswDisabled; 387 } 388 389 /** 390 * @return true, if disable 391 */ 392 private static boolean initQSWDisabled() { 393 if (Boolean.parseBoolean(System.getProperty(QSW_OFF_PROPERTY))) { 394 return true; 395 } 396 try { 397 return ResourceLoader.getResourceFile(QSW_OFF_FILE, null) != null; 398 } catch (Exception ignore) { 399 return false; 400 } 401 } 402 403 private class Listener implements ActionListener 404 { 405 public void actionPerformed(ActionEvent e) { 406 Object src = e.getSource(); 407 if (src == nextBtn) 408 doNext(); 409 else if (src == backBtn) 410 doBack(); 411 else if (src == doneBtn) 412 doDone(); 413 else 414 System.err.println("QSG.Listener " + e); 415 } 416 } 417 418 private class FilePanel extends JPanel { 419 420 FilePanel(String key, final JFileChooser chooser) { 421 uif.initPanel(this, key, new BorderLayout(), false); 422 423 label = uif.createLabel(key, true); 424 425 field = uif.createInputField(key, label); 426 currPathComp = field; 427 428 button = uif.createButton(key + ".browse"); 429 button.addActionListener(new ActionListener() { 430 public void actionPerformed(ActionEvent e) { 431 // seed the path if the user has started to enter 432 // something 433 String path = getPath(); 434 if (chooser instanceof FileChooser && 435 ((FileChooser)chooser).getChosenExtension() != null && 436 ((FileChooser)chooser).getChosenExtension().equals(".jti")) { 437 438 File f = InterviewEditor.loadConfigFile( 439 contextManager, parent, uif, 440 (FileChooser)chooser); 441 path = (f == null ? null : f.getPath()); 442 } 443 else { 444 // set chooser to value in field? 445 if (path != null && path.length() > 0) 446 chooser.setSelectedFile(new File(path)); 447 448 int rc = chooser.showDialog(body, chooser.getApproveButtonText()); 449 if (rc != JFileChooser.APPROVE_OPTION) 450 return; 451 452 path = chooser.getSelectedFile().getPath(); 453 } 454 455 field.setText(path); 456 if (combo != null) 457 combo.setSelectedItem(path); 458 } 459 }); 460 461 add(label, BorderLayout.WEST); 462 add(field, BorderLayout.CENTER); // default, may be changed to combo 463 add(button, BorderLayout.EAST); 464 } 465 466 public void setEnabled(boolean b) { 467 super.setEnabled(b); 468 label.setEnabled(b); 469 currPathComp.setEnabled(b); 470 button.setEnabled(b); 471 } 472 473 void setSuggestions(String[] suggestions) { 474 if (suggestions == null || suggestions.length == 0) 475 setPathComponent(field); 476 else { 477 if (combo == null) { 478 combo = uif.createChoice(getName()/*key*/, true, label); 479 //combo.setEditable(true); 480 combo.setFont(combo.getFont().deriveFont(Font.PLAIN)); 481 if (listener != null) { 482 // would be better to use editor addActionListener 483 Component c = combo.getEditor().getEditorComponent(); 484 if (c instanceof JTextField) 485 ((JTextField) c).getDocument().addDocumentListener(listener); 486 } 487 } 488 setPathComponent(combo); 489 combo.removeAllItems(); 490 for (int i = 0; i < suggestions.length; i++) 491 combo.addItem(suggestions[i]); 492 } 493 } 494 495 /** 496 * @return Null if no file path was provided, or if the given path is 497 * rejected due to validation reasons. 498 */ 499 File getFile() { 500 String path = getPath(); 501 return (path == null || path.length() == 0 ? null : new File(path)); 502 } 503 504 String getPath() { 505 //System.err.println("QSG.FP.getPath currComp=" + currPathComp); 506 //System.err.println("QSG.FP.getPath combo.selectedItem=" + (combo == null ? "null" : String.valueOf(combo.getSelectedItem()))); 507 if (currPathComp == field) 508 return field.getText(); 509 else if (currPathComp == combo) { 510 Component c = combo.getEditor().getEditorComponent(); 511 if (c.isShowing() && c instanceof JTextField) 512 return ((JTextField) c).getText(); 513 else 514 return ((String) (combo.getSelectedItem())); 515 } 516 else 517 throw new IllegalStateException(); 518 } 519 520 void setDocumentListener(DocumentListener l) { 521 field.getDocument().addDocumentListener(l); 522 listener = l; 523 } 524 525 private void setPathComponent(JComponent newPathComp) { 526 //System.err.println("QSG.FP.setPathComponent " + newPathComp); 527 if (newPathComp != currPathComp) { 528 if (currPathComp != null) 529 remove(currPathComp); 530 add(newPathComp, BorderLayout.CENTER); 531 newPathComp.setEnabled(isEnabled()); 532 label.setLabelFor(newPathComp); 533 currPathComp = newPathComp; 534 } 535 } 536 537 private JLabel label; 538 private JTextField field; 539 private JComboBox combo; 540 private JComponent currPathComp; 541 private JButton button; 542 private DocumentListener listener; 543 } 544 545 private abstract class Pane extends JPanel { 546 Pane(String key) { 547 paneKey = key; 548 setLayout(new GridBagLayout()); 549 int dpi = uif.getDotsPerInch(); 550 setPreferredSize(new Dimension(5 * dpi, (int) (2.5 * dpi))); 551 head = uif.getI18NString(paneKey + ".hd"); 552 } 553 554 void stateChanged() { } 555 556 String getHead() { 557 return head; 558 } 559 560 void update() { 561 updateNextButton(); 562 } 563 564 abstract void updateNextButton(); 565 566 Pane getNext() { 567 return null; 568 } 569 570 JCheckBox addCheck(String key) { 571 JCheckBox cb = uif.createCheckBox(paneKey + "." + key); 572 cb.addChangeListener(changeListener); 573 574 GridBagConstraints c = new GridBagConstraints(); 575 c.fill = GridBagConstraints.HORIZONTAL; 576 c.gridwidth = GridBagConstraints.REMAINDER; 577 c.insets.left = 10; 578 c.insets.bottom = 5; 579 c.weightx = 1; 580 add(cb, c); 581 582 return cb; 583 } 584 585 JRadioButton addChoice(String key, ButtonGroup bg) { 586 JRadioButton rb = uif.createRadioButton(paneKey + "." + key, bg); 587 rb.addChangeListener(changeListener); 588 589 GridBagConstraints c = new GridBagConstraints(); 590 c.fill = GridBagConstraints.HORIZONTAL; 591 c.gridwidth = GridBagConstraints.REMAINDER; 592 c.insets.left = 10; 593 c.insets.bottom = 5; 594 c.weightx = 1; 595 add(rb, c); 596 597 return rb; 598 } 599 600 FilePanel addFile(String key, JFileChooser chooser) { 601 return addFile(key, chooser, null); 602 } 603 604 FilePanel addFile(String key, final JFileChooser chooser, final JRadioButton rb) { 605 final FilePanel fp = new FilePanel(paneKey + "." + key, chooser); 606 607 GridBagConstraints c = new GridBagConstraints(); 608 c.fill = GridBagConstraints.HORIZONTAL; 609 c.gridwidth = GridBagConstraints.REMAINDER; 610 c.insets.bottom = 10; 611 c.insets.left = (rb == null ? 0 : 30); 612 c.weightx = 1; 613 add(fp, c); 614 615 if (rb != null) { 616 fp.addAncestorListener(new AncestorListener() { 617 public void ancestorAdded(AncestorEvent e) { 618 fp.setEnabled(rb.isSelected()); 619 } 620 public void ancestorMoved(AncestorEvent e) { } 621 public void ancestorRemoved(AncestorEvent e) { } 622 }); 623 rb.addChangeListener(new ChangeListener() { 624 public void stateChanged(ChangeEvent e) { 625 fp.setEnabled(rb.isSelected()); 626 } 627 }); 628 } 629 630 fp.setDocumentListener(new DocumentListener() { 631 public void changedUpdate(DocumentEvent e) { 632 changeListener.stateChanged(new ChangeEvent(fp)); 633 } 634 public void insertUpdate(DocumentEvent e) { 635 changedUpdate(e); 636 } 637 public void removeUpdate(DocumentEvent e) { 638 changedUpdate(e); 639 } 640 }); 641 642 return fp; 643 } 644 645 JTextArea addText() { 646 return addText(true); 647 } 648 649 JTextArea addText(boolean initContent) { 650 // text area... 651 JTextArea textArea = uif.createTextArea("qsw.text"); 652 textArea.setEditable(false); 653 textArea.setLineWrap(true); 654 textArea.setOpaque(false); 655 textArea.setBackground(UIFactory.Colors.TRANSPARENT.getValue()); 656 textArea.setWrapStyleWord(true); 657 // override JTextArea focus traversal keys, resetting them to 658 // the Component default (i.e. the same as for the parent.) 659 textArea.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null); 660 textArea.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null); 661 if (initContent) 662 textArea.setText(uif.getI18NString(paneKey + ".txt")); 663 /* 664 // set enter to be same as Next 665 { 666 InputMap im = textArea.getInputMap(); 667 im.put(enterKey, "next"); 668 ActionMap am = textArea.getActionMap(); 669 am.put("next", valueAction); 670 } 671 */ 672 GridBagConstraints c = new GridBagConstraints(); 673 c.gridwidth = GridBagConstraints.REMAINDER; 674 c.insets.top = 20; 675 c.insets.right = 10; 676 c.insets.bottom = 10; 677 c.fill = GridBagConstraints.BOTH; 678 add(textArea, c); 679 return textArea; 680 } 681 682 private ChangeListener changeListener = new ChangeListener() { 683 public void stateChanged(ChangeEvent e) { 684 Pane.this.stateChanged(); 685 } 686 }; 687 688 private String paneKey; 689 private String head; 690 }; 691 692 //------------------------------------------------------------------------------ 693 694 private class TaskPane extends Pane { 695 TaskPane() { 696 super("qsw.tsk"); 697 addText(); 698 newRun = addChoice("new", bg); 699 resumeRun = addChoice("resume", bg); 700 browse = addChoice("browse", bg); 701 } 702 703 void stateChanged() { 704 task = (newRun.isSelected() ? NEW 705 : resumeRun.isSelected() ? RESUME 706 : browse.isSelected() ? BROWSE 707 : UNSET); 708 updateNextButton(); 709 } 710 711 void updateNextButton() { 712 nextBtn.setEnabled(task != UNSET); 713 } 714 715 716 Pane getNext() { 717 718 return (task == NEW || task == BROWSE ? (Pane) testSuitePane 719 : task == RESUME ? (Pane) openWorkDirPane 720 : null); 721 } 722 723 724 private ButtonGroup bg = new ButtonGroup(); 725 private JRadioButton newRun; 726 private JRadioButton resumeRun; 727 private JRadioButton browse; 728 }; 729 730 //------------------------------------------------------------------------------ 731 732 private class ConfigPane extends Pane { 733 ConfigPane() { 734 super("qsw.cfg"); 735 addText(); 736 jtiChooser = new FileChooser(true); 737 jtiChooser.addChoosableExtension(".jti", 738 uif.getI18NString("qsw.cfg.jtiFiles")); 739 740 jtmChooser = new FileChooser(true); 741 jtmChooser.setDialogTitle(uif.getI18NString("qsw.cfg.jtmChooser.title")); 742 jtmChooser.addChoosableExtension(".jtm", 743 uif.getI18NString("qsw.cfg.jtmFiles")); 744 745 newConfig = addChoice("new", bg); 746 jtmConfig = addChoice("template", bg); 747 jtmPanel = addFile("jtm.field", jtmChooser, jtmConfig); 748 749 } 750 751 752 void tuneTemplateFilter() { 753 if (contextManager != null && 754 contextManager.getFeatureManager() != null && 755 contextManager.getFeatureManager().isEnabled(FeatureManager.WD_WITHOUT_TEMPLATE) ) { 756 jtmChooser.addChoosableExtension(".jti", 757 uif.getI18NString("qsw.cfg.jtiFiles")); 758 } 759 } 760 761 762 private void tunePane() { 763 764 if (contextManager != null) { 765 766 jtmChooser.setCurrentDirectory(contextManager.getDefaultTemplateLoadPath()); 767 768 if (contextManager.getFeatureManager() != null) { 769 FeatureManager fm = contextManager.getFeatureManager(); 770 jtmConfig.setEnabled(fm.isEnabled(FeatureManager.TEMPLATE_USAGE)); 771 newConfig.setEnabled(fm.isEnabled(FeatureManager.WD_WITHOUT_TEMPLATE)); 772 } 773 } 774 } 775 776 777 void stateChanged() { 778 showError(null); 779 updateNextButton(); 780 } 781 782 783 void updateNextButton() { 784 785 tunePane(); 786 787 if (newConfig.isSelected()) { 788 nextBtn.setEnabled(true); 789 } else if (jtmConfig.isSelected()) { 790 File f = jtmPanel.getFile(); 791 nextBtn.setEnabled(f != null && f.exists() && f.isFile()); 792 } 793 else 794 nextBtn.setEnabled(false); 795 } 796 797 Pane getNext() { 798 if (bg.getSelection() == null) 799 return null; 800 801 if (newConfig.isSelected()) { 802 configData = null; 803 configFile = null; 804 jtmData = null; 805 jtmFile = null; 806 } else if (jtmConfig.isSelected()) { 807 jtmData = new Properties(); 808 jtmFile = chkConfigFile(jtmPanel, jtmData); 809 if (jtmFile == null) { 810 return null; 811 } 812 813 if (jtmData != null) { 814 String jtmDataInterview = (String) (jtmData.get("INTERVIEW")); 815 816 if (jtmDataInterview != null 817 && !config.getClass().getName().equals(jtmDataInterview)) { 818 uif.showError("qsw.ts.templateMismatch"); 819 return null; 820 } 821 822 jtmTemplate = Boolean.parseBoolean((String)jtmData.get("IS_TEMPLATE")); 823 824 if (config != null) { 825 try { 826 if (jtmTemplate) { 827 testSuite.loadInterviewFromTemplate(jtmFile, config); 828 config.setTemplatePath(jtmFile.getAbsolutePath()); 829 } else { 830 config.load(jtmFile); 831 } 832 } catch (TestSuite.Fault ex) { 833 // todo 834 ex.printStackTrace(); 835 } catch (IOException ex) { 836 // todo 837 ex.printStackTrace(); 838 } catch (Interview.Fault ex) { 839 uif.showError("qsw.ts.cantLoadConfig", ex.getMessage()); 840 return null; 841 } 842 } 843 } 844 845 return (task == NEW ? (Pane) newWorkDirPane : (Pane) endPane); 846 } 847 848 849 850 if (configData != null) { 851 String configDataInterview = (String) (configData.get("INTERVIEW")); 852 853 if (configDataInterview != null 854 && !config.getClass().getName().equals(configDataInterview)) { 855 uif.showError("qsw.ts.configMismatch"); 856 return null; 857 } 858 859 try { 860 config.load(configData, configFile); 861 } 862 catch (InterviewParameters.Fault e) { 863 uif.showError("qsw.ts.cantLoadConfig", e.getMessage()); 864 return null; 865 } 866 } 867 868 return (config == null ? null : task == NEW ? (Pane) newWorkDirPane : (Pane) endPane); 869 870 } 871 872 873 private File chkConfigFile(FilePanel panel, Properties data ) { 874 String path = panel.getPath(); 875 File file = null; 876 if (path.length() == 0) { 877 showError("qsw.cfg.noFile"); 878 return null; 879 } 880 881 File f = new File(path); 882 if (!f.exists()) { 883 showError("qsw.cfg.cantFindFile"); 884 return null; 885 } 886 887 if (!f.isFile()) { 888 showError("qsw.cfg.badFile"); 889 return null; 890 } 891 892 try { 893 InputStream in = new BufferedInputStream(new FileInputStream(f)); 894 895 try { 896 data.clear(); 897 data.load(in); 898 file = f; 899 } 900 catch (RuntimeException e) { 901 // can get IllegalArgumentException if the file is corrupt 902 uif.showError("qsw.cfg.cantReadFile", e); 903 return null; 904 } 905 finally { 906 in.close(); 907 } 908 } 909 catch (IOException e) { 910 uif.showError("qsw.cfg.cantReadFile", e); 911 return null; 912 } 913 914 return file; 915 } 916 917 private ButtonGroup bg = new ButtonGroup(); 918 private JRadioButton newConfig; 919 private JRadioButton fileConfig; 920 private JRadioButton jtmConfig; 921 private FilePanel filePanel; 922 private FilePanel jtmPanel; 923 private FileChooser jtiChooser; 924 private FileChooser jtmChooser; 925 926 private long configLastModified; 927 928 }; 929 930 //------------------------------------------------------------------------------ 931 932 private class TestSuitePane extends Pane { 933 TestSuitePane() { 934 super("qsw.ts"); 935 addText(); 936 chooser = new TestSuiteChooser(); 937 testSuitePanel = addFile("file", chooser); 938 } 939 940 void stateChanged() { 941 showError(null); 942 updateNextButton(); 943 } 944 945 void update() { 946 super.update(); 947 948 // update file with suggestions based on - 949 // - config template 950 // - installation directory and its parent 951 // - current directory 952 953 Set s = new TreeSet(); 954 if (configData != null) { 955 String configTestSuite = (String) (configData.get("TESTSUITE")); 956 if (configTestSuite != null) 957 s.add(configTestSuite); 958 } 959 960 if (userDirIsTestSuite) 961 s.add(userDir.getPath()); 962 963 if (installDirIsTestSuite) 964 s.add(installDir.getPath()); 965 966 if (installParentDirIsTestSuite) 967 s.add(installParentDir.getPath()); 968 969 if (s.size() > 0) 970 testSuitePanel.setSuggestions((String[]) (s.toArray(new String[s.size()]))); 971 } 972 973 void updateNextButton() { 974 File file = testSuitePanel.getFile(); 975 TestSuite chooserTestSuite = chooser.getSelectedTestSuite(); 976 977 if (file == null) { 978 nextBtn.setEnabled(false); 979 } 980 else if (chooserTestSuite != null && chooserTestSuite.getRoot().equals(file)) { 981 nextBtn.setEnabled(true); 982 } 983 else { 984 nextBtn.setEnabled(TestSuite.isTestSuite(file)); 985 } 986 } 987 988 Pane getNext() { 989 // update test suite and check validity? 990 // if ts == chooser.getSelectedFile, use chooser.getSelectedTestSuite 991 File file = testSuitePanel.getFile(); 992 if (file == null) { 993 showError("qsw.ts.noFile"); 994 return null; 995 } 996 else if (testSuite == null || !testSuite.getRoot().equals(file) || config == null) { 997 try { 998 TestSuite chooserTestSuite = chooser.getSelectedTestSuite(); 999 if (chooserTestSuite != null 1000 && chooserTestSuite.getRoot().equals(file)) 1001 testSuite = chooserTestSuite; 1002 else 1003 testSuite = TestSuite.open(file); 1004 } 1005 catch (FileNotFoundException e) { 1006 showError("qsw.ts.cantFindFile"); 1007 return null; 1008 } 1009 catch (TestSuite.Fault e) { 1010 uif.showError("qsw.ts.cantOpen", 1011 new Object[] { file, e.getMessage() }); 1012 return null; 1013 } 1014 1015 // now that test suite is set, try to update config too 1016 try { 1017 if (config != null) { 1018 config.dispose(); 1019 } 1020 config = testSuite.createInterview(); 1021 } 1022 catch (TestSuite.Fault e) { 1023 uif.showError("qsw.ts.cantCreateInterview", e.getMessage()); 1024 return null; 1025 } 1026 catch (Throwable t) { 1027 uif.showError("qsw.ts.cantCreateInterview", t.toString()); 1028 return null; 1029 } 1030 1031 } 1032 1033 if (testSuite != null) { 1034 contextManager = ExecTool.createContextManager(testSuite); 1035 } 1036 configPane.tuneTemplateFilter(); 1037 1038 if (!checkSingleTestManager()) { 1039 return null; 1040 } 1041 1042 1043 return (task == NEW || task == BROWSE ? (Pane) configPane 1044 : task == RESUME ? (Pane) openWorkDirPane 1045 : null); 1046 1047 // return (config == null ? null : task == NEW ? (Pane) newWorkDirPane : (Pane) endPane); 1048 } 1049 1050 private FilePanel testSuitePanel; 1051 private TestSuiteChooser chooser; 1052 }; 1053 1054 //------------------------------------------------------------------------------ 1055 1056 private abstract class WorkDirPane extends Pane { 1057 WorkDirPane(String key) { 1058 super(key); 1059 textArea = addText(); 1060 chooser = new WorkDirChooser(true); 1061 workDirPanel = addFile("file", chooser); 1062 } 1063 1064 protected final JTextArea textArea; 1065 protected final FilePanel workDirPanel; 1066 protected WorkDirChooser chooser; 1067 }; 1068 1069 private class CreateWorkDirPane extends WorkDirPane { 1070 CreateWorkDirPane() { 1071 super("qsw.nwd"); 1072 chooser.setMode(WorkDirChooser.NEW); 1073 } 1074 1075 void stateChanged() { 1076 updateNextButton(); 1077 } 1078 1079 public void update() { 1080 chooser.setTestSuite(testSuite); 1081 } 1082 1083 void updateNextButton() { 1084 String path = workDirPanel.getPath(); 1085 nextBtn.setEnabled(path != null && path.length() > 0); 1086 } 1087 1088 Pane getNext() { 1089 File file = workDirPanel.getFile(); 1090 1091 if (file == null) { 1092 showError("qsw.nwd.noFile"); 1093 return null; 1094 } 1095 else if (workDir == null || !workDir.getRoot().equals(file)) { 1096 try { 1097 WorkDirectory chooserWorkDir = chooser.getSelectedWorkDirectory(); 1098 if (chooserWorkDir != null && canonicalEquals(chooserWorkDir.getRoot(), file)) { 1099 // workdir was created inside the chooser 1100 workDir = chooserWorkDir; 1101 } 1102 else 1103 workDir = WorkDirectory.create(file, testSuite); 1104 1105 if (jtmFile != null && workDir != null && jtmTemplate) { 1106 TemplateUtilities.setTemplateFile(workDir, jtmFile, true); 1107 //tool.setWorkDir(workDir, true); 1108 //tool.getConfigHandler().loadConfigNoUI(jtmFile); 1109 } 1110 1111 } 1112 catch (WorkDirectory.Fault e) { 1113 uif.showError("qsw.nwd.cantCreate", 1114 new Object[] { file, e.getMessage() }); 1115 return null; 1116 } catch (IOException ex) { 1117 ex.printStackTrace(); 1118 } 1119 } 1120 1121 return endPane; 1122 } 1123 }; 1124 1125 private static boolean canonicalEquals(File f1, File f2) { 1126 try { 1127 File c1 = f1.getCanonicalFile(); 1128 File c2 = f2.getCanonicalFile(); 1129 return (c1.equals(c2)); 1130 } 1131 catch (IOException e) { 1132 return false; 1133 } 1134 } 1135 1136 private class OpenWorkDirPane extends WorkDirPane { 1137 OpenWorkDirPane() { 1138 super("qsw.owd"); 1139 chooser.setMode(WorkDirChooser.OPEN_FOR_ANY_TESTSUITE); 1140 1141 if (userDirIsWorkDirectory) 1142 workDirPanel.setSuggestions(new String[] { userDir.getPath() }); 1143 } 1144 1145 void stateChanged() { 1146 updateNextButton(); 1147 } 1148 1149 void updateNextButton() { 1150 File file = workDirPanel.getFile(); 1151 WorkDirectory chooserWorkDir = chooser.getSelectedWorkDirectory(); 1152 1153 if (file == null) 1154 nextBtn.setEnabled(false); 1155 else if (chooserWorkDir != null && chooserWorkDir.getRoot().equals(file)) 1156 nextBtn.setEnabled(true); 1157 else 1158 nextBtn.setEnabled(WorkDirectory.isWorkDirectory(file)); 1159 } 1160 1161 Pane getNext() { 1162 File file = workDirPanel.getFile(); 1163 1164 if (file == null) { 1165 showError("qsw.owd.noFile"); 1166 return null; 1167 } 1168 else if (workDir == null || !workDir.getRoot().equals(file)) { 1169 try { 1170 WorkDirectory chooserWorkDir = chooser.getSelectedWorkDirectory(); 1171 if (chooserWorkDir != null 1172 && chooserWorkDir.getRoot().equals(file)) 1173 workDir = chooserWorkDir; 1174 else 1175 workDir = WorkDirectory.open(file); 1176 testSuite = workDir.getTestSuite(); 1177 } 1178 catch (FileNotFoundException e) { 1179 showError("qsw.owd.cantFindFile"); 1180 return null; 1181 } 1182 catch (WorkDirectory.Fault e) { 1183 uif.showError("qsw.owd.cantOpen", 1184 new Object[] { file, e.getMessage() }); 1185 return null; 1186 } 1187 1188 try { 1189 if (config != null) { 1190 config.dispose(); 1191 } 1192 config = testSuite.createInterview(); 1193 // should get latest config for workDir 1194 } 1195 catch (TestSuite.Fault e) { 1196 uif.showError("qsw.owd.createCreateInterview", e.getMessage()); 1197 return null; 1198 } 1199 1200 FileHistory h = FileHistory.getFileHistory(workDir, "configHistory.jtl"); 1201 File latestConfigFile = h.getLatestEntry(); 1202 if (latestConfigFile != null) { 1203 try { 1204 config.load(latestConfigFile); 1205 } 1206 catch (IOException e) { 1207 uif.showError("qsw.owd.cantLoadDefaultConfig", 1208 new Object[] { latestConfigFile, e }); 1209 return null; 1210 } 1211 catch (InterviewParameters.Fault e) { 1212 uif.showError("qsw.owd.cantLoadDefaultConfig", 1213 new Object[] { latestConfigFile, e.getMessage() }); 1214 return null; 1215 } 1216 } 1217 if (testSuite != null) { 1218 contextManager = ExecTool.createContextManager(testSuite); 1219 1220 if (!checkSingleTestManager()) { 1221 return null; 1222 } 1223 } 1224 1225 } 1226 1227 return endPane; 1228 } 1229 }; 1230 1231 //------------------------------------------------------------------------------ 1232 1233 private class EndPane extends Pane { 1234 EndPane() { 1235 super("qsw.end"); 1236 configTextArea = addText(false); 1237 configCheck = addCheck("cfg"); 1238 runTestsTextArea = addText(false); 1239 runTestsCheck = addCheck("run"); 1240 } 1241 1242 void update() { 1243 super.update(); 1244 1245 // update text according to whether config is complete or not 1246 // (and so whether config editor required) 1247 // set configCheck if config incomplete 1248 Integer haveConfig = new Integer(configData == null ? 0 : 1); 1249 1250 StringBuffer sb = new StringBuffer(); 1251 if (config.isFinishable()) { 1252 // "Your configuration is complete, but you can change it by using 1253 // the Configuration Editor." 1254 sb.append(uif.getI18NString("qsw.end.cfgComplete")); 1255 configCheck.setSelected(task == BROWSE ? false : true); 1256 } 1257 else { 1258 if (configData != null) { 1259 // "Your configuration is incomplete." 1260 sb.append(uif.getI18NString("qsw.end.cfgIncomplete")); 1261 sb.append(" "); 1262 } 1263 // "Before you can run tests, you must complete (a|your) configuration 1264 // by using the Configuration Editor." 1265 sb.append(uif.getI18NString("qsw.end.needEditor", haveConfig)); 1266 configCheck.setSelected(task == BROWSE ? false : true); 1267 } 1268 sb.append(" "); 1269 // "You can open the Configuration Editor automatically by 1270 // checking the box below. You can also open the Configuration Editor 1271 // at any time from the Configure menu." 1272 sb.append(uif.getI18NString("qsw.end.editor")); 1273 configTextArea.setText(sb.toString()); 1274 1275 if (task == BROWSE) { 1276 runTestsTextArea.setVisible(false); 1277 runTestsCheck.setVisible(false); 1278 } 1279 else { 1280 runTestsTextArea.setVisible(true); 1281 runTestsCheck.setVisible(true); 1282 // "Once (the|your) configuration is complete, you can run tests automatically 1283 // by checking the box below. You can also run tests at any time from the 1284 // Run Tests menu." 1285 runTestsTextArea.setText(uif.getI18NString("qsw.end.runTests", haveConfig)); 1286 } 1287 1288 stateChanged(); 1289 } 1290 1291 void updateNextButton() { 1292 nextBtn.setEnabled(false); 1293 } 1294 1295 void stateChanged() { 1296 if (runTestsCheck.isSelected() 1297 && (config == null || !config.isFinishable())) 1298 configCheck.setSelected(true); 1299 showConfigEditorFlag = configCheck.isSelected(); 1300 runTestsFlag = runTestsCheck.isSelected(); 1301 } 1302 1303 private JTextArea configTextArea; 1304 private JCheckBox configCheck; 1305 private JTextArea runTestsTextArea; 1306 private JCheckBox runTestsCheck; 1307 }; 1308 1309 protected void windowClosingAction(AWTEvent e) { 1310 setVisible(false); 1311 closeExecTool(e); 1312 } 1313 1314 } 1315