KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > admin > AdminClientPanel


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.admin;
5
6 import org.apache.commons.httpclient.HttpClient;
7 import org.apache.commons.httpclient.HttpStatus;
8 import org.apache.commons.httpclient.methods.GetMethod;
9 import org.apache.commons.io.IOUtils;
10 import org.apache.log4j.Level;
11 import org.apache.log4j.Logger;
12 import org.dijon.Button;
13 import org.dijon.CheckBox;
14 import org.dijon.Dialog;
15 import org.dijon.DialogResource;
16 import org.dijon.FrameResource;
17 import org.dijon.Label;
18 import org.dijon.ScrollPane;
19 import org.dijon.Separator;
20 import org.dijon.TextArea;
21 import org.dijon.TextPane;
22 import org.dijon.UndoMonger;
23
24 import com.tc.admin.common.BrowserLauncher;
25 import com.tc.admin.common.ComponentNode;
26 import com.tc.admin.common.ContactTerracottaAction;
27 import com.tc.admin.common.PrefsHelper;
28 import com.tc.admin.common.XAbstractAction;
29 import com.tc.admin.common.XContainer;
30 import com.tc.admin.common.XMenu;
31 import com.tc.admin.common.XMenuBar;
32 import com.tc.admin.common.XMenuItem;
33 import com.tc.admin.common.XRootNode;
34 import com.tc.admin.common.XTabbedPane;
35 import com.tc.admin.common.XTextArea;
36 import com.tc.admin.common.XTextField;
37 import com.tc.admin.common.XTreeModel;
38 import com.tc.admin.common.XTreeNode;
39
40 import java.awt.BorderLayout JavaDoc;
41 import java.awt.event.ActionEvent JavaDoc;
42 import java.awt.event.ActionListener JavaDoc;
43 import java.awt.event.HierarchyEvent JavaDoc;
44 import java.awt.event.HierarchyListener JavaDoc;
45 import java.awt.event.KeyAdapter JavaDoc;
46 import java.awt.event.KeyEvent JavaDoc;
47 import java.awt.event.MouseAdapter JavaDoc;
48 import java.awt.event.MouseEvent JavaDoc;
49 import java.beans.PropertyChangeEvent JavaDoc;
50 import java.beans.PropertyChangeListener JavaDoc;
51 import java.io.IOException JavaDoc;
52 import java.io.InputStream JavaDoc;
53 import java.io.PrintWriter JavaDoc;
54 import java.io.StringWriter JavaDoc;
55 import java.net.ConnectException JavaDoc;
56 import java.net.MalformedURLException JavaDoc;
57 import java.net.URL JavaDoc;
58 import java.net.URLEncoder JavaDoc;
59 import java.util.ArrayList JavaDoc;
60 import java.util.Date JavaDoc;
61 import java.util.Properties JavaDoc;
62 import java.util.StringTokenizer JavaDoc;
63 import java.util.prefs.Preferences JavaDoc;
64
65 import javax.swing.Icon JavaDoc;
66 import javax.swing.JOptionPane JavaDoc;
67 import javax.swing.JPopupMenu JavaDoc;
68 import javax.swing.JScrollPane JavaDoc;
69 import javax.swing.JSeparator JavaDoc;
70 import javax.swing.JSplitPane JavaDoc;
71 import javax.swing.KeyStroke JavaDoc;
72 import javax.swing.SwingUtilities JavaDoc;
73 import javax.swing.Timer JavaDoc;
74 import javax.swing.event.ChangeEvent JavaDoc;
75 import javax.swing.event.ChangeListener JavaDoc;
76 import javax.swing.event.DocumentEvent JavaDoc;
77 import javax.swing.event.DocumentListener JavaDoc;
78 import javax.swing.event.HyperlinkEvent JavaDoc;
79 import javax.swing.event.HyperlinkListener JavaDoc;
80 import javax.swing.event.TreeSelectionEvent JavaDoc;
81 import javax.swing.event.TreeSelectionListener JavaDoc;
82 import javax.swing.text.AttributeSet JavaDoc;
83 import javax.swing.text.Element JavaDoc;
84 import javax.swing.text.JTextComponent JavaDoc;
85 import javax.swing.text.html.HTML JavaDoc;
86 import javax.swing.tree.TreeModel JavaDoc;
87 import javax.swing.tree.TreePath JavaDoc;
88 import javax.swing.undo.UndoManager JavaDoc;
89 import javax.swing.undo.UndoableEdit JavaDoc;
90
91 public class AdminClientPanel extends XContainer
92   implements AdminClientController,
93              UndoMonger
94 {
95   private NavTree m_tree;
96   private XContainer m_nodeView;
97   private JSplitPane JavaDoc m_mainSplitter;
98   private Integer JavaDoc m_mainDivLoc;
99   private JSplitPane JavaDoc m_leftSplitter;
100   private Integer JavaDoc m_leftDivLoc;
101   private DividerListener m_dividerListener;
102   private XTabbedPane m_bottomPane;
103   private XTextArea m_logArea;
104   private ArrayList JavaDoc m_logListeners;
105   private Icon JavaDoc m_infoIcon;
106   private XTextField m_statusLine;
107   protected UndoAction m_undoCmd;
108   protected RedoAction m_redoCmd;
109   protected UndoManager JavaDoc m_undoManager;
110   protected NewServerAction m_newServerAction;
111   protected HelpAction m_helpAction;
112   protected AboutAction m_aboutAction;
113
114   public static final String JavaDoc UNDO = "Undo";
115   public static final String JavaDoc REDO = "Redo";
116
117   protected MouseAdapter JavaDoc
118     m_statusCleaner = new MouseAdapter JavaDoc() {
119       public void mouseClicked(MouseEvent JavaDoc e) {
120         setStatus(null);
121       }
122     };
123   
124   public AdminClientPanel() {
125     super();
126
127     AdminClientContext acc = AdminClient.getContext();
128     
129     acc.controller = this;
130     
131     FrameResource frameRes = acc.topRes.getFrame("MyFrame");
132     load(frameRes.getContentPane());
133     
134     m_tree = (NavTree)findComponent("Tree");
135     m_nodeView = (XContainer)findComponent("NodeView");
136     m_bottomPane = (XTabbedPane)findComponent("BottomPane");
137     m_logArea = (XTextArea)m_bottomPane.findComponent("LogArea");
138     m_statusLine = (XTextField)findComponent("StatusLine");
139
140     m_nodeView.setLayout(new BorderLayout JavaDoc());
141
142     m_tree.addMouseListener(new MouseAdapter JavaDoc() {
143       public void mousePressed(MouseEvent JavaDoc me) {
144         TreePath JavaDoc path = m_tree.getPathForLocation(me.getX(), me.getY());
145
146         if(path != null) {
147           m_tree.requestFocus();
148           
149           XTreeNode node = (XTreeNode)path.getLastPathComponent();
150           if(node != null) {
151             select(node);
152           }
153         }
154       }
155
156       public void mouseClicked(MouseEvent JavaDoc me) {
157         TreePath JavaDoc path = m_tree.getPathForLocation(me.getX(), me.getY());
158
159         if(path != null) {
160           m_tree.requestFocus();
161           
162           XTreeNode node = (XTreeNode)path.getLastPathComponent();
163           if(node != null) {
164             node.nodeClicked(me);
165           }
166         }
167       }
168     });
169     
170     m_tree.addTreeSelectionListener(new TreeSelectionListener JavaDoc() {
171       public void valueChanged(TreeSelectionEvent JavaDoc tse) {
172         TreePath JavaDoc path = tse.getNewLeadSelectionPath();
173
174         m_nodeView.removeAll();
175
176         if(path != null) {
177           m_tree.requestFocus();
178           
179           XTreeNode node = (XTreeNode)path.getLastPathComponent();
180           if(node != null) {
181             node.nodeSelected(tse);
182             
183             if(node instanceof ComponentNode) {
184               ComponentNode cnode = (ComponentNode)node;
185               java.awt.Component JavaDoc comp = (java.awt.Component JavaDoc)cnode.getComponent();
186               
187               if(comp != null) {
188                 m_nodeView.add(comp);
189               }
190             }
191           }
192         }
193
194         m_nodeView.revalidate();
195         m_nodeView.repaint();
196       }
197     });
198
199     m_infoIcon = LogHelper.getHelper().getInfoIcon();
200
201     m_logListeners = new ArrayList JavaDoc();
202     LogDocumentListener ldl = new LogDocumentListener(m_logArea);
203     m_logListeners.add(ldl);
204     m_logArea.getDocument().addDocumentListener(ldl);
205
206     m_bottomPane.addChangeListener(new ChangeListener JavaDoc() {
207       public void stateChanged(ChangeEvent JavaDoc e) {
208         int index = m_bottomPane.getSelectedIndex();
209         m_bottomPane.setIconAt(index, null);
210       }
211     });
212
213     m_tree.setModel(new NavTreeModel());
214
215     setHelpPath("/com/tc/admin/AdminClient.html");
216
217     addMouseListener(m_statusCleaner);
218
219     addKeyListener(new KeyAdapter JavaDoc() {
220       public void keyPressed(KeyEvent JavaDoc e) {
221         setStatus(null);
222       }
223     });
224
225     getActionMap().put(UNDO, m_undoCmd = new UndoAction());
226     getActionMap().put(REDO, m_redoCmd = new RedoAction());
227     
228     initNavTreeMenu();
229   }
230
231   protected NewServerAction getNewServerAction() {
232     if(m_newServerAction == null) {
233       m_newServerAction = new NewServerAction();
234     }
235     return m_newServerAction;
236   }
237   
238   protected HelpAction getHelpAction() {
239     if(m_helpAction == null) {
240       m_helpAction = new HelpAction();
241     }
242     return m_helpAction;
243   }
244   
245   protected AboutAction getAboutAction() {
246     if(m_aboutAction == null) {
247       m_aboutAction = new AboutAction();
248     }
249     return m_aboutAction;
250   }
251   
252   protected void initNavTreeMenu() {
253     JPopupMenu JavaDoc popup = new JPopupMenu JavaDoc("ProjectTree Actions");
254     
255     popup.add(getNewServerAction());
256     popup.add(new Separator());
257     popup.add(getHelpAction());
258     if(shouldAddAboutItem()) {
259       popup.add(getAboutAction());
260     }
261     
262     m_tree.setPopupMenu(popup);
263   }
264   
265   private String JavaDoc getBundleString(String JavaDoc key) {
266     return AdminClient.getContext().getMessage(key);
267   }
268   
269   private String JavaDoc formatBundleString(String JavaDoc key, Object JavaDoc[] args) {
270     return AdminClient.getContext().format(key, args);
271   }
272
273   private String JavaDoc formatBundleString(String JavaDoc key, Object JavaDoc arg) {
274     return formatBundleString(key, new Object JavaDoc[]{arg});
275   }
276
277   public void initMenubar(XMenuBar menuBar) {
278     XMenu menu = new XMenu(getBundleString("file.menu.label"));
279
280     menu.add(m_newServerAction = new NewServerAction());
281     menu.add(new JSeparator JavaDoc());
282     menu.add(new QuitAction());
283
284     menuBar.add(menu);
285
286     menu = new XMenu(getBundleString("help.menu.label"));
287     XMenuItem mitem = new XMenuItem("AdminConsole Help",
288                                     HelpHelper.getHelper().getHelpIcon());
289     mitem.setAction(m_helpAction = new HelpAction());
290     menu.add(mitem);
291     menu.addSeparator();
292     menu.add(new ContactTerracottaAction("Visit Terracotta Forums",
293                                          "http://www.terracottatech.com/forums/"));
294     menu.add(new ContactTerracottaAction("Contact Terracotta Technical Support",
295                                          "http://www.terracottatech.com/support_services.shtml"));
296     menu.addSeparator();
297     menu.add(new UpdateCheckerAction());
298     menu.add(m_aboutAction = new AboutAction());
299     
300     menuBar.add(menu);
301   }
302
303   class HelpAction extends XAbstractAction {
304     HelpAction() {
305       super("AdminConsole Help");
306     }
307     
308     public void actionPerformed(ActionEvent JavaDoc ae) {
309       block();
310       BrowserLauncher.openURL("http://www.terracotta.org/kit/reflector?kitID=2.3&pageID=ConsoleGuide");
311       unblock();
312     }
313   }
314   
315   public boolean isExpanded(XTreeNode node) {
316     return node != null &&
317            m_tree.isExpanded(new TreePath JavaDoc(node.getPath()));
318   }
319
320   public void expand(XTreeNode node) {
321     if(node != null) {
322       m_tree.expandPath(new TreePath JavaDoc(node.getPath()));
323     }
324   }
325
326   public boolean isSelected(XTreeNode node) {
327     return node != null &&
328            m_tree.isPathSelected(new TreePath JavaDoc(node.getPath()));
329   }
330
331   public void select(XTreeNode node) {
332     if(node != null) {
333       m_tree.requestFocus();
334       m_tree.setSelectionPath(new TreePath JavaDoc(node.getPath()));
335     }
336   }
337
338   public void remove(XTreeNode node) {
339     XTreeModel model = (XTreeModel)m_tree.getModel();
340     XTreeNode parent = (XTreeNode)node.getParent();
341     int index = parent.getIndex(node);
342     TreePath JavaDoc nodePath = new TreePath JavaDoc(node.getPath());
343     TreePath JavaDoc selPath = m_tree.getSelectionPath();
344
345     node.tearDown();
346     model.removeNodeFromParent(node);
347
348     if(nodePath.isDescendant(selPath)) {
349       int count = parent.getChildCount();
350
351       if(count > 0) {
352         node = (XTreeNode)parent.getChildAt(index < count ? index : count-1);
353       }
354       else {
355         node = parent;
356       }
357
358       m_tree.setSelectionPath(new TreePath JavaDoc(node.getPath()));
359     }
360   }
361
362   public void nodeStructureChanged(XTreeNode node) {
363     TreeModel treeModel = m_tree.getModel();
364     
365     if(treeModel instanceof XTreeModel) {
366       ((XTreeModel)treeModel).nodeStructureChanged(node);
367     }
368   }
369
370   public void nodeChanged(XTreeNode node) {
371     TreeModel treeModel = m_tree.getModel();
372     
373     if(treeModel instanceof XTreeModel) {
374       ((XTreeModel)treeModel).nodeChanged(node);
375     }
376   }
377
378   protected Preferences JavaDoc getPreferences() {
379     AdminClientContext acc = AdminClient.getContext();
380     return acc.prefs.node("AdminClientFrame");
381   }
382
383   protected void storePreferences() {
384     AdminClientContext acc = AdminClient.getContext();
385     acc.client.storePrefs();
386   }
387
388   private int getSplitPref(JSplitPane JavaDoc splitter) {
389     Preferences JavaDoc prefs = getPreferences();
390     Preferences JavaDoc splitPrefs = prefs.node(splitter.getName());
391
392     return splitPrefs.getInt("Split", -1);
393   }
394
395   private JSplitPane JavaDoc getMainSplitter() {
396     if(m_mainSplitter == null) {
397       m_mainSplitter = (JSplitPane JavaDoc)findComponent("MainSplitter");
398       m_mainDivLoc = new Integer JavaDoc(getSplitPref(m_mainSplitter));
399
400       if(m_dividerListener == null) {
401         m_dividerListener = new DividerListener();
402       }
403     }
404
405     return m_mainSplitter;
406   }
407
408   private JSplitPane JavaDoc getLeftSplitter() {
409     if(m_leftSplitter == null) {
410       m_leftSplitter = (JSplitPane JavaDoc)findComponent("LeftSplitter");
411       m_leftDivLoc = new Integer JavaDoc(getSplitPref(m_leftSplitter));
412
413       if(m_dividerListener == null) {
414         m_dividerListener = new DividerListener();
415       }
416     }
417
418     return m_leftSplitter;
419   }
420
421   public void updateServerPrefs() {
422     XRootNode root = m_tree.getRootNode();
423     int count = root.getChildCount();
424     AdminClientContext acc = AdminClient.getContext();
425     PrefsHelper helper = PrefsHelper.getHelper();
426     Preferences JavaDoc prefs = acc.prefs.node("AdminClient");
427     Preferences JavaDoc serverPrefs = prefs.node(ServersHelper.SERVERS);
428     Preferences JavaDoc serverPref;
429     ServerNode serverNode;
430
431     helper.clearChildren(serverPrefs);
432
433     for(int i = 0; i < count; i++) {
434       serverNode = (ServerNode)root.getChildAt(i);
435       serverPref = serverPrefs.node("server-"+i);
436       serverNode.setPreferences(serverPref);
437     }
438
439     storePreferences();
440   }
441
442   public void disconnectAll() {
443     XRootNode root = m_tree.getRootNode();
444     int count = root.getChildCount();
445     ServerNode serverNode;
446
447     for(int i = 0; i < count; i++) {
448       serverNode = (ServerNode)root.getChildAt(i);
449
450       if(serverNode.isConnected()) {
451         serverNode.disconnectOnExit();
452       }
453     }
454
455     root.tearDown();
456     storePreferences();
457   }
458
459   class DividerListener implements PropertyChangeListener JavaDoc {
460     public void propertyChange(PropertyChangeEvent JavaDoc pce) {
461       JSplitPane JavaDoc splitter = (JSplitPane JavaDoc)pce.getSource();
462       String JavaDoc propName = pce.getPropertyName();
463
464       if(splitter.isShowing() == false ||
465          JSplitPane.DIVIDER_LOCATION_PROPERTY.equals(propName) == false)
466       {
467         return;
468       }
469
470       int divLoc = splitter.getDividerLocation();
471       Integer JavaDoc divLocObj = new Integer JavaDoc(divLoc);
472       Preferences JavaDoc prefs = getPreferences();
473       String JavaDoc name = splitter.getName();
474       Preferences JavaDoc node = prefs.node(name);
475
476       node.putInt("Split", divLoc);
477       storePreferences();
478
479       if(m_mainSplitter.getName().equals(name)) {
480         m_mainDivLoc = divLocObj;
481       }
482       else {
483         m_leftDivLoc = divLocObj;
484       }
485     }
486   }
487
488   public void doLayout() {
489     super.doLayout();
490
491     JSplitPane JavaDoc splitter = getMainSplitter();
492     if(m_mainDivLoc != null) {
493       splitter.setDividerLocation(m_mainDivLoc.intValue());
494     }
495     else {
496       splitter.setDividerLocation(0.7);
497     }
498
499     splitter = getLeftSplitter();
500     if(m_leftDivLoc != null) {
501       splitter.setDividerLocation(m_leftDivLoc.intValue());
502     }
503     else {
504       splitter.setDividerLocation(0.25);
505     }
506   }
507
508   public void log(String JavaDoc s) {
509     m_logArea.append(s+System.getProperty("line.separator"));
510     m_logArea.setCaretPosition(m_logArea.getDocument().getLength()-1);
511   }
512
513   public void log(Exception JavaDoc e) {
514     StringWriter JavaDoc sw = new StringWriter JavaDoc();
515     PrintWriter JavaDoc pw = new PrintWriter JavaDoc(sw);
516
517     e.printStackTrace(pw);
518     pw.close();
519
520     log(sw.toString());
521   }
522
523   public void setStatus(String JavaDoc msg) {
524     m_statusLine.setText(msg);
525   }
526
527   public void clearStatus() {
528     setStatus("");
529   }
530
531   public void addNotify() {
532     super.addNotify();
533
534     getMainSplitter().addPropertyChangeListener(m_dividerListener);
535     getLeftSplitter().addPropertyChangeListener(m_dividerListener);
536
537     // TODO: what's up with this in the plugin?
538
//m_tree.requestFocusInWindow();
539
}
540
541   public void removeNotify() {
542     getMainSplitter().removePropertyChangeListener(m_dividerListener);
543     getLeftSplitter().removePropertyChangeListener(m_dividerListener);
544
545     super.removeNotify();
546   }
547
548   class NewServerAction extends XAbstractAction {
549     NewServerAction() {
550       super(getBundleString("new.server.action.label"));
551     }
552
553     public void actionPerformed(ActionEvent JavaDoc ae) {
554       XTreeModel model = (XTreeModel)m_tree.getModel();
555       XTreeNode root = (XTreeNode)model.getRoot();
556       int index = root.getChildCount();
557       ServerNode serverNode = new ServerNode();
558
559       model.insertNodeInto(serverNode, root, index);
560       TreePath JavaDoc path = new TreePath JavaDoc(serverNode.getPath());
561       m_tree.makeVisible(path);
562       m_tree.setSelectionPath(path);
563       
564       AdminClientContext acc = AdminClient.getContext();
565       PrefsHelper helper = PrefsHelper.getHelper();
566       Preferences JavaDoc prefs = acc.prefs.node("AdminClient");
567       Preferences JavaDoc servers = prefs.node(ServersHelper.SERVERS);
568       int count = helper.childrenNames(servers).length;
569
570       serverNode.setPreferences(servers.node("server-"+count));
571       storePreferences();
572     }
573   }
574
575   class QuitAction extends XAbstractAction {
576     QuitAction() {
577       super(getBundleString("quit.action.label"));
578
579       setAccelerator(
580         KeyStroke.getKeyStroke(KeyEvent.VK_Q,
581                                MENU_SHORTCUT_KEY_MASK,
582                                true));
583     }
584
585     public void actionPerformed(ActionEvent JavaDoc ae) {
586       System.exit(0);
587     }
588   }
589
590   private java.awt.Frame JavaDoc getFrame() {
591     return (java.awt.Frame JavaDoc)
592       SwingUtilities.getAncestorOfClass(java.awt.Frame JavaDoc.class, this);
593   }
594   
595   protected boolean shouldAddAboutItem() {
596     return true;
597   }
598  
599   class UpdateCheckerAction extends XAbstractAction {
600     Dialog m_updateCheckerDialog;
601     ProductInfo m_productInfo;
602
603     UpdateCheckerAction() {
604       super(getBundleString("update-checker.action.label"));
605       Preferences JavaDoc updateCheckerPrefs = getUpdateCheckerPrefs();
606       boolean shouldCheck = updateCheckerPrefs.getBoolean("checking-enabled", true);
607       
608       Logger.getLogger("org.apache.commons.httpclient.HttpClient").setLevel(Level.OFF);
609       Logger.getLogger("org.apache.commons.httpclient.params.DefaultHttpParams").setLevel(Level.OFF);
610       Logger.getLogger("org.apache.commons.httpclient.methods.GetMethod").setLevel(Level.OFF);
611       Logger.getLogger("org.apache.commons.httpclient.HttpMethodDirector").setLevel(Level.OFF);
612       Logger.getLogger("org.apache.commons.httpclient.HttpConnection").setLevel(Level.OFF);
613       Logger.getLogger("org.apache.commons.httpclient.HttpMethodBase").setLevel(Level.OFF);
614       Logger.getLogger("org.apache.commons.httpclient.HttpState").setLevel(Level.OFF);
615       Logger.getLogger("org.apache.commons.httpclient.HttpParser").setLevel(Level.OFF);
616       Logger.getLogger("org.apache.commons.httpclient.cookie.CookieSpec").setLevel(Level.OFF);
617       Logger.getLogger("httpclient.wire.header").setLevel(Level.OFF);
618       Logger.getLogger("httpclient.wire.content").setLevel(Level.OFF);
619       
620       if(shouldCheck) {
621         long nextCheckTime = updateCheckerPrefs.getLong("next-check-time", 0L);
622         
623         if(nextCheckTime == 0L) {
624           updateCheckerPrefs.putLong("next-check-time", nextCheckTime());
625           storePreferences();
626         } else if(nextCheckTime < System.currentTimeMillis()) {
627           AdminClientPanel.this.addHierarchyListener(new HierarchyListener JavaDoc() {
628             public void hierarchyChanged(HierarchyEvent JavaDoc e) {
629               if((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0 &&
630                   AdminClientPanel.this.isDisplayable())
631               {
632                 AdminClientPanel.this.removeHierarchyListener(this);
633                 SwingUtilities.invokeLater(new Runnable JavaDoc() {
634                   public void run() {
635                     Timer JavaDoc t = new Timer JavaDoc(100, UpdateCheckerAction.this);
636                     t.setRepeats(false);
637                     t.start();
638                   }
639                 });
640               }
641             }
642           });
643         }
644       }
645     }
646     
647     Preferences JavaDoc getUpdateCheckerPrefs() {
648       return getPreferences().node("update-checker");
649     }
650     
651     public void actionPerformed(ActionEvent JavaDoc e) {
652       final Preferences JavaDoc updateCheckerPrefs = getUpdateCheckerPrefs();
653       final boolean promptForCheck = updateCheckerPrefs.getBoolean("prompt-for-check-enabled", true);
654       final Object JavaDoc src = e.getSource();
655       
656       if(promptForCheck || !(src instanceof Timer JavaDoc)) {
657         if(m_updateCheckerDialog == null) {
658           AdminClientContext acc = AdminClient.getContext();
659           java.awt.Frame JavaDoc frame = getFrame();
660   
661           m_updateCheckerDialog = frame != null ? new Dialog(frame) : new Dialog();
662           m_updateCheckerDialog.load((DialogResource)acc.topRes.child("UpdateCheckerDialog"));
663           
664           Button button = (Button)m_updateCheckerDialog.findComponent("EnableCheckingButton");
665           button.addActionListener(new ActionListener JavaDoc() {
666             public void actionPerformed(ActionEvent JavaDoc ae) {
667               updateCheckerPrefs.putBoolean("checking-enabled", true);
668               storePreferences();
669               UpdateCheckerAction.this.startUpdateCheck(true);
670               m_updateCheckerDialog.setVisible(false);
671             }
672           });
673           m_updateCheckerDialog.getRootPane().setDefaultButton(button);
674   
675           CheckBox promptForCheckToggle = (CheckBox)m_updateCheckerDialog.findComponent("PromptForCheckToggle");
676           promptForCheckToggle.addActionListener(new ActionListener JavaDoc() {
677             public void actionPerformed(ActionEvent JavaDoc ae) {
678               CheckBox cb = (CheckBox)ae.getSource();
679               updateCheckerPrefs.putBoolean("prompt-for-check-enabled", cb.isSelected());
680               storePreferences();
681             }
682           });
683           promptForCheckToggle.setSelected(updateCheckerPrefs.getBoolean("prompt-for-check-enabled", true));
684   
685           button = (Button)m_updateCheckerDialog.findComponent("DisableCheckingButton");
686           button.addActionListener(new ActionListener JavaDoc() {
687             public void actionPerformed(ActionEvent JavaDoc ae) {
688               updateCheckerPrefs.putBoolean("checking-enabled", false);
689               storePreferences();
690               m_updateCheckerDialog.setVisible(false);
691             }
692           });
693   
694           button = (Button)m_updateCheckerDialog.findComponent("CloseButton");
695           button.addActionListener(new ActionListener JavaDoc() {
696             public void actionPerformed(ActionEvent JavaDoc ae) {
697               m_updateCheckerDialog.setVisible(false);
698             }
699           });
700           Label lastCheckLabel = (Label)m_updateCheckerDialog.findComponent("LastCheckTimeLabel");
701           long lastCheckTime = updateCheckerPrefs.getLong("last-check-time", 0L);
702           if(lastCheckTime != 0L) {
703             lastCheckLabel.setText(formatBundleString("update-checker.last.checked.msg",
704                                                       new Date JavaDoc(lastCheckTime)));
705           }
706         }
707         
708         m_updateCheckerDialog.pack();
709         m_updateCheckerDialog.center(AdminClientPanel.this);
710         m_updateCheckerDialog.setVisible(true);
711       } else {
712         UpdateCheckerAction.this.startUpdateCheck(false);
713       }
714     }
715     
716     ProductInfo getProductInfo() {
717       if(m_productInfo == null) {
718         m_productInfo = new ProductInfo();
719       }
720       return m_productInfo;
721     }
722     
723     URL JavaDoc constructCheckURL() throws MalformedURLException JavaDoc {
724       String JavaDoc defaultPropsUrl = "http://www.terracotta.org/kit/reflector?kitID=default&pageID=update.properties";
725       String JavaDoc propsUrl = System.getProperty("terracotta.update-checker.url", defaultPropsUrl);
726       StringBuffer JavaDoc sb = new StringBuffer JavaDoc(propsUrl);
727       ProductInfo productInfo = getProductInfo();
728       
729       sb.append(defaultPropsUrl.equals(propsUrl) ? '&' : '?');
730
731       sb.append("os-name=");
732       sb.append(URLEncoder.encode(System.getProperty("os.name")));
733       sb.append("&jvm-name=");
734       sb.append(URLEncoder.encode(System.getProperty("java.vm.name")));
735       sb.append("&jvm-version=");
736       sb.append(URLEncoder.encode(System.getProperty("java.vm.version")));
737       sb.append("&platform=");
738       sb.append(URLEncoder.encode(System.getProperty("os.arch")));
739       sb.append("&tc-version=");
740       sb.append(URLEncoder.encode(productInfo.getVersion()));
741       sb.append("&tc-product=");
742       sb.append(productInfo.getLicense().equals(ProductInfo.DEFAULT_LICENSE) ? "oss" : "ee");
743       
744       return new URL JavaDoc(sb.toString());
745     }
746     
747     void showMessage(String JavaDoc msg) {
748       TextArea textArea = new TextArea();
749       textArea.setText(msg);
750       textArea.setRows(8);
751       textArea.setColumns(80);
752       textArea.setEditable(false);
753       ScrollPane scrollPane = new ScrollPane(textArea);
754       JOptionPane.showMessageDialog(AdminClientPanel.this, scrollPane,
755                                     getBundleString("update-checker.action.title"),
756                                     JOptionPane.INFORMATION_MESSAGE);
757     }
758     
759     public Properties JavaDoc getResponseBody(URL JavaDoc url, HttpClient client) throws ConnectException JavaDoc, IOException JavaDoc {
760       GetMethod get = new GetMethod(url.toString());
761
762       get.setFollowRedirects(true);
763       try {
764         int status = client.executeMethod(get);
765         if (status != HttpStatus.SC_OK) {
766           throw new ConnectException JavaDoc("The http client has encountered a status code other than ok for the url: " + url
767                                      + " status: " + HttpStatus.getStatusText(status));
768         }
769         Properties JavaDoc props = new Properties JavaDoc();
770         props.load(get.getResponseBodyAsStream());
771         return props;
772       } finally {
773         get.releaseConnection();
774       }
775     }
776
777     void startUpdateCheck(final boolean wasPrompted) {
778       Thread JavaDoc t = new Thread JavaDoc() {
779         public void run() {
780           InputStream JavaDoc is = null;
781           Object JavaDoc result = null;
782           String JavaDoc versionNotice = null;
783           
784           try {
785             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
786             String JavaDoc version = getProductInfo().getVersion();
787             if(version.indexOf('.') != -1) {
788               URL JavaDoc url = constructCheckURL();
789               HttpClient httpClient = new HttpClient();
790               Properties JavaDoc props = getResponseBody(url, httpClient);
791               
792               String JavaDoc propVal = props.getProperty("general.notice");
793               if(propVal != null && (propVal = propVal.trim()) != null && propVal.length() > 0) {
794                 showMessage(propVal);
795               }
796
797               propVal = props.getProperty(version+".notice");
798               if(propVal != null && (propVal = propVal.trim()) != null && propVal.length() > 0) {
799                 showMessage(propVal);
800               }
801               versionNotice = propVal;
802               
803               propVal = props.getProperty(version+".updates");
804               if(propVal != null && (propVal = propVal.trim()) != null && propVal.length() > 0) {
805                 sb.append("<ul>");
806                 StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(propVal, ",");
807                 while(st.hasMoreElements()) {
808                   sb.append("<li>");
809                   String JavaDoc newVersion = st.nextToken();
810                   sb.append(newVersion);
811   
812                   propVal = props.getProperty(newVersion+".release-notes");
813                   if(propVal != null && (propVal = propVal.trim()) != null && propVal.length() > 0) {
814                     sb.append(" -- <a HREF=\"");
815                     sb.append(propVal);
816                     sb.append("\">");
817                     sb.append(getBundleString("update-checker.release-notes.label"));
818                     sb.append("</a>");
819                   }
820                   sb.append("</li>\n");
821                 }
822                 sb.append("</ol>");
823               }
824             }
825             if(sb.length() > 0) {
826               sb.insert(0, "<html><body><p>"+getBundleString("update-checker.updates.available.msg")+"</p>");
827               sb.append("</body></html>");
828               TextPane textPane = new TextPane();
829               textPane.setEditable(false);
830               textPane.setContentType("text/html");
831               textPane.setBackground(null);
832               textPane.setText(sb.toString());
833               textPane.addHyperlinkListener(new HyperlinkListener JavaDoc() {
834                 public void hyperlinkUpdate(HyperlinkEvent JavaDoc e) {
835                   if(e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
836                     Element JavaDoc elem = e.getSourceElement();
837                     AttributeSet JavaDoc a = elem.getAttributes();
838                     AttributeSet JavaDoc anchor = (AttributeSet JavaDoc) a.getAttribute(HTML.Tag.A);
839                     String JavaDoc action = (String JavaDoc) anchor.getAttribute(HTML.Attribute.HREF);
840                     BrowserLauncher.openURL(action);
841                   }
842                 }
843               });
844               result = textPane;
845             } else if(wasPrompted && versionNotice == null) {
846               result = getBundleString("update-checker.current.msg");
847             }
848           } catch(Exception JavaDoc e) {
849             if(wasPrompted) {
850               result = getBundleString("update-checker.connect.failed.msg");
851             }
852           } finally {
853             IOUtils.closeQuietly(is);
854           }
855           UpdateCheckerAction.this.finishUpdateCheck(wasPrompted, result);
856         }
857       };
858       t.start();
859     }
860
861     void finishUpdateCheck(final boolean wasPrompted, final Object JavaDoc msg) {
862       if(msg != null) {
863         SwingUtilities.invokeLater(new Runnable JavaDoc() {
864           public void run() {
865             JOptionPane.showMessageDialog(AdminClientPanel.this, msg,
866                                           getBundleString("update-checker.action.title"),
867                                           JOptionPane.INFORMATION_MESSAGE);
868           }
869         });
870       }
871
872       final Preferences JavaDoc updateCheckerPrefs = getUpdateCheckerPrefs();
873       updateCheckerPrefs.putLong("next-check-time", nextCheckTime());
874       updateCheckerPrefs.putLong("last-check-time", System.currentTimeMillis());
875       storePreferences();
876     }
877     
878     long nextCheckTime() {
879       long currentTime = System.currentTimeMillis();
880       Long JavaDoc minutes = Long.getLong("terracotta.update-checker.next-check-minutes");
881       long nextCheckTime;
882       
883       if(minutes != null) {
884         nextCheckTime = currentTime+(minutes.longValue()*60*1000);
885       } else {
886         nextCheckTime = currentTime+(14*24*60*60*1000);
887       }
888
889       return nextCheckTime;
890     }
891   }
892   
893   class AboutAction extends XAbstractAction {
894     Dialog m_aboutDialog;
895     
896     AboutAction() {
897       super(getBundleString("about.action.label"));
898     }
899
900     public void actionPerformed(ActionEvent JavaDoc ae) {
901       if(m_aboutDialog == null) {
902         AdminClientContext acc = AdminClient.getContext();
903         java.awt.Frame JavaDoc frame = getFrame();
904
905         m_aboutDialog = frame != null ? new Dialog(frame) : new Dialog();
906         m_aboutDialog.load((DialogResource)acc.topRes.child("AboutDialog"));
907
908         AdminClientInfoPanel info;
909         String JavaDoc title = getBundleString("title");
910         info = (AdminClientInfoPanel)m_aboutDialog.findComponent("AdminClientInfoPanel");
911         info.init(title, new ProductInfo());
912         Label monikerLabel = (Label)m_aboutDialog.findComponent("MonikerLabel");
913         monikerLabel.setText(title);
914         Button okButton = (Button)m_aboutDialog.findComponent("OKButton");
915         m_aboutDialog.getRootPane().setDefaultButton(okButton);
916         okButton.addActionListener(new ActionListener JavaDoc() {
917           public void actionPerformed(ActionEvent JavaDoc ae2) {
918             m_aboutDialog.setVisible(false);
919           }
920         });
921       }
922
923       m_aboutDialog.pack();
924       m_aboutDialog.center(AdminClientPanel.this);
925       m_aboutDialog.setVisible(true);
926     }
927   }
928
929   public void addServerLog(ConnectionContext cc) {
930     ServerLog log = new ServerLog(cc);
931     JScrollPane JavaDoc scroller = new JScrollPane JavaDoc(log);
932     int index = m_bottomPane.getTabCount();
933
934     m_bottomPane.addTab(cc.toString(), (Icon JavaDoc)null, scroller, null);
935     m_bottomPane.setSelectedIndex(index);
936
937     LogDocumentListener ldl = new LogDocumentListener(log);
938     log.getDocument().addDocumentListener(ldl);
939     m_logListeners.add(ldl);
940   }
941
942   public void removeServerLog(ConnectionContext cc) {
943     JScrollPane JavaDoc scroller;
944     ServerLog log;
945     LogDocumentListener ldl;
946
947     for(int i = 1; i < m_bottomPane.getTabCount(); i++) {
948       scroller = (JScrollPane JavaDoc)m_bottomPane.getComponentAt(i);
949       log = (ServerLog)scroller.getViewport().getView();
950
951       if(cc.equals(log.getConnectionContext())) {
952         ldl = (LogDocumentListener)m_logListeners.remove(i);
953         log.getDocument().removeDocumentListener(ldl);
954         m_bottomPane.removeTabAt(i);
955
956         int index = m_bottomPane.getSelectedIndex();
957         m_bottomPane.setIconAt(index, null);
958
959         return;
960       }
961     }
962   }
963
964   class LogDocumentListener implements DocumentListener JavaDoc {
965     JTextComponent JavaDoc textComponent;
966
967     LogDocumentListener(JTextComponent JavaDoc textComponent) {
968       this.textComponent = textComponent;
969     }
970
971     public void insertUpdate(DocumentEvent JavaDoc e) {
972       int index = m_logListeners.indexOf(this);
973
974       if(!textComponent.isShowing() &&
975          m_bottomPane.getIconAt(index) == null)
976       {
977         m_bottomPane.setIconAt(index, m_infoIcon);
978       }
979     }
980
981     public void removeUpdate(DocumentEvent JavaDoc e) {/**/}
982     public void changedUpdate(DocumentEvent JavaDoc e) {/**/}
983   }
984   
985   public void block() {
986     /**/
987   }
988
989   public void unblock() {
990     /**/
991   }
992
993   public UndoManager JavaDoc getUndoManager() {
994     if(m_undoManager == null) {
995       m_undoManager = new MyUndoManager();
996     }
997
998     return m_undoManager;
999   }
1000
1001  class UndoAction extends XAbstractAction {
1002    public void actionPerformed(ActionEvent JavaDoc ae) {
1003      UndoManager JavaDoc undoMan = getUndoManager();
1004      UndoableEdit JavaDoc next = ((MyUndoManager)undoMan).nextUndoable();
1005
1006      if(next != null) {
1007        undoMan.undo();
1008        setStatus("Undid '"+next.getPresentationName()+"'");
1009      }
1010    }
1011
1012    public boolean isEnabled() {
1013      return getUndoManager().canUndo();
1014    }
1015  }
1016
1017  class RedoAction extends XAbstractAction {
1018    public void actionPerformed(ActionEvent JavaDoc ae) {
1019      UndoManager JavaDoc undoMan = getUndoManager();
1020      UndoableEdit JavaDoc next = ((MyUndoManager)undoMan).nextRedoable();
1021
1022      if(next != null) {
1023        undoMan.redo();
1024        setStatus("Redid '"+next.getPresentationName()+"'");
1025      }
1026    }
1027
1028    public boolean isEnabled() {
1029      return getUndoManager().canRedo();
1030    }
1031  }
1032
1033  class MyUndoManager extends UndoManager JavaDoc {
1034    public UndoableEdit JavaDoc nextUndoable() {
1035      return editToBeUndone();
1036    }
1037
1038    public UndoableEdit JavaDoc nextRedoable() {
1039      return editToBeRedone();
1040    }
1041  }
1042
1043  public String JavaDoc toString() {
1044    return getName();
1045  }
1046
1047  protected void addEdit(UndoableEdit JavaDoc edit) {
1048    getUndoManager().addEdit(edit);
1049  }
1050}
1051
Popular Tags