1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 2001, 2011, 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 
  28 package com.sun.javatest.exec;
  29 
  30 import com.sun.interview.Interview.Fault;
  31 import com.sun.javatest.Harness;
  32 import com.sun.javatest.InterviewParameters;
  33 import com.sun.javatest.TestResultTable;
  34 import com.sun.javatest.TestSuite;
  35 import com.sun.javatest.WorkDirectory;
  36 import com.sun.javatest.tool.Preferences;
  37 import com.sun.javatest.tool.Tool;
  38 import com.sun.javatest.tool.ToolManager;
  39 import com.sun.javatest.tool.UIFactory;
  40 import java.awt.BorderLayout;
  41 import java.awt.print.PageFormat;
  42 import java.awt.print.PrinterException;
  43 import java.awt.print.PrinterJob;
  44 import java.awt.print.Printable;
  45 import java.io.File;
  46 import java.util.ArrayList;
  47 import java.util.HashMap;
  48 import java.util.List;
  49 import java.util.Map;
  50 import java.util.ResourceBundle;
  51 import javax.swing.Action;
  52 import javax.swing.JComponent;
  53 import javax.swing.JLabel;
  54 import javax.swing.JMenu;
  55 import javax.swing.JMenuBar;
  56 import javax.swing.JPanel;
  57 import javax.swing.JToolBar;
  58 
  59 
  60 public class ExecTool extends Tool implements ExecModel,
  61         BasicSession.OrderedObserver {
  62 
  63     SessionExt session;
  64     ContextManager context;
  65     final ExecToolManager etm;
  66     final TestSuite testSuite;
  67     final ET_TestTreeControl testTreePanel;
  68     final ET_SessionControl sessionControl;
  69     final ET_RunTestControl runTestsHandler;
  70     final ET_ReportControl reportHandler;
  71     final ET_FilterHandler filterHandler;
  72     final List<ET_Control> controls = new ArrayList<ET_Control>();
  73 
  74     JMenuBar menuBar = null;
  75     private boolean shouldPauseTree;
  76     private PageFormat pageFormat;
  77 
  78     public ExecTool(ExecToolManager mgr, TestSuite ts) throws Session.Fault {
  79         super(mgr, "exec", "browse.window.csh");
  80         this.testSuite = ts;
  81         String testSuiteName = testSuite.getName();
  82         if (testSuiteName != null)
  83             setShortTitle(testSuiteName);
  84         this.etm = mgr;
  85         context = createContextManager();
  86         ET_ControlFactory controlFactory = context.getExecToolControlFactory(this, uif);
  87         ET_PrivateControlFactory prviateFactory = new ET_PrivateControlFactory(this, uif, this);
  88 
  89 
  90         sessionControl = controlFactory.createSessionControl();
  91         Session s = sessionControl.getSession();
  92         if (s instanceof SessionExt) {
  93             session = (SessionExt)s;
  94         } else {
  95             throw new Error(uif.getI18NString("bcc.notSessionExtInstance.err", s.getClass()));
  96         }
  97         context.setCurrentConfig(session);
  98         controls.add(sessionControl);
  99 
 100 
 101         runTestsHandler =  prviateFactory.createRunTestControl();
 102         runTestsHandler.setConfig(session);
 103         controls.add(runTestsHandler);
 104 
 105         reportHandler = controlFactory.createReportControl();
 106         controls.add(reportHandler);
 107 
 108         ET_FilterControl fControl = controlFactory.createFilterControl();
 109         if (fControl instanceof ET_FilterHandler){
 110             filterHandler = (ET_FilterHandler)fControl;
 111         } else {
 112             throw new Error(uif.getI18NString("et.badFilterControl.err"));
 113         }
 114         controls.add(filterHandler);
 115 
 116         testTreePanel = prviateFactory.createTestTreeControl();
 117         testTreePanel.setFilterSelectionHandler(filterHandler.getFilterSelectionHandler());
 118         testTreePanel.setParameters(session.getParameters());
 119         runTestsHandler.setTreePanelModel(testTreePanel.getTreePanelModel());
 120         controls.add(testTreePanel);
 121 
 122         ET_ViewControl viewControl = controlFactory.createViewControl();
 123         viewControl.setConfig(session);
 124         controls.add(viewControl);
 125 
 126         ET_HelpControl helpControl = controlFactory.createHelpControl();
 127         controls.add(helpControl);
 128 
 129         List<ET_Control> customControls = controlFactory.createCustomControls();
 130         if (customControls != null) {
 131             controls.addAll(customControls);
 132         }
 133 
 134         Harness harness = runTestsHandler.getHarness();
 135         for (ET_Control c:controls) {
 136             if (c instanceof Session.Observer) {
 137                 session.addObserver((Session.Observer)c);
 138             }
 139             if (c instanceof ET_RunTestControl.Observer) {
 140                 runTestsHandler.addObserver((ET_RunTestControl.Observer)c);
 141             }
 142             if (c instanceof HarnessAware) {
 143                 ((HarnessAware)c).setHarness(harness);
 144             }
 145         }
 146 
 147         session.addObserver(context);
 148         session.addObserver(this);
 149 
 150 
 151 //        initGUI();
 152     }
 153 
 154     ContextManager createContextManager() {
 155         try {
 156            ContextManager cm = createContextManager(testSuite);
 157            if (cm != null) {
 158                cm.setTestSuite(testSuite);
 159                if (session != null) {
 160                    cm.setCurrentConfig(session);
 161                }
 162                cm.setTool(this);
 163            }
 164            return cm;
 165         } catch (Exception e) {
 166             e.printStackTrace();        // XXX rm
 167             // should print log entry
 168         }
 169         return null;
 170     }
 171     public static ContextManager createContextManager(TestSuite ts) {
 172         ContextManager cm = null;
 173         String cls = null;
 174         if (ts != null)
 175             cls = ts.getTestSuiteInfo(TestSuite.TM_CONTEXT_NAME);
 176         try {
 177             if (cls == null) {
 178                 // use default implementation
 179                 cm = (ContextManager) ((Class.forName(
 180                         "com.sun.javatest.exec.ContextManager")).newInstance());
 181             } else {
 182                 cm = (ContextManager) ((Class.forName(cls, true,
 183                         ts.getClassLoader())).newInstance());
 184             }
 185             cm.setTestSuite(ts);
 186         } catch (Exception e) {
 187             e.printStackTrace();
 188         }
 189         return cm;
 190     }
 191 
 192     public UIFactory getUIF() {
 193         return uif;
 194     }
 195 
 196 
 197     @Override
 198     public JMenuBar getMenuBar() {
 199         if (!this.initialized) {
 200             return null;
 201         }
 202         if (menuBar != null) {
 203             return menuBar;
 204         }
 205 
 206         menuBar = new JMenuBar();
 207         for (ET_Control c:controls) {
 208             JMenu m = c.getMenu();
 209             if (m != null) {
 210                 menuBar.add(m);
 211             }
 212         }
 213         return menuBar;
 214     }
 215 
 216     protected JToolBar getToolBar() {
 217         ArrayList<Action> v = new ArrayList<Action>();
 218         for (ET_Control c: controls) {
 219             List<Action> acts = c.getToolBarActionList();
 220             if (acts != null) {
 221                 v.addAll(acts);
 222                 v.add(null);
 223             }
 224         }
 225         Action[] toolBarActions = v.toArray(new Action[v.size()]);
 226 
 227         Preferences p = Preferences.access();
 228 
 229         JToolBar toolBar = uif.createToolBar("exec.toolbar");
 230         toolBar.setFloatable(false);
 231         boolean tbVisible = p.getPreference(TOOLBAR_PREF, "true").equals("true");
 232         toolBar.setVisible(tbVisible);
 233         toolBar.getMargin().left = 10;
 234         toolBar.getMargin().right = 10;
 235 
 236         JLabel lab = uif.createLabel("exec.filter", false);
 237         JComponent selector = filterHandler.getFilterSelectionHandler().getFilterSelector();
 238         //lab.setLabelFor(selector);
 239         lab.setMaximumSize(lab.getPreferredSize());
 240 
 241         toolBar.add(lab);
 242         toolBar.addSeparator();
 243         toolBar.add(selector);
 244         toolBar.addSeparator();
 245 
 246         // now add all the other buttons
 247         uif.addToolBarActions(toolBar, toolBarActions);
 248         return toolBar;
 249     }
 250 
 251     boolean initialized = false;
 252     @Override
 253     public void setVisible(boolean f) {
 254         initGUI(); // does real work just once
 255         super.setVisible(f);
 256     }
 257     protected void initGUI() {
 258         if (initialized) {
 259             return;
 260         }
 261         initialized = true;
 262 
 263         if (context != null &&
 264             "com.sun.javatest.exec.ContextManager".equals(context.getClass().getCanonicalName())) {
 265             context = null;
 266         }
 267         setLayout(new BorderLayout());
 268         if (shouldPauseTree)
 269             testTreePanel.getTreePanelModel().pauseWork();
 270 
 271         ToolBarPanel toolBarPanel = new ToolBarPanel();
 272         toolBarPanel.add(getToolBar());
 273 
 274 
 275         //add(toolBar, BorderLayout.NORTH);
 276         add(toolBarPanel, BorderLayout.NORTH);
 277 
 278 
 279         add(testTreePanel.getViewComponent(), BorderLayout.CENTER);
 280 
 281         // this panel contains two full-width panels
 282         JPanel statusStrips = uif.createPanel("exec.strips", false);
 283         statusStrips.setLayout(new BorderLayout());
 284         statusStrips.add(sessionControl.getViewComponent(), BorderLayout.NORTH);
 285         statusStrips.add(runTestsHandler.getViewComponent(), BorderLayout.SOUTH);
 286         add(statusStrips, BorderLayout.SOUTH);
 287 
 288         testTreePanel.initialize();
 289 
 290 
 291         //asavdd(sessionControl.getStateViewPanel(), BorderLayout.SOUTH);
 292         //filterHandler.updateParameters();
 293         updateGUI();
 294 
 295     }
 296 
 297     @Override
 298     protected void save(Map<String, String> m) {
 299         for (ET_Control c:controls) {
 300             c.save(m);
 301         }
 302     }
 303 
 304     @Override
 305     protected void restore(Map<String, String> m) {
 306         for (ET_Control c:controls) {
 307             c.restore(m);
 308         }
 309     }
 310 
 311     @Override
 312     public void dispose() {
 313         // standard cleanup (remove refs to child components)
 314         super.dispose();
 315         if (context != null)
 316             context.dispose();
 317 
 318         for (ET_Control c:controls) {
 319             c.dispose();
 320         }
 321 
 322         // no need to track changes in preferences any more
 323         //Preferences p = Preferences.access();
 324         //p.removeObserver(TOOLBAR_PREF, prefsObserver);
 325         //p.save();
 326 
 327     }
 328 
 329     public TestSuite getTestSuite() {
 330         return testSuite;
 331     }
 332 
 333     /**
 334      * @return Array of 1 element - the current testSuite
 335      */
 336     @Override
 337     public TestSuite[] getLoadedTestSuites() {
 338         return (testSuite == null ? null : new TestSuite[]{testSuite});
 339     }
 340 
 341     public WorkDirectory getWorkDirectory() {
 342         return session.getWorkDirectory();
 343     }
 344 
 345     public InterviewParameters getInterviewParameters() {
 346         return session.getInterviewParameters();
 347     }
 348 
 349     public FilterConfig getFilterConfig() {
 350          return filterHandler.getFilterConfig();
 351     }
 352 
 353     public ContextManager getContextManager() {
 354         if (context == null) {
 355             try {
 356                 context = createContextManager();
 357                 //context = (ContextManager) ((Class.forName(
 358                 //        "com.sun.javatest.exec.ContextManager")).newInstance());
 359             } catch (Exception e) {
 360                 e.printStackTrace();
 361                 return null;
 362             }
 363         }
 364         return context;
 365     }
 366 
 367     public TestResultTable getActiveTestResultTable() {
 368         WorkDirectory workDir = getWorkDirectory();
 369         if (workDir != null)
 370             return workDir.getTestResultTable();
 371         else if (testTreePanel != null)
 372             return testTreePanel.getTestResultTable();
 373         else
 374             return null;
 375 
 376     }
 377 
 378 
 379     /**
 380      * Returns action creating work directory.
 381      * This ugly method violates the beautiful picture, but present here to
 382      * preserve functionality of creating the WD from the File menu.
 383      * Hopefully some day it will be eliminated.
 384      *
 385      * @return real action or null
 386      */
 387     Action getCreateWDAction() {
 388         if (sessionControl instanceof BasicSessionControl) {
 389             return ((BasicSessionControl)sessionControl).newWorkDirAction;
 390         }
 391         return null; // no idea how to create WD
 392     }
 393 
 394     /**
 395      * Returns action opening work directory for the TestSuite.
 396      * This ugly method violates the beautiful picture, but present here to
 397      * preserve functionality of creating the WD from the File menu.
 398      * Hopefully some day it will be eliminated.
 399      *
 400      * @return real action or null
 401      */
 402     Action getOpenWDAction() {
 403         if (sessionControl instanceof BasicSessionControl) {
 404             return ((BasicSessionControl)sessionControl).openWorkDirAction;
 405         }
 406         return null; // no idea how to create WD
 407     }
 408 
 409     void updateGUI() {
 410         if (!initialized) {
 411             return;
 412         }
 413         for (ET_Control c: controls) {
 414             c.updateGUI();
 415         }
 416         updateTitle();
 417     }
 418 
 419     /**
 420      * Invoked when manager orders to use new wd.
 421      * @param wd
 422      * @throws com.sun.javatest.exec.Session.Fault
 423      * @see ExecTool#update(WorkDirectory, boolean)
 424      */
 425     public void update(WorkDirectory wd) throws Session.Fault {
 426         // reloading the config is traditional
 427         session.update(new BasicSession.U_NewWD(wd), true);
 428     }
 429 
 430     /**
 431      * Invoked when manager orders to use new wd.
 432      * @param wd Work dir to update.
 433      * @param updateConfig - hint whether to reload the configuration from disk
 434      * @throws com.sun.javatest.exec.Session.Fault
 435      */
 436     public void update(WorkDirectory wd, boolean updateConfig) throws Session.Fault {
 437         session.update(new BasicSession.U_NewWD(wd), updateConfig);
 438     }
 439 
 440     /**
 441      * Invoked when manager orders to use new ip
 442      * @param ip
 443      * @throws com.sun.javatest.exec.Session.Fault
 444      */
 445     public void update(InterviewParameters ip) throws Session.Fault {
 446         if (session.getInterviewParameters().getFile() != null) {
 447             // someone already initialized IP
 448             return;
 449         }
 450         session.update(new BasicSession.U_NewConfig(ip));
 451     }
 452 
 453     /**
 454      * Session.Observer interface method
 455      * @param e
 456      */
 457     public void updated(Session.Event e) {
 458         updateGUI();
 459     }
 460 
 461     /**
 462      * BasicSession.OrderedObserver interface method.
 463      */
 464     public int order() {
 465         return Integer.MAX_VALUE;
 466     }
 467 
 468     public void showWorkDirDialog(boolean allowTemplates) {
 469         throw new UnsupportedOperationException("Not supported already.");
 470     }
 471 
 472     public void showConfigEditor(boolean runTests) {
 473         throw new UnsupportedOperationException("Not supported already.");
 474     }
 475     public void showTemplateEditor() {
 476         throw new UnsupportedOperationException("Not supported already.");
 477     }
 478 
 479     /**
 480      * Invoked after QSW
 481      */
 482     public void showConfigEditor() {
 483         sessionControl.edit();
 484     }
 485 
 486     /**
 487      * Invoked after QSW
 488      */
 489     public void runTests() {
 490         runTestsHandler.runTests();
 491     }
 492 
 493 
 494     public void runTests(String[] urls) {
 495         if (urls == null || urls.length == 0)
 496             // error dialog?
 497             return;
 498         runTestsHandler.executeImmediate(urls);
 499     }
 500 
 501     public void showMessage(ResourceBundle msgs, String key) {
 502         throw new UnsupportedOperationException("Not supported yet.");
 503     }
 504 
 505     public void printSetup() {
 506         PageFormat pf = PrinterJob.getPrinterJob().pageDialog(
 507             (pageFormat == null ? PrinterJob.getPrinterJob().defaultPage() : pageFormat));
 508         pageFormat = (pf == null ? pageFormat : pf);
 509     }
 510 
 511     public void print(Printable p) {
 512         //throw new UnsupportedOperationException("Not supported yet.");
 513         PrinterJob pj = PrinterJob.getPrinterJob();
 514 
 515         pj.setPrintable(p, (pageFormat == null ? pj.defaultPage() : pageFormat));
 516         boolean result = pj.printDialog();
 517 
 518         if (result) {
 519             try {
 520                 pj.print();
 521             } catch(PrinterException e) {
 522                 // Should send to logging system
 523                 //e.printStackTrace();
 524             }
 525         }
 526         else {
 527             //System.err.println("print job REJECTED!");
 528             //Send to logging system
 529         }
 530     }
 531 
 532     public void setWorkDir(WorkDirectory wd, boolean addToFileHistory) throws Fault, TestSuite.Fault {
 533         throw new UnsupportedOperationException("Not supported yet.");
 534     }
 535 
 536     /**
 537      * Causes a series of actions to be performed to complete configuration.
 538      */
 539     public void configure() {
 540         sessionControl.configure();
 541     }
 542 
 543     /**
 544      * @return true if configuring is in progress at the moment.
 545      */
 546     public boolean isConfiguring() {
 547         return sessionControl.isConfiguring();
 548     }
 549 
 550 
 551     public ExecToolManager getExecToolManager() {
 552         return etm;
 553     }
 554 
 555     public void showQuickStartWizard() {
 556         throw new UnsupportedOperationException("Not supported yet.");
 557     }
 558     public boolean isQuickStartWizardShowing() {
 559         return false;
 560     }
 561 
 562     void updateTitle() {
 563         // set the title for the tool, based on the following info:
 564         // - test suite name
 565         // - test suite path
 566         // - work dir path
 567         // all of which may be null.
 568 
 569         String testSuiteName = (testSuite == null ? null : testSuite.getName());
 570         WorkDirectory workDir = session.getParameters().getWorkDirectory();
 571         String workDirPath = (workDir == null ? null : workDir.getRoot().getPath());
 572         if (testSuite == null)
 573             setI18NTitle("exec.title.noTS.txt");
 574         else if (workDirPath == null) {
 575             if (testSuiteName == null)
 576                 setI18NTitle("exec.title.noWD.txt");
 577             else {
 578                 setShortTitle(testSuiteName);
 579                 setI18NTitle("exec.title.tsName.txt", testSuiteName);
 580             }
 581         } else {
 582             if (testSuiteName == null)
 583                 // workDirPath == null is verified
 584                 setI18NTitle("exec.title.wd.txt", workDirPath);
 585             else {
 586                 setShortTitle(testSuiteName);
 587                 setI18NTitle("exec.title.tsName_wd.txt", new Object[]{testSuiteName, workDirPath});
 588             }
 589         }
 590 
 591     }
 592 
 593     void pauseTreeCacheWork() {
 594         if (testTreePanel != null &&
 595                 testTreePanel.getTreePanelModel() != null)
 596             testTreePanel.getTreePanelModel().pauseWork();
 597         else
 598             shouldPauseTree = true;
 599     }
 600 
 601     void unpauseTreeCacheWork() {
 602         if (testTreePanel != null &&
 603                 testTreePanel.getTreePanelModel() != null) {
 604             testTreePanel.getTreePanelModel().refreshTree();
 605             testTreePanel.getTreePanelModel().unpauseWork();
 606 
 607         }
 608         else
 609             shouldPauseTree = false;
 610     }
 611     // special method to allow saving when the interview was externally modified
 612     // for JDTS project, may change in the future
 613     // as of JT 4.3 does nothing...
 614     void syncInterview() {
 615         // nothing to do :)
 616     }
 617 
 618     // legacy
 619     void loadInterview(File file) {
 620         if (sessionControl instanceof BasicSessionControl) {
 621             BasicSessionControl bcc = (BasicSessionControl)sessionControl;
 622             if (bcc.session.getWorkDirectory() == null) {
 623                 throw new IllegalStateException();
 624             }
 625             bcc.loadInterviewFromFile(bcc.session.getWorkDirectory(), file);
 626         }
 627     }
 628 
 629     void saveTreeState(Map<String, String> m) {
 630         testTreePanel.saveTreeState(m);
 631     }
 632 
 633     void restoreTreeState(Map<String, String> m) {
 634         testTreePanel.restoreTreeState(m);
 635     }
 636 
 637     static final String TOOLBAR_PREF = "exec.toolbar";
 638     static final String FILTER_WARN_PREF = "exec.filterWarn";
 639     static final String TESTS2RUN_PREF = "exec.tests2runPop";
 640     static final String ACTIVE_FILTER = "filter";
 641 
 642 }