KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > oddjob > monitor > OddjobExplorer


1 package org.oddjob.monitor;
2
3 import java.awt.event.ActionEvent JavaDoc;
4 import java.awt.event.WindowAdapter JavaDoc;
5 import java.awt.event.WindowEvent JavaDoc;
6 import java.io.File JavaDoc;
7 import java.io.IOException JavaDoc;
8 import java.io.ObjectInputStream JavaDoc;
9 import java.io.ObjectOutputStream JavaDoc;
10 import java.util.ArrayList JavaDoc;
11 import java.util.List JavaDoc;
12
13 import javax.swing.AbstractAction JavaDoc;
14 import javax.swing.Action JavaDoc;
15 import javax.swing.JFileChooser JavaDoc;
16 import javax.swing.JFrame JavaDoc;
17 import javax.swing.JMenu JavaDoc;
18 import javax.swing.JMenuItem JavaDoc;
19 import javax.swing.JOptionPane JavaDoc;
20 import javax.swing.JSeparator JavaDoc;
21 import javax.swing.UIManager JavaDoc;
22 import javax.swing.WindowConstants JavaDoc;
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 /**
37  * @oddjob.description Runs Oddjob Explorer. This is the default job that
38  * Oddjob runs on startup.
39  * <p>
40  * In the log panel the log level shown is set to be that of the
41  * rootLogger in the log4j.properties file in the <code>opt/classes</code>
42  * directory. By default it is set to INFO so you will not see
43  * DEBUG messages in the log panel. For more information on configuring the
44  * file see <a hre="http://logging.apache.org/log4j">
45  * http://logging.apache.org/log4j</a>
46  *
47  * @author Rob Gordon
48  */

49
50 public class OddjobExplorer extends SerializableJob
51 implements Stoppable {
52     private static final long serialVersionUID = 20050806;
53
54     /**
55      * @oddjob.property
56      * @oddjob.description The oddjob file.
57      * @oddjob.required No.
58      */

59     private transient volatile File JavaDoc file;
60
61     private transient File JavaDoc dir;
62
63     /**
64      * @oddjob.property
65      * @oddjob.description The root node of jobs to monitor.
66      * @oddjob.required No.
67      */

68     private transient Object JavaDoc rootNode;
69
70     /**
71      * @oddjob.property
72      * @oddjob.description How often to poll in milli seconds for property updates.
73      * @oddjob.required No.
74      */

75     private transient long pollingInterval;
76     
77     /**
78      * @oddjob.property
79      * @oddjob.description This property is passed on to Oddjob when opening
80      * and reloading a file.
81      * @oddjob.required No.
82      */

83     private transient boolean loadOnly;
84     
85     /**
86      * @oddjob.property
87      * @oddjob.description The log format for formatting log messages. For more
88      * information on the format please see <a HREF="http://logging.apache.org/log4j/docs/">
89      * http://logging.apache.org/log4j/docs/</a>
90      * @oddjob.required No.
91      */

92     private transient String JavaDoc logFormat;
93     
94     /** The frame */
95     private transient JFrame JavaDoc frame;
96         
97     private transient Action JavaDoc newAction;
98     private transient Action JavaDoc openAction;
99     private transient Action JavaDoc closeAction;
100     private transient Action JavaDoc reloadAction;
101     private transient Action JavaDoc designerAction;
102     private transient Action JavaDoc exitAction;
103
104     private transient JMenu JavaDoc fileMenu;
105     
106     private transient ExplorerModel explorerModel;
107     private transient ExplorerComponent explorerComponent;
108     private transient MonitorMenuBar menuBar;
109     
110     /** Poll for property changes. */
111     private transient PropertyPolling propertyPolling;
112     
113     /**
114      * The ThreadManager. This job will not
115      * stop until the ThreadManager says it can.
116      */

117     private transient ThreadManager threadManager;
118     
119     private static List JavaDoc sharedFileHistory;
120     private List JavaDoc fileHistory;
121
122     /** Required by 'set property' and other actions. */
123     private transient ArooaContext arooaContext;
124     
125     /**
126      * Default Constructor.
127      */

128     public OddjobExplorer() {
129         fileHistory = new ArrayList JavaDoc();
130         completeConstruction();
131     }
132     
133     /**
134      * Completes construction of this object. Required because de-serialisation
135      * doesn't go through the constructor.
136      */

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             // first to start
152
sharedFileHistory = fileHistory;
153         }
154         else {
155             fileHistory = sharedFileHistory;
156         }
157         propertyPolling = new PropertyPolling(this);
158         
159     }
160     
161     /**
162      * Set the config file name.
163      *
164      * @param configFile
165      * The config file name.
166      */

167     public void setFile(File JavaDoc 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     /**
186      * Get the config file name.
187      *
188      * @return The config file name.
189      */

190     public File JavaDoc getFile() {
191         return this.file;
192     }
193
194     public void setDir(File JavaDoc dir) {
195         this.dir = dir;
196     }
197
198     public File JavaDoc 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 JavaDoc(newAction));
219         fileMenu.add(new JMenuItem JavaDoc(openAction));
220         fileMenu.add(new JMenuItem JavaDoc(closeAction));
221         fileMenu.add(new JMenuItem JavaDoc(reloadAction));
222         fileMenu.add(new JSeparator JavaDoc());
223
224         fileMenu.add(new JMenuItem JavaDoc(designerAction));
225         fileMenu.add(new JSeparator JavaDoc());
226         
227         Action JavaDoc a[] = new Action JavaDoc[fileHistory.size()];
228         // reverse for recent first
229
for (int i = 0; i < fileHistory.size(); ++i) {
230             a[fileHistory.size() - i - 1] = new HistoryAction(fileHistory.size() - i, (File JavaDoc) 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 JavaDoc(a[i]));
236         }
237         if (hasHistory) {
238             fileMenu.add(new JSeparator JavaDoc());
239         }
240         fileMenu.add(new JMenuItem JavaDoc(exitAction));
241     }
242     
243     /**
244      * Load Oddjob from the configuration file.
245      */

246     private void load() {
247         if (file == null) {
248             throw new IllegalStateException JavaDoc("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     /**
258      * Set the root node directly.
259      *
260      * @param rootNode The root node for the monitor tree.
261      */

262     synchronized public void setRoot(Object JavaDoc rootNode) {
263         this.rootNode = rootNode;
264     }
265
266     /**
267      * Get the root node of the monitor tree.
268      *
269      * @return The root node.
270      */

271     synchronized public Object JavaDoc getRoot() {
272         return this.rootNode;
273     }
274     
275     /*
276      * (non-Javadoc)
277      * @see org.oddjob.framework.BaseComponent#setContext(org.oddjob.arooa.ArooaXMLContext)
278      */

279     public boolean setContext(ArooaContext arooaContext) {
280         this.arooaContext = arooaContext;
281         return super.setContext(arooaContext);
282     }
283     
284     /**
285      */

286     public void show() {
287         if (frame == null) {
288             throw new IllegalStateException JavaDoc("No frame - explorer must have stopped.");
289         }
290         frame.toFront();
291     }
292     
293     void createView() {
294         if (rootNode == null) {
295             throw new IllegalStateException JavaDoc("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 JavaDoc[] active = threadManager.activeDescriptions();
316         if (active.length > 0) {
317             StringBuffer JavaDoc message = new StringBuffer JavaDoc();
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         // nothing to destroy
328
if (rootNode == null) {
329             return true;
330         }
331         // if we created the oddjob we must destroy it.
332
if (file != null) {
333             Lifecycle.destroy(rootNode);
334             addFileHistory();
335             // leave conifg for reload.
336
// config = null;
337
}
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     /**
352      * Helper method to create the menu bar.
353      *
354      */

355     void createMenuBar() {
356         menuBar = new MonitorMenuBar(this);
357         fileMenu = menuBar.getFileMenu();
358         
359         updateFileMenu();
360     }
361     
362     /*
363      * (non-Javadoc)
364      * @see org.oddjob.jobs.AbstractJob#execute()
365      */

366     protected int execute() throws Exception JavaDoc {
367
368         threadManager = new ThreadManager();
369         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
370
371         frame = new JFrame JavaDoc();
372         title();
373         createMenuBar();
374
375         frame.addWindowListener(new WindowAdapter JavaDoc() {
376             public void windowClosing(WindowEvent JavaDoc e) {
377                 maybeCloseWindow();
378             }
379
380             public void windowClosed(WindowEvent JavaDoc 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 JavaDoc e) {
406                     break;
407                 }
408             }
409         }
410         addFileHistory();
411         return 0;
412     }
413     
414     /**
415      * Close.
416      */

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 this explorer owns the oddjob then we must stop it
430
if (file != null && rootNode != null) {
431             ((Oddjob) rootNode).stop();
432         }
433         maybeCloseWindow();
434     }
435     
436     class NewAction extends AbstractAction JavaDoc {
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         /*
444          * (non-Javadoc)
445          *
446          * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
447          */

448         public void actionPerformed(ActionEvent JavaDoc e) {
449             OddjobExplorer expl = new OddjobExplorer();
450             expl.setDir(dir);
451             Thread JavaDoc t = new Thread JavaDoc(expl);
452             t.start();
453         }
454     }
455         
456     class OpenAction extends AbstractAction JavaDoc {
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         /*
464          * (non-Javadoc)
465          *
466          * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
467          */

468         public void actionPerformed(ActionEvent JavaDoc e) {
469             try {
470                 JFileChooser JavaDoc chooser = new JFileChooser JavaDoc();
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 JavaDoc 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 JavaDoc {
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         /*
504          * (non-Javadoc)
505          *
506          * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
507          */

508         public void actionPerformed(ActionEvent JavaDoc e) {
509             try {
510                 destroyView();
511             }
512             catch (Exception JavaDoc 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 JavaDoc {
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         /*
527          * (non-Javadoc)
528          *
529          * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
530          */

531         public void actionPerformed(ActionEvent JavaDoc e) {
532             try {
533                 if (!destroyView()) {
534                     return;
535                 }
536                 rootNode = new Oddjob();
537                 createView();
538                 load();
539             }
540             catch (Exception JavaDoc 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 JavaDoc {
548         ExitAction() {
549             putValue(Action.NAME, "Exit");
550             putValue(Action.MNEMONIC_KEY, Standards.EXIT_MNEMONIC_KEY);
551         }
552
553         /*
554          * (non-Javadoc)
555          *
556          * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
557          */

558         public void actionPerformed(ActionEvent JavaDoc e) {
559             maybeCloseWindow();
560         }
561     }
562
563     class HistoryAction extends AbstractAction JavaDoc {
564         private final File JavaDoc file;
565         HistoryAction(int number, File JavaDoc file) {
566             putValue(Action.NAME, "" + number + " " + file.getName() + " ["
567                     + file.getAbsoluteFile().getParent() + "]");
568             putValue(Action.MNEMONIC_KEY, new Integer JavaDoc(48 + number));
569             this.file = file;
570         }
571
572         /*
573          * (non-Javadoc)
574          *
575          * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
576          */

577         public void actionPerformed(ActionEvent JavaDoc 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 JavaDoc ex) {
589                 logger().warn("Exception opening file [" + file + "]", ex);
590                 JOptionPane.showMessageDialog(frame, ex, "Exception!", JOptionPane.ERROR_MESSAGE);
591             }
592         }
593     }
594
595     /**
596      * Custom serialsation.
597      */

598     private void writeObject(ObjectOutputStream JavaDoc s)
599     throws IOException JavaDoc {
600         if (destroyed) {
601             throw new IllegalStateException JavaDoc("[" + this + "] destroyed");
602         }
603         s.defaultWriteObject();
604     }
605
606     /**
607      * Custom serialisation.
608      */

609     private void readObject(ObjectInputStream JavaDoc s)
610     throws IOException JavaDoc, ClassNotFoundException JavaDoc {
611         s.defaultReadObject();
612         completeConstruction();
613     }
614
615     /**
616      * @return Returns the pollingInterval.
617      */

618     public synchronized long getPollingInterval() {
619         return pollingInterval;
620     }
621
622     /**
623      * @param pollingInterval
624      * The pollingInterval to set.
625      */

626     public synchronized void setPollingInterval(long pollingInterval) {
627         this.pollingInterval = pollingInterval;
628     }
629
630     /**
631      * @return Returns the loadOnly.
632      */

633     public boolean getLoadOnly() {
634         return loadOnly;
635     }
636     /**
637      * @param loadOnly The loadOnly to set.
638      */

639     public void setLoadOnly(boolean loadOnly) {
640         this.loadOnly = loadOnly;
641     }
642 }
643
Popular Tags