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