1 /* 2 * $Id$ 3 * 4 * Copyright (c) 2002, 2009, 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.audit; 28 29 import java.awt.BorderLayout; 30 import java.awt.Component; 31 import java.awt.Dimension; 32 import java.awt.EventQueue; 33 import java.awt.GridBagConstraints; 34 import java.awt.GridBagLayout; 35 import java.awt.event.ActionEvent; 36 import java.awt.event.ActionListener; 37 import java.awt.event.HierarchyEvent; 38 import java.awt.event.HierarchyListener; 39 import java.io.File; 40 import java.util.Map; 41 import javax.swing.BorderFactory; 42 import javax.swing.JLabel; 43 import javax.swing.JMenu; 44 import javax.swing.JMenuBar; 45 import javax.swing.JPanel; 46 import javax.swing.JTabbedPane; 47 import javax.swing.JTextField; 48 import javax.swing.event.ChangeEvent; 49 import javax.swing.event.ChangeListener; 50 51 import com.sun.javatest.tool.jthelp.ContextHelpManager; 52 import com.sun.javatest.InterviewParameters; 53 import com.sun.javatest.TestSuite; 54 import com.sun.javatest.WorkDirectory; 55 import com.sun.javatest.tool.Tool; 56 import com.sun.javatest.util.I18NResourceBundle; 57 import javax.swing.JDialog; 58 import javax.swing.Timer; 59 60 class AuditTool extends Tool 61 { 62 AuditTool(AuditToolManager m) { 63 super(m, "audit", "audit.window.csh"); 64 setI18NTitle("tool.title"); 65 setShortTitle(uif.getI18NString("tool.shortTitle")); 66 initGUI(); 67 } 68 69 public void dispose() { 70 super.dispose(); 71 72 if (optionsDialog != null) { 73 optionsDialog.setVisible(false); 74 optionsDialog.dispose(); 75 } 76 } 77 78 public JMenuBar getMenuBar() { 79 return menuBar; 80 } 81 82 public TestSuite[] getLoadedTestSuites() { 83 TestSuite ts = (interviewParams == null ? null : interviewParams.getTestSuite()); 84 return (ts == null ? null : new TestSuite[] { ts }); 85 } 86 87 public WorkDirectory[] getLoadedWorkDirectories() { 88 WorkDirectory wd = (interviewParams == null ? null : interviewParams.getWorkDirectory()); 89 return (wd == null ? null : new WorkDirectory[] { wd }); 90 } 91 92 public void save(Map<String, String> m) { 93 if (interviewParams == null) 94 return; 95 96 // save test suite 97 TestSuite ts = interviewParams.getTestSuite(); 98 m.put("testSuite", ts.getRoot().getPath()); 99 100 // save work directory 101 WorkDirectory wd = interviewParams.getWorkDirectory(); 102 if (wd != null) 103 m.put("workDir", wd.getPath()); 104 105 // save name of interview file 106 File cf = interviewParams.getFile(); 107 if (cf != null) 108 m.put("config", cf.getPath()); 109 } 110 111 @Override 112 protected void restore(Map<String, String> m) { 113 String tsp = (String) (m.get("testSuite")); 114 String wdp = (String) (m.get("workDir")); 115 String cfp = (String) (m.get("config")); 116 117 if (tsp == null && wdp == null && cfp == null) 118 return; 119 120 try { 121 if (interviewParams != null) { 122 interviewParams.dispose(); 123 } 124 interviewParams = InterviewParameters.open(tsp, wdp, cfp); 125 updateGUI(null, interviewParams, uif.getI18NString("tool.restore.txt")); 126 autoShowOptions = false; 127 } 128 catch (InterviewParameters.Fault e) { 129 uif.showError("tool.cantRestore", e.getMessage()); 130 } 131 } 132 133 private void initGUI() { 134 int dpi = uif.getDotsPerInch(); 135 setPreferredSize(new Dimension(6 * dpi, 4 * dpi)); 136 setLayout(new BorderLayout()); 137 138 addHierarchyListener(listener); 139 140 menuBar = uif.createMenuBar("tool"); 141 String[] auditMenuEntries = { 142 OPTIONS 143 }; 144 JMenu auditMenu = uif.createMenu("tool.audit", auditMenuEntries, listener); 145 menuBar.add(auditMenu); 146 147 menuBar.add(uif.createHorizontalGlue("tool.pad")); 148 149 JMenu helpMenu = uif.createMenu("tool.help"); 150 helpMenu.add(uif.createHelpMenuItem("tool.help.window", "audit.window.csh")); 151 menuBar.add(helpMenu); 152 153 JPanel head = uif.createPanel("head", false); 154 head.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 155 head.setLayout(new GridBagLayout()); 156 157 GridBagConstraints lc = new GridBagConstraints(); 158 lc.anchor = GridBagConstraints.EAST; 159 lc.gridwidth = 1; 160 lc.insets.right = 5; 161 lc.weightx = 0; 162 163 GridBagConstraints fc = new GridBagConstraints(); 164 fc.fill = GridBagConstraints.HORIZONTAL; 165 fc.weightx = 1; 166 fc.gridwidth = GridBagConstraints.REMAINDER; 167 168 testSuiteField = initField("tool.testSuite", head, lc, fc); 169 workDirField = initField("tool.workDir", head, lc, fc); 170 configFileField = initField("tool.configFile", head, lc, fc); 171 172 add(head, BorderLayout.NORTH); 173 174 panes = new AuditPane[] { 175 new SummaryPane(uif), 176 new BadTestsPane(uif), 177 new BadChecksumPane(uif), 178 new BadTestDescriptionPane(uif), 179 new BadTestCaseTestsPane(uif) 180 }; 181 182 tabs = uif.createTabbedPane("tool.tabs", panes); 183 tabs.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); 184 tabs.addChangeListener(new ChangeListener() { 185 public void stateChanged(ChangeEvent e) { 186 Component c = tabs.getSelectedComponent(); 187 ContextHelpManager.setHelpIDString(tabs, ContextHelpManager.getHelpIDString(c)); 188 } 189 }); 190 ContextHelpManager.setHelpIDString(tabs, ContextHelpManager.getHelpIDString(panes[0])); 191 192 add(tabs, BorderLayout.CENTER); 193 194 updateGUI(null, null, uif.getI18NString("tool.initial.txt")); 195 } 196 197 private JTextField initField(String key, JPanel p, 198 GridBagConstraints lc, GridBagConstraints fc) { 199 200 JLabel lbl = uif.createLabel(key, true); 201 p.add(lbl, lc); 202 JTextField tf = uif.createOutputField(key, lbl); 203 tf.setBorder(null); 204 p.add(tf, fc); 205 return tf; 206 } 207 208 209 private synchronized void showOptions() { 210 if (worker != null) { 211 uif.showError("tool.auditInProgress"); 212 return; 213 } 214 215 if (optionsDialog == null) { 216 // should arguably worry about standard ownership problem 217 optionsDialog = new OptionsDialog(this, listener, uif); 218 } 219 220 if (interviewParams != null) 221 optionsDialog.setParameters(interviewParams); 222 223 optionsDialog.setVisible(true); 224 } 225 226 private void setOptions() { 227 String tsp = optionsDialog.getTestSuitePath(); 228 String wdp = optionsDialog.getWorkDirPath(); 229 String cfp = optionsDialog.getConfigFilePath(); 230 231 if ( isEmpty(tsp) && isEmpty(wdp) && isEmpty(cfp) ) { 232 uif.showError("tool.noOptions"); 233 return; 234 } 235 236 try { 237 if (interviewParams != null) { 238 interviewParams.dispose(); 239 } 240 interviewParams = InterviewParameters.open(tsp, wdp, cfp); 241 } 242 catch (InterviewParameters.Fault e) { 243 uif.showError("tool.badOptions", e.getMessage()); 244 return; 245 } 246 247 optionsDialog.setVisible(false); 248 249 startAudit(); 250 } 251 252 private synchronized void startAudit() { 253 if (worker != null) { 254 uif.showError("tool.auditInProgress"); 255 return; 256 } 257 258 // can't do this operation without WD 259 if (interviewParams.getWorkDirectory() == null) { 260 uif.showError("tool.noWd"); 261 return; 262 } 263 264 final JDialog d = uif.createWaitDialog("tool.wait", this); 265 d.setLocationRelativeTo(this); 266 267 worker = new Thread() { 268 public void run() { 269 Audit a = audit; // default to previous value 270 try { 271 a = new Audit(interviewParams); 272 } 273 finally { 274 synchronized (AuditTool.this) { 275 worker = null; 276 } 277 d.setVisible(false); 278 // the following may not be right if the audit 279 // has been interrupted and we are reverting to 280 // previous state. Ideally, should pull parameters 281 // from the audit object 282 updateGUI(a, interviewParams, null); 283 } 284 } 285 }; 286 287 ActionListener al = new ActionListener() { 288 public void actionPerformed(ActionEvent evt){ 289 // show dialog if still processing 290 if (worker != null && worker.isAlive()) { 291 d.setVisible(true); 292 } 293 } 294 }; 295 296 // show wait dialog if operation is still running after 297 // WAIT_DIALOG_DELAY 298 Timer timer = new Timer(WAIT_DIALOG_DELAY, al); 299 timer.setRepeats(false); 300 timer.start(); 301 302 worker.start(); 303 304 305 updateGUI(null, interviewParams, ""); 306 } 307 308 private static int WAIT_DIALOG_DELAY = 2000; 309 310 private void updateGUI(final Audit a, final InterviewParameters p, final String msg) { 311 if (!EventQueue.isDispatchThread()) { 312 EventQueue.invokeLater(new Runnable() { 313 public void run() { 314 updateGUI(a, p, msg); 315 } 316 }); 317 return; 318 } 319 320 audit = a; 321 322 TestSuite ts = (p == null ? null : p.getTestSuite()); 323 String tsp = (ts == null ? "" : ts.getPath()); 324 testSuiteField.setText(tsp); 325 326 WorkDirectory wd = (p == null ? null : p.getWorkDirectory()); 327 String wdp = (wd == null? "" : wd.getPath()); 328 workDirField.setText(wdp); 329 330 File configFile = (p == null ? null : p.getFile()); 331 String cfp = (configFile == null ? "" : configFile.getPath()); 332 configFileField.setText(cfp); 333 334 for (int i = 0; i < panes.length; i++) { 335 AuditPane pane = panes[i]; 336 if (a != null) 337 pane.show(a); 338 else if (msg != null) 339 pane.show(msg); 340 } 341 } 342 343 private static boolean isEmpty(String s) { 344 return (s == null || s.length() == 0); 345 } 346 347 348 private JMenuBar menuBar; 349 private JTextField testSuiteField; 350 private JTextField workDirField; 351 private JTextField configFileField; 352 private AuditPane[] panes; 353 private JTabbedPane tabs; 354 private OptionsDialog optionsDialog; 355 private boolean autoShowOptions = true;; 356 private Listener listener = new Listener(); 357 358 private InterviewParameters interviewParams; 359 360 // access to these fields must be synchronized 361 private Thread worker; 362 private Audit audit; 363 364 private static final String OPTIONS = "options"; 365 private static I18NResourceBundle i18n = I18NResourceBundle.getBundleForClass(AuditTool.class); 366 367 private class Listener implements ActionListener, HierarchyListener { 368 public void actionPerformed(ActionEvent e) { 369 String cmd = e.getActionCommand(); 370 if (cmd.equals(OPTIONS)) { 371 showOptions(); 372 } 373 else if (cmd.equals(OptionsDialog.OK)) { 374 setOptions(); 375 } 376 } 377 378 public void hierarchyChanged(HierarchyEvent e) { 379 if (isShowing() && autoShowOptions) { 380 EventQueue.invokeLater(new Runnable() { 381 public void run() { 382 showOptions(); 383 } 384 }); 385 autoShowOptions = false; 386 } 387 } 388 }; 389 }