1 package org.oddjob.monitor; 2 3 import java.awt.event.ActionEvent ; 4 import java.awt.event.WindowAdapter ; 5 import java.awt.event.WindowEvent ; 6 import java.io.File ; 7 import java.io.IOException ; 8 import java.io.ObjectInputStream ; 9 import java.io.ObjectOutputStream ; 10 import java.util.ArrayList ; 11 import java.util.List ; 12 13 import javax.swing.AbstractAction ; 14 import javax.swing.Action ; 15 import javax.swing.JFileChooser ; 16 import javax.swing.JFrame ; 17 import javax.swing.JMenu ; 18 import javax.swing.JMenuItem ; 19 import javax.swing.JOptionPane ; 20 import javax.swing.JSeparator ; 21 import javax.swing.UIManager ; 22 import javax.swing.WindowConstants ; 23 24 import org.oddjob.Oddjob; 25 import org.oddjob.Stoppable; 26 import org.oddjob.arooa.ArooaContext; 27 import org.oddjob.arooa.Lifecycle; 28 import org.oddjob.framework.SerializableJob; 29 import org.oddjob.monitor.control.PropertyPolling; 30 import org.oddjob.monitor.model.ExplorerModel; 31 import org.oddjob.monitor.view.DesignerAction; 32 import org.oddjob.monitor.view.ExplorerComponent; 33 import org.oddjob.monitor.view.MonitorMenuBar; 34 import org.oddjob.util.ThreadManager; 35 36 49 50 public class OddjobExplorer extends SerializableJob 51 implements Stoppable { 52 private static final long serialVersionUID = 20050806; 53 54 59 private transient volatile File file; 60 61 private transient File dir; 62 63 68 private transient Object rootNode; 69 70 75 private transient long pollingInterval; 76 77 83 private transient boolean loadOnly; 84 85 92 private transient String logFormat; 93 94 95 private transient JFrame frame; 96 97 private transient Action newAction; 98 private transient Action openAction; 99 private transient Action closeAction; 100 private transient Action reloadAction; 101 private transient Action designerAction; 102 private transient Action exitAction; 103 104 private transient JMenu fileMenu; 105 106 private transient ExplorerModel explorerModel; 107 private transient ExplorerComponent explorerComponent; 108 private transient MonitorMenuBar menuBar; 109 110 111 private transient PropertyPolling propertyPolling; 112 113 117 private transient ThreadManager threadManager; 118 119 private static List sharedFileHistory; 120 private List fileHistory; 121 122 123 private transient ArooaContext arooaContext; 124 125 128 public OddjobExplorer() { 129 fileHistory = new ArrayList (); 130 completeConstruction(); 131 } 132 133 137 private void completeConstruction() { 138 newAction = new NewAction(); 139 openAction = new OpenAction(); 140 closeAction = new CloseAction(); 141 reloadAction = new ReloadAction(); 142 designerAction = new DesignerAction(this); 143 exitAction = new ExitAction(); 144 145 reloadAction.setEnabled(false); 146 closeAction.setEnabled(false); 147 148 pollingInterval = 5000; 149 150 if (sharedFileHistory == null) { 151 sharedFileHistory = fileHistory; 153 } 154 else { 155 fileHistory = sharedFileHistory; 156 } 157 propertyPolling = new PropertyPolling(this); 158 159 } 160 161 167 public void setFile(File configFile) { 168 this.file = configFile; 169 if (file != null) { 170 this.dir = configFile.getAbsoluteFile().getParentFile(); 171 } 172 title(); 173 reloadAction.setEnabled(configFile != null); 174 closeAction.setEnabled(configFile != null); 175 } 176 177 void title() { 178 if (frame != null) { 179 frame.setTitle("OddJob Explorer" + (file == null 180 ? "" : " - " + file.getName())); 181 } 182 183 } 184 185 190 public File getFile() { 191 return this.file; 192 } 193 194 public void setDir(File dir) { 195 this.dir = dir; 196 } 197 198 public File getDir() { 199 return dir; 200 } 201 202 void addFileHistory() { 203 if (file == null) { 204 return; 205 } 206 fileHistory = sharedFileHistory; 207 fileHistory.remove(file); 208 fileHistory.add(file); 209 while (fileHistory.size() > 4) { 210 fileHistory.remove(0); 211 } 212 sharedFileHistory = fileHistory; 213 updateFileMenu(); 214 } 215 216 void updateFileMenu() { 217 fileMenu.removeAll(); 218 fileMenu.add(new JMenuItem (newAction)); 219 fileMenu.add(new JMenuItem (openAction)); 220 fileMenu.add(new JMenuItem (closeAction)); 221 fileMenu.add(new JMenuItem (reloadAction)); 222 fileMenu.add(new JSeparator ()); 223 224 fileMenu.add(new JMenuItem (designerAction)); 225 fileMenu.add(new JSeparator ()); 226 227 Action a[] = new Action [fileHistory.size()]; 228 for (int i = 0; i < fileHistory.size(); ++i) { 230 a[fileHistory.size() - i - 1] = new HistoryAction(fileHistory.size() - i, (File ) fileHistory.get(i)); 231 } 232 boolean hasHistory = false; 233 for (int i = 0; i < a.length; ++i) { 234 hasHistory = true; 235 fileMenu.add(new JMenuItem (a[i])); 236 } 237 if (hasHistory) { 238 fileMenu.add(new JSeparator ()); 239 } 240 fileMenu.add(new JMenuItem (exitAction)); 241 } 242 243 246 private void load() { 247 if (file == null) { 248 throw new IllegalStateException ("Config is null!"); 249 } 250 Oddjob oj = (Oddjob) rootNode; 251 oj.setFile(file); 252 oj.setName(file.getName()); 253 oj.setLoadOnly(loadOnly); 254 threadManager.run(oj, "Running root Oddjob."); 255 } 256 257 262 synchronized public void setRoot(Object rootNode) { 263 this.rootNode = rootNode; 264 } 265 266 271 synchronized public Object getRoot() { 272 return this.rootNode; 273 } 274 275 279 public boolean setContext(ArooaContext arooaContext) { 280 this.arooaContext = arooaContext; 281 return super.setContext(arooaContext); 282 } 283 284 286 public void show() { 287 if (frame == null) { 288 throw new IllegalStateException ("No frame - explorer must have stopped."); 289 } 290 frame.toFront(); 291 } 292 293 void createView() { 294 if (rootNode == null) { 295 throw new IllegalStateException ("No root not to create view from!"); 296 } 297 explorerModel = new ExplorerModel(); 298 explorerModel.setArooaContext(arooaContext); 299 explorerModel.setThreadManager(threadManager); 300 explorerModel.setLogFormat(logFormat); 301 explorerModel.setRoot(rootNode); 302 303 explorerComponent = new ExplorerComponent( 304 explorerModel, 305 menuBar, 306 propertyPolling); 307 frame.getContentPane().add(explorerComponent); 308 frame.pack(); 309 frame.validate(); 310 reloadAction.setEnabled(true); 311 closeAction.setEnabled(true); 312 } 313 314 boolean destroyView() { 315 String [] active = threadManager.activeDescriptions(); 316 if (active.length > 0) { 317 StringBuffer message = new StringBuffer (); 318 message.append("The following are still running:\n\n"); 319 for (int i = 0; i < active.length; ++i) { 320 message.append(active[i]); 321 message.append('\n'); 322 } 323 logger().debug(message.toString()); 324 JOptionPane.showMessageDialog(frame, message.toString(), "Threads Running!", JOptionPane.ERROR_MESSAGE); 325 return false; 326 } 327 if (rootNode == null) { 329 return true; 330 } 331 if (file != null) { 333 Lifecycle.destroy(rootNode); 334 addFileHistory(); 335 } 338 menuBar.noSession(); 339 explorerComponent.destroy(); 340 explorerModel.destroy(); 341 rootNode = null; 342 343 frame.getContentPane().removeAll(); 344 frame.getContentPane().validate(); 345 frame.getContentPane().repaint(); 346 reloadAction.setEnabled(false); 347 closeAction.setEnabled(false); 348 return true; 349 } 350 351 355 void createMenuBar() { 356 menuBar = new MonitorMenuBar(this); 357 fileMenu = menuBar.getFileMenu(); 358 359 updateFileMenu(); 360 } 361 362 366 protected int execute() throws Exception { 367 368 threadManager = new ThreadManager(); 369 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 370 371 frame = new JFrame (); 372 title(); 373 createMenuBar(); 374 375 frame.addWindowListener(new WindowAdapter () { 376 public void windowClosing(WindowEvent e) { 377 maybeCloseWindow(); 378 } 379 380 public void windowClosed(WindowEvent e) { 381 frame = null; 382 } 383 }); 384 385 frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 386 frame.setJMenuBar(menuBar); 387 if (file != null) { 388 rootNode = new Oddjob(); 389 createView(); 390 load(); 391 } 392 else if (rootNode != null) { 393 createView(); 394 } 395 else { 396 frame.setSize(600, 380); 397 } 398 frame.setVisible(true); 399 400 while (!stop) { 401 propertyPolling.poll(); 402 synchronized (this) { 403 try { 404 wait(pollingInterval); 405 } catch (InterruptedException e) { 406 break; 407 } 408 } 409 } 410 addFileHistory(); 411 return 0; 412 } 413 414 417 private void maybeCloseWindow() { 418 if (destroyView()) { 419 frame.dispose(); 420 stop = true; 421 synchronized (OddjobExplorer.this) { 422 OddjobExplorer.this.notifyAll(); 423 } 424 logger().debug("Monitor closed."); 425 } 426 } 427 428 public void onStop() { 429 if (file != null && rootNode != null) { 431 ((Oddjob) rootNode).stop(); 432 } 433 maybeCloseWindow(); 434 } 435 436 class NewAction extends AbstractAction { 437 NewAction() { 438 putValue(Action.NAME, "New"); 439 putValue(Action.MNEMONIC_KEY, Standards.NEW_MNEMONIC_KEY); 440 putValue(Action.ACCELERATOR_KEY, Standards.NEW_ACCELERATOR_KEY); 441 } 442 443 448 public void actionPerformed(ActionEvent e) { 449 OddjobExplorer expl = new OddjobExplorer(); 450 expl.setDir(dir); 451 Thread t = new Thread (expl); 452 t.start(); 453 } 454 } 455 456 class OpenAction extends AbstractAction { 457 OpenAction() { 458 putValue(Action.NAME, "Open"); 459 putValue(Action.MNEMONIC_KEY, Standards.OPEN_MNEMONIC_KEY); 460 putValue(Action.ACCELERATOR_KEY, Standards.OPEN_ACCELERATOR_KEY); 461 } 462 463 468 public void actionPerformed(ActionEvent e) { 469 try { 470 JFileChooser chooser = new JFileChooser (); 471 if (dir != null) { 472 chooser.setCurrentDirectory(dir); 473 } 474 475 int option = chooser.showOpenDialog(frame); 476 if (option != JFileChooser.APPROVE_OPTION) { 477 return; 478 } 479 if (!destroyView()) { 480 return; 481 } 482 483 setFile(chooser.getSelectedFile()); 484 rootNode = new Oddjob(); 485 createView(); 486 load(); 487 } 488 catch (Exception ex) { 489 logger().warn("Exception opening file [" + file + "]", ex); 490 JOptionPane.showMessageDialog(frame, ex, "Exception!", JOptionPane.ERROR_MESSAGE); 491 } 492 } 493 494 } 495 496 class CloseAction extends AbstractAction { 497 CloseAction() { 498 putValue(Action.NAME, "Close"); 499 putValue(Action.MNEMONIC_KEY, Standards.CLOSE_MNEMONIC_KEY); 500 putValue(Action.ACCELERATOR_KEY, Standards.CLOSE_ACCELERATOR_KEY); 501 } 502 503 508 public void actionPerformed(ActionEvent e) { 509 try { 510 destroyView(); 511 } 512 catch (Exception ex) { 513 logger().warn("Exception opening file [" + file + "]", ex); 514 JOptionPane.showMessageDialog(frame, ex, "Exception!", JOptionPane.ERROR_MESSAGE); 515 } 516 } 517 } 518 519 class ReloadAction extends AbstractAction { 520 ReloadAction() { 521 putValue(Action.NAME, "Reload"); 522 putValue(Action.MNEMONIC_KEY, Standards.RELOAD_MNEMONIC_KEY); 523 putValue(Action.ACCELERATOR_KEY, Standards.RELOAD_ACCELERATOR_KEY); 524 } 525 526 531 public void actionPerformed(ActionEvent e) { 532 try { 533 if (!destroyView()) { 534 return; 535 } 536 rootNode = new Oddjob(); 537 createView(); 538 load(); 539 } 540 catch (Exception ex) { 541 logger().warn("Exception reloading file [" + file + "]", ex); 542 JOptionPane.showMessageDialog(frame, ex, "Exception!", JOptionPane.ERROR_MESSAGE); 543 } 544 } 545 } 546 547 class ExitAction extends AbstractAction { 548 ExitAction() { 549 putValue(Action.NAME, "Exit"); 550 putValue(Action.MNEMONIC_KEY, Standards.EXIT_MNEMONIC_KEY); 551 } 552 553 558 public void actionPerformed(ActionEvent e) { 559 maybeCloseWindow(); 560 } 561 } 562 563 class HistoryAction extends AbstractAction { 564 private final File file; 565 HistoryAction(int number, File file) { 566 putValue(Action.NAME, "" + number + " " + file.getName() + " [" 567 + file.getAbsoluteFile().getParent() + "]"); 568 putValue(Action.MNEMONIC_KEY, new Integer (48 + number)); 569 this.file = file; 570 } 571 572 577 public void actionPerformed(ActionEvent e) { 578 try { 579 if (!destroyView()) { 580 return; 581 } 582 addFileHistory(); 583 setFile(file); 584 rootNode = new Oddjob(); 585 createView(); 586 load(); 587 } 588 catch (Exception ex) { 589 logger().warn("Exception opening file [" + file + "]", ex); 590 JOptionPane.showMessageDialog(frame, ex, "Exception!", JOptionPane.ERROR_MESSAGE); 591 } 592 } 593 } 594 595 598 private void writeObject(ObjectOutputStream s) 599 throws IOException { 600 if (destroyed) { 601 throw new IllegalStateException ("[" + this + "] destroyed"); 602 } 603 s.defaultWriteObject(); 604 } 605 606 609 private void readObject(ObjectInputStream s) 610 throws IOException , ClassNotFoundException { 611 s.defaultReadObject(); 612 completeConstruction(); 613 } 614 615 618 public synchronized long getPollingInterval() { 619 return pollingInterval; 620 } 621 622 626 public synchronized void setPollingInterval(long pollingInterval) { 627 this.pollingInterval = pollingInterval; 628 } 629 630 633 public boolean getLoadOnly() { 634 return loadOnly; 635 } 636 639 public void setLoadOnly(boolean loadOnly) { 640 this.loadOnly = loadOnly; 641 } 642 } 643 | Popular Tags |