1 5 package com.tc.admin; 6 7 import org.dijon.AbstractTreeCellRenderer; 8 9 import com.tc.admin.common.ComponentNode; 10 import com.tc.admin.common.StatusView; 11 import com.tc.admin.common.XAbstractAction; 12 import com.tc.admin.common.XTreeNode; 13 import com.tc.admin.dso.DSOHelper; 14 import com.tc.admin.dso.DSONode; 15 import com.tc.config.schema.L2Info; 16 import com.tc.management.beans.L2MBeanNames; 17 18 import java.awt.Color ; 19 import java.awt.Frame ; 20 import java.awt.Graphics ; 21 import java.awt.event.ActionEvent ; 22 import java.awt.event.KeyEvent ; 23 import java.io.IOException ; 24 import java.lang.reflect.InvocationTargetException ; 25 import java.net.ConnectException ; 26 import java.net.UnknownHostException ; 27 import java.text.MessageFormat ; 28 import java.util.prefs.Preferences ; 29 30 import javax.management.MBeanServerNotification ; 31 import javax.management.Notification ; 32 import javax.management.NotificationListener ; 33 import javax.management.ObjectName ; 34 import javax.management.remote.JMXConnector ; 35 import javax.naming.CommunicationException ; 36 import javax.naming.ServiceUnavailableException ; 37 import javax.swing.Icon ; 38 import javax.swing.JCheckBoxMenuItem ; 39 import javax.swing.JComponent ; 40 import javax.swing.JPopupMenu ; 41 import javax.swing.JSeparator ; 42 import javax.swing.JTree ; 43 import javax.swing.KeyStroke ; 44 import javax.swing.SwingUtilities ; 45 46 51 52 public class ServerNode extends ComponentNode 53 implements ConnectionListener, 54 NotificationListener 55 { 56 private AdminClientContext m_acc; 57 private ServerConnectionManager m_connectManager; 58 private Exception m_connectException; 59 private ServerPanel m_serverPanel; 60 private ConnectDialog m_connectDialog; 61 private JPopupMenu m_popupMenu; 62 private ConnectAction m_connectAction; 63 private DisconnectAction m_disconnectAction; 64 private DeleteAction m_deleteAction; 65 private AutoConnectAction m_autoConnectAction; 66 private JCheckBoxMenuItem m_autoConnectMenuItem; 67 private ShutdownAction m_shutdownAction; 68 69 private static final String CONNECT_ACTION = "Connect"; 70 private static final String DISCONNECT_ACTION = "Disconnect"; 71 private static final String DELETE_ACTION = "Delete"; 72 private static final String AUTO_CONNECT_ACTION = "AutoConnect"; 73 74 private static final String HOST = ServersHelper.HOST; 75 private static final String PORT = ServersHelper.PORT; 76 private static final String AUTO_CONNECT = ServersHelper.AUTO_CONNECT; 77 78 ServerNode() { 79 this(ConnectionContext.DEFAULT_HOST, ConnectionContext.DEFAULT_PORT, ConnectionContext.DEFAULT_AUTO_CONNECT); 80 } 81 82 ServerNode(final String host, final int jmxPort, final boolean autoConnect) { 83 super(); 84 85 m_acc = AdminClient.getContext(); 86 setRenderer(new ServerNodeTreeCellRenderer()); 87 AutoConnectionListener acl = new AutoConnectionListener(); 88 m_connectManager = new ServerConnectionManager(host, jmxPort, autoConnect, acl); 89 if(autoConnect) { 90 String [] creds = ServerConnectionManager.getCachedCredentials(m_connectManager); 91 if(creds != null) { 92 m_connectManager.setCredentials(creds[0], creds[1]); 93 } 94 } 95 initMenu(autoConnect); 96 setComponent(m_serverPanel = new ServerPanel(this)); 97 } 98 99 103 private class AutoConnectionListener implements ConnectionListener { 104 public void handleConnection() { 105 if (m_connectManager != null) { 106 final boolean isConnected = m_connectManager.isConnected(); 107 108 if (SwingUtilities.isEventDispatchThread()) { 109 SwingUtilities.invokeLater(new Runnable () { 110 public void run() { 111 if (m_connectManager != null) { 112 setConnected(isConnected); 113 } 114 } 115 }); 116 } else { 117 try { 118 SwingUtilities.invokeAndWait(new Runnable () { 119 public void run() { 120 if (m_connectManager != null) { 121 setConnected(isConnected); 122 } 123 } 124 }); 125 } catch (InterruptedException ex) { 126 } catch (InvocationTargetException ite) { 127 m_acc.log(ite); 128 } 129 } 130 } 131 } 132 133 public void handleException() { 134 if (m_connectManager != null) { 135 final Exception e = m_connectManager.getConnectionException(); 136 137 if (SwingUtilities.isEventDispatchThread()) { 138 SwingUtilities.invokeLater(new Runnable () { 139 public void run() { 140 if (m_connectManager != null) { 141 reportConnectionException(e); 142 } 143 } 144 }); 145 } else { 146 try { 147 SwingUtilities.invokeAndWait(new Runnable () { 148 public void run() { 149 if (m_connectManager != null) { 150 reportConnectionException(e); 151 } 152 } 153 }); 154 } catch (InterruptedException ex) { 155 } catch (InvocationTargetException ite) { 156 m_acc.log(ite); 157 } 158 } 159 } 160 } 161 } 162 163 ServerConnectionManager getServerConnectionManager() { 164 return m_connectManager; 165 } 166 167 ConnectionContext getConnectionContext() { 168 return m_connectManager.getConnectionContext(); 169 } 170 171 void setHost(String host) { 172 m_connectManager.setHostname(host); 173 } 174 175 String getHost() { 176 return m_connectManager.getHostname(); 177 } 178 179 void setPort(int port) { 180 m_connectManager.setJMXPortNumber(port); 181 } 182 183 int getPort() { 184 return m_connectManager.getJMXPortNumber(); 185 } 186 187 private void initMenu(boolean autoConnect) { 188 m_popupMenu = new JPopupMenu ("Server Actions"); 189 190 m_connectAction = new ConnectAction(); 191 m_disconnectAction = new DisconnectAction(); 192 m_shutdownAction = new ShutdownAction(); 193 m_deleteAction = new DeleteAction(); 194 m_autoConnectAction = new AutoConnectAction(); 195 196 addActionBinding(CONNECT_ACTION, m_connectAction); 197 addActionBinding(DISCONNECT_ACTION, m_disconnectAction); 198 addActionBinding(DELETE_ACTION, m_deleteAction); 199 addActionBinding(AUTO_CONNECT_ACTION, m_autoConnectAction); 200 201 m_connectManager.addToggleAutoConnectListener(new ServerConnectionManager.AutoConnectListener() { 202 public void handleEvent() { 203 m_autoConnectMenuItem.setSelected(false); 204 Thread reActivator = new Thread () { 205 public void run() { 206 boolean ready = false; 207 try { 208 while (!ready) { 209 Thread.sleep(500); 210 if (m_serverPanel != null && m_serverPanel.getConnectButton() != null && m_acc.controller != null) { 211 ready = true; 212 } 213 } 214 } catch (InterruptedException e) { 215 try { 216 Thread.sleep(2000); 217 } catch (InterruptedException ie) { 218 ie.printStackTrace(); 219 System.exit(0); 220 } 222 } 223 m_serverPanel.getConnectButton().setEnabled(true); 224 m_acc.controller.updateServerPrefs(); 225 } 226 }; 227 reActivator.start(); 228 } 229 }); 230 231 m_popupMenu.add(m_connectAction); 232 m_popupMenu.add(m_disconnectAction); 233 m_popupMenu.add(new JSeparator ()); 234 m_popupMenu.add(m_deleteAction); 236 m_popupMenu.add(new JSeparator ()); 237 238 m_popupMenu.add(m_autoConnectMenuItem = new JCheckBoxMenuItem (m_autoConnectAction)); 239 m_autoConnectMenuItem.setSelected(autoConnect); 240 } 241 242 private void setConnected(boolean connected) { 243 if (m_acc == null) { return; } 244 if (connected) { 245 m_acc.controller.block(); 246 247 m_connectException = null; 248 if (m_connectManager.isActive()) { 249 handleActivation(); 250 } else if (m_connectManager.isStarted()) { 251 handleStarting(); 252 } 253 254 m_acc.controller.unblock(); 255 } else { 256 handleDisconnect(); 257 } 258 259 m_connectAction.setEnabled(!connected); 260 m_disconnectAction.setEnabled(connected); 261 } 262 263 boolean isConnected() { 264 return m_connectManager != null && m_connectManager.isConnected(); 265 } 266 267 boolean isStarted() { 268 return m_connectManager != null && m_connectManager.isStarted(); 269 } 270 271 boolean isActive() { 272 return m_connectManager != null && m_connectManager.isActive(); 273 } 274 275 boolean hasConnectionException() { 276 return m_connectException != null; 277 } 278 279 ConnectDialog getConnectDialog(ConnectionListener listener) { 280 if (m_connectDialog == null) { 281 Frame frame = (Frame ) m_serverPanel.getAncestorOfClass(java.awt.Frame .class); 282 m_connectDialog = new ConnectDialog(frame, m_connectManager, listener); 283 } else { 284 m_connectDialog.setServerConnectionManager(m_connectManager); 285 m_connectDialog.setConnectionListener(listener); 286 } 287 288 return m_connectDialog; 289 } 290 291 294 void connect() { 295 try { 296 beginConnect(); 297 } catch (Exception e) { 298 m_acc.controller.log(e); 299 } 300 } 301 302 private void beginConnect() throws Exception { 303 m_acc.controller.block(); 304 305 m_connectException = null; 306 307 ConnectDialog cd = getConnectDialog(this); 308 Frame frame = (Frame ) m_serverPanel.getAncestorOfClass(java.awt.Frame .class); 309 310 String [] creds = ServerConnectionManager.getCachedCredentials(getServerConnectionManager()); 311 if(creds != null) { 312 m_connectManager.setCredentials(creds[0], creds[1]); 313 } 314 315 cd.center(frame); 316 cd.setVisible(true); 317 } 318 319 322 public void handleConnection() { 323 JMXConnector jmxc; 324 if ((jmxc = m_connectDialog.getConnector()) != null) { 325 try { 326 m_connectManager.setJMXConnector(jmxc); 327 } catch (IOException ioe) { 328 reportConnectionException(ioe); 329 } 330 } 331 332 m_acc.controller.unblock(); 333 } 334 335 338 public void handleException() { 339 Exception e = m_connectDialog.getError(); 340 341 if (e != null) { 342 reportConnectionException(e); 343 } 344 345 m_acc.controller.unblock(); 346 } 347 348 public static String getConnectionExceptionString(Exception e, Object connectionObject) { 349 AdminClientContext acc = AdminClient.getContext(); 350 String msg = null; 351 352 if (e instanceof ServiceUnavailableException || e.getCause() instanceof ServiceUnavailableException ) { 353 String tmpl = acc.getMessage("service.unavailable"); 354 MessageFormat form = new MessageFormat (tmpl); 355 Object [] args = new Object [] { connectionObject }; 356 357 msg = form.format(args); 358 } else if (e.getCause() instanceof ConnectException ) { 359 String tmpl = acc.getMessage("cannot.connect.to"); 360 MessageFormat form = new MessageFormat (tmpl); 361 Object [] args = new Object [] { connectionObject }; 362 363 msg = form.format(args); 364 } else if (e.getCause() instanceof UnknownHostException 365 || (e.getCause() != null && e.getCause().getCause() instanceof java.rmi.UnknownHostException )) { 366 String tmpl = acc.getMessage("unknown.host"); 367 MessageFormat form = new MessageFormat (tmpl); 368 Object [] args = new Object [] { connectionObject }; 369 370 msg = form.format(args); 371 } else if (e.getCause() instanceof CommunicationException ) { 372 String tmpl = acc.getMessage("cannot.connect.to"); 373 MessageFormat form = new MessageFormat (tmpl); 374 Object [] args = new Object [] { connectionObject }; 375 376 msg = form.format(args); 377 378 } else { 379 msg = e.getMessage(); 380 } 381 382 return "<html>" + msg + "</html>"; 383 } 384 385 private void reportConnectionException(Exception e) { 386 String msg = getConnectionExceptionString(e, this); 387 388 m_connectException = e; 389 if (msg != null && m_serverPanel != null) { 390 m_serverPanel.setStatusLabel(msg); 391 } 392 m_acc.controller.nodeChanged(ServerNode.this); 393 } 394 395 398 void disconnect() { 399 String msg = m_acc.getMessage("disconnecting.from"); 400 MessageFormat form = new MessageFormat (msg); 401 Object [] args = new Object [] { this }; 402 403 m_acc.controller.setStatus(form.format(args)); 404 m_connectManager.setAutoConnect(false); 405 m_acc.controller.updateServerPrefs(); 406 m_autoConnectMenuItem.setSelected(false); 407 m_connectManager.setConnected(false); 408 } 409 410 void disconnectOnExit() { 411 String msg = m_acc.getMessage("disconnecting.from"); 412 MessageFormat form = new MessageFormat (msg); 413 Object [] args = new Object [] { this }; 414 415 m_acc.controller.setStatus(form.format(args)); 416 m_connectManager.disconnectOnExit(); 417 } 418 419 void shutdown() { 420 try { 421 ConnectionContext cntx = getConnectionContext(); 422 ObjectName serverInfo = getServerInfo(cntx); 423 424 cntx.invoke(serverInfo, "stop", new Object [] {}, new String [] {}); 425 } catch (Exception e) { 426 m_acc.log(e); 427 } 428 } 429 430 public Icon getIcon() { 431 return ServersHelper.getHelper().getServerIcon(); 432 } 433 434 public JPopupMenu getPopupMenu() { 435 return m_popupMenu; 436 } 437 438 public void setPreferences(Preferences prefs) { 439 prefs.put(HOST, getHost()); 440 prefs.putInt(PORT, getPort()); 441 prefs.putBoolean(AUTO_CONNECT, isAutoConnect()); 442 } 443 444 public String toString() { 445 return m_connectManager.toString(); 446 } 447 448 private class ConnectAction extends XAbstractAction { 449 ConnectAction() { 450 super("Connect", ServersHelper.getHelper().getConnectIcon()); 451 452 setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, MENU_SHORTCUT_KEY_MASK, true)); 453 } 454 455 public void actionPerformed(ActionEvent ae) { 456 connect(); 457 } 458 } 459 460 private class DisconnectAction extends XAbstractAction { 461 DisconnectAction() { 462 super("Disconnect", ServersHelper.getHelper().getDisconnectIcon()); 463 464 setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, MENU_SHORTCUT_KEY_MASK, true)); 465 setEnabled(false); 466 } 467 468 public void actionPerformed(ActionEvent ae) { 469 disconnect(); 470 } 471 } 472 473 private class ShutdownAction extends XAbstractAction { 474 ShutdownAction() { 475 super("Shutdown", ServersHelper.getHelper().getShutdownIcon()); 476 477 setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, MENU_SHORTCUT_KEY_MASK, true)); 478 setEnabled(false); 479 } 480 481 public void actionPerformed(ActionEvent ae) { 482 shutdown(); 483 } 484 } 485 486 private class DeleteAction extends XAbstractAction { 487 DeleteAction() { 488 super("Delete", ServersHelper.getHelper().getDeleteIcon()); 489 490 setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, MENU_SHORTCUT_KEY_MASK, true)); 491 } 492 493 public void actionPerformed(ActionEvent ae) { 494 if (isConnected()) { 495 disconnectOnExit(); 496 } 497 498 501 SwingUtilities.invokeLater(new Runnable () { 502 public void run() { 503 AdminClientController controller = m_acc.controller; 504 505 String name = ServerNode.this.toString(); 506 MessageFormat form = new MessageFormat (m_acc.getMessage("deleted.server")); 507 508 controller.setStatus(form.format(new Object [] { name })); 509 510 controller.remove(ServerNode.this); 512 513 controller.updateServerPrefs(); 516 } 517 }); 518 } 519 } 520 521 private class AutoConnectAction extends XAbstractAction { 522 AutoConnectAction() { 523 super("Auto-connect"); 524 setShortDescription("Attempt to connect automatically"); 525 } 526 527 public void actionPerformed(ActionEvent ae) { 528 JCheckBoxMenuItem menuitem = (JCheckBoxMenuItem ) ae.getSource(); 529 boolean autoConnect = menuitem.isSelected(); 530 531 if(autoConnect) { 532 String [] creds = ServerConnectionManager.getCachedCredentials(getServerConnectionManager()); 533 if(creds != null) { 534 m_connectManager.setCredentials(creds[0], creds[1]); 535 } 536 } 537 538 m_connectManager.setAutoConnect(autoConnect); 539 m_serverPanel.setupConnectButton(); 540 m_acc.controller.updateServerPrefs(); 541 } 542 } 543 544 boolean isAutoConnect() { 545 return m_connectManager.isAutoConnect(); 546 } 547 548 void handleStarting() { 549 m_acc.controller.nodeChanged(ServerNode.this); 550 m_serverPanel.started(); 551 m_shutdownAction.setEnabled(false); 552 } 553 554 void tryAddDSONode() { 555 if (getChildCount() == 0) { 556 ConnectionContext cntx = getConnectionContext(); 557 558 if (DSOHelper.getHelper().getDSOMBean(cntx) != null) { 559 DSONode dsoNode = null; 560 561 add(dsoNode = new DSONode(cntx)); 562 m_acc.controller.nodeStructureChanged(this); 563 m_acc.controller.expand(dsoNode); 564 } else { 565 try { 566 ObjectName mbsd = cntx.queryName("JMImplementation:type=MBeanServerDelegate"); 567 if(mbsd != null) { 568 try { 569 cntx.removeNotificationListener(mbsd, this); 570 } catch(Exception e) {} 571 cntx.addNotificationListener(mbsd, this); 572 } 573 } catch(Exception ioe) { 574 ioe.printStackTrace(); 575 } 576 } 577 } 578 m_acc.controller.nodeChanged(ServerNode.this); 579 } 580 581 static ObjectName getServerInfo(ConnectionContext cntx) throws Exception { 582 return ServerHelper.getHelper().getServerInfoMBean(cntx); 583 } 584 585 ProductInfo getProductInfo() { 586 ProductInfo info; 587 588 try { 589 info = getProductInfo(getConnectionContext()); 590 } catch (Exception e) { 591 m_acc.log(e); 592 info = new ProductInfo(); 593 } 594 595 return info; 596 } 597 598 public static ProductInfo getProductInfo(ConnectionContext cntx) throws Exception { 599 ObjectName serverInfo = getServerInfo(cntx); 600 601 String version = cntx.getStringAttribute(serverInfo, "Version"); 602 String buildID = cntx.getStringAttribute(serverInfo, "BuildID"); 603 String license = cntx.getStringAttribute(serverInfo, "DescriptionOfCapabilities"); 604 String copyright = cntx.getStringAttribute(serverInfo, "Copyright"); 605 606 return new ProductInfo(version, buildID, license, copyright); 607 } 608 609 long getStartTime() { 610 try { 611 ConnectionContext cntx = getConnectionContext(); 612 ObjectName serverInfo = getServerInfo(cntx); 613 614 return cntx.getLongAttribute(serverInfo, "StartTime"); 615 } catch (Exception e) { 616 m_acc.log(e); 617 return 0L; 618 } 619 } 620 621 long getActivateTime() { 622 try { 623 ConnectionContext cntx = getConnectionContext(); 624 ObjectName serverInfo = getServerInfo(cntx); 625 626 return cntx.getLongAttribute(serverInfo, "ActivateTime"); 627 } catch (Exception e) { 628 m_acc.log(e); 629 return 0L; 630 } 631 } 632 633 void handleActivation() { 634 tryAddDSONode(); 635 m_serverPanel.activated(); 636 m_shutdownAction.setEnabled(true); 637 } 638 639 public void handleNotification(Notification notification, Object handback) { 640 if(notification instanceof MBeanServerNotification ) { 641 MBeanServerNotification mbsn = (MBeanServerNotification )notification; 642 String type = notification.getType(); 643 ObjectName name = mbsn.getMBeanName(); 644 645 if(type.equals(MBeanServerNotification.REGISTRATION_NOTIFICATION)) { 646 if(name.getCanonicalName().equals(L2MBeanNames.DSO.getCanonicalName())) { 647 SwingUtilities.invokeLater(new Runnable () { 648 public void run() { 649 DSONode dsoNode = new DSONode(getConnectionContext()); 650 651 add(dsoNode); 652 m_acc.controller.nodeStructureChanged(ServerNode.this); 653 m_acc.controller.expand(dsoNode); 654 m_acc.controller.nodeChanged(ServerNode.this); 655 } 656 }); 657 } 658 } 659 } 660 } 661 662 L2Info[] getClusterMembers() { 663 ConnectionContext cc = getConnectionContext(); 664 L2Info[] result = null; 665 666 try { 667 result = (L2Info[]) cc.getAttribute(getServerInfo(cc), "L2Info"); 668 } catch (Exception e) { 669 m_acc.log(e); 670 } 671 672 return result != null ? result : new L2Info[0]; 673 } 674 675 void handleDisconnect() { 676 for (int i = getChildCount() - 1; i >= 0; i--) { 677 ((XTreeNode) getChildAt(i)).tearDown(); 678 remove(i); 679 } 680 681 m_serverPanel.disconnected(); 682 m_acc.controller.nodeStructureChanged(ServerNode.this); 683 m_acc.controller.select(this); 684 m_shutdownAction.setEnabled(false); 685 } 686 687 Color getServerStatusColor() { 688 return getServerStatusColor(getServerConnectionManager()); 689 } 690 691 static Color getServerStatusColor(ServerConnectionManager scm) { 692 if(scm != null) { 693 if (scm.isActive()) { 694 return Color.GREEN; 695 } else if (scm.isStarted()) { 696 return Color.YELLOW; 697 } else if (scm.getConnectionException() != null) { 698 return Color.RED; 699 } 700 } 701 return Color.LIGHT_GRAY; 702 } 703 704 private class ServerNodeTreeCellRenderer extends AbstractTreeCellRenderer { 705 protected StatusView m_statusView; 706 707 public ServerNodeTreeCellRenderer() { 708 super(); 709 710 m_statusView = new StatusView() { 711 public void setForeground(Color fg) { 712 super.setForeground(fg); 713 if (m_label != null) { 714 m_label.setForeground(fg); 715 } 716 } 717 718 public void paint(Graphics g) { 719 super.paint(g); 720 if (hasFocus) { 721 paintFocus(g, 0, 0, getWidth(), getHeight()); 722 } 723 } 724 }; 725 } 726 727 public JComponent getComponent() { 728 return m_statusView; 729 } 730 731 public void setValue(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean focused) { 732 m_statusView.setIndicator(ServerNode.this.getServerStatusColor()); 733 m_statusView.setLabel(value.toString()); 734 } 735 } 736 737 public void tearDown() { 738 if (m_connectDialog != null) { 739 m_connectDialog.tearDown(); 740 } 741 m_connectManager.tearDown(); 742 743 m_acc = null; 744 m_connectManager = null; 745 m_serverPanel = null; 746 m_connectDialog = null; 747 m_popupMenu = null; 748 m_connectAction = null; 749 m_disconnectAction = null; 750 m_shutdownAction = null; 751 m_deleteAction = null; 752 m_autoConnectAction = null; 753 754 super.tearDown(); 755 } 756 } 757 | Popular Tags |