1 5 package com.tc; 6 7 import org.apache.commons.io.FileUtils; 8 import org.apache.commons.io.IOUtils; 9 import org.apache.commons.lang.StringUtils; 10 import org.apache.xmlbeans.XmlError; 11 import org.dijon.Button; 12 import org.dijon.CheckBox; 13 import org.dijon.Container; 14 import org.dijon.ContainerResource; 15 import org.dijon.Dialog; 16 import org.dijon.DialogResource; 17 import org.dijon.DictionaryResource; 18 import org.dijon.EmptyBorder; 19 import org.dijon.Frame; 20 import org.dijon.Label; 21 import org.dijon.Menu; 22 import org.dijon.MenuBar; 23 import org.dijon.SplitPane; 24 import org.dijon.TabbedPane; 25 26 import com.tc.admin.ConnectionContext; 27 import com.tc.admin.ConnectionListener; 28 import com.tc.admin.ProductInfo; 29 import com.tc.admin.ServerConnectionManager; 30 import com.tc.admin.common.BrowserLauncher; 31 import com.tc.admin.common.ContactTerracottaAction; 32 import com.tc.admin.common.OutputStreamListener; 33 import com.tc.admin.common.XAbstractAction; 34 import com.tc.admin.common.XTree; 35 import com.tc.config.Directories; 36 import com.tc.management.beans.L2MBeanNames; 37 import com.tc.object.appevent.NonPortableEventContext; 38 import com.tc.object.appevent.NonPortableFieldSetContext; 39 import com.tc.object.appevent.NonPortableLogicalInvokeContext; 40 import com.tc.object.appevent.NonPortableObjectEvent; 41 import com.tc.servers.ServerSelection; 42 import com.tc.servers.ServersDialog; 43 import com.tc.util.NonPortableReason; 44 import com.tc.util.runtime.Os; 45 import com.terracottatech.config.DsoApplication; 46 import com.terracottatech.config.TcConfigDocument.TcConfig; 47 48 import java.awt.Color ; 49 import java.awt.Cursor ; 50 import java.awt.Dimension ; 51 import java.awt.GraphicsConfiguration ; 52 import java.awt.GraphicsDevice ; 53 import java.awt.GraphicsEnvironment ; 54 import java.awt.Insets ; 55 import java.awt.Rectangle ; 56 import java.awt.Toolkit ; 57 import java.awt.event.ActionEvent ; 58 import java.awt.event.ActionListener ; 59 import java.awt.event.ComponentAdapter ; 60 import java.awt.event.ComponentEvent ; 61 import java.awt.event.MouseAdapter ; 62 import java.awt.event.MouseEvent ; 63 import java.awt.event.MouseMotionAdapter ; 64 import java.awt.event.WindowAdapter ; 65 import java.awt.event.WindowEvent ; 66 import java.beans.PropertyChangeEvent ; 67 import java.beans.PropertyChangeListener ; 68 import java.io.File ; 69 import java.io.FileInputStream ; 70 import java.io.FileOutputStream ; 71 import java.io.IOException ; 72 import java.lang.reflect.Method ; 73 import java.net.Socket ; 74 import java.net.URL ; 75 import java.text.MessageFormat ; 76 import java.util.ArrayList ; 77 import java.util.Collection ; 78 import java.util.Enumeration ; 79 import java.util.HashMap ; 80 import java.util.Iterator ; 81 import java.util.List ; 82 import java.util.Map ; 83 import java.util.Properties ; 84 import java.util.prefs.Preferences ; 85 86 import javax.management.Notification ; 87 import javax.management.NotificationListener ; 88 import javax.management.ObjectName ; 89 import javax.swing.Icon ; 90 import javax.swing.ImageIcon ; 91 import javax.swing.JFileChooser ; 92 import javax.swing.JOptionPane ; 93 import javax.swing.JSplitPane ; 94 import javax.swing.SwingUtilities ; 95 import javax.swing.WindowConstants ; 96 import javax.swing.event.ChangeEvent ; 97 import javax.swing.event.ChangeListener ; 98 import javax.swing.event.DocumentEvent ; 99 import javax.swing.text.Document ; 100 import javax.swing.tree.TreePath ; 101 import javax.swing.tree.TreeSelectionModel ; 102 103 public class SessionIntegratorFrame extends Frame { 104 private static final boolean m_debug = Boolean.getBoolean("SessionIntegratorFrame.debug"); 105 106 private ConfigHelper m_configHelper; 107 private SplashDialog m_splashDialog; 108 109 private ServersDialog m_serversDialog; 110 private Properties m_properties; 111 private SplitPane m_controlSplitter; 112 private Integer m_controlDividerLocation; 113 private DividerListener m_dividerListener; 114 private TabbedPane m_tabbedPane; 115 private int m_lastSelectedTabIndex; 116 private WebAppTreeModel m_webAppTreeModel; 117 private Button m_startButton; 118 private Button m_stopButton; 119 private CheckBox m_dsoEnabledToggle; 120 private boolean m_dsoEnabled; 121 private XTree m_webAppTree; 122 private WebAppLinkNode m_lastArmedLink; 123 private TabbedPane m_configTabbedPane; 124 private ConfigTextPane m_xmlPane; 125 private XmlChangeListener m_xmlChangeListener; 126 private ConfigProblemTable m_configProblemTable; 127 private ConfigProblemTableModel m_configProblemTableModel; 128 129 private ProcessOutputView m_l2OutView; 130 private Label m_l2Label; 131 private ProcessStatus m_l2Status; 132 private boolean m_handlingAppEvent; 133 private L2StartupListener m_l2StartupListener; 134 private L2ShutdownListener m_l2ShutdownListener; 135 private L2ShutdownMonitor m_l2Monitor; 136 private L2ConnectListener m_l2ConnectListener; 137 private ServerConnectionManager m_l2ConnectManager; 138 139 private CheckBox m_webServer1EnabledToggle; 140 private boolean m_webServer1Enabled; 141 private ProcessOutputView m_webServer1OutView; 142 private Label m_webServer1Label; 143 private ProcessStatus m_webServer1Status; 144 private Button m_webServer1Control; 145 private WebServer1StartupListener m_webServer1StartupListener; 146 private WebServer1ShutdownListener m_webServer1ShutdownListener; 147 private WebServerShutdownMonitor m_webServer1Monitor; 148 149 private CheckBox m_webServer2EnabledToggle; 150 private boolean m_webServer2Enabled; 151 private ProcessOutputView m_webServer2OutView; 152 private Label m_webServer2Label; 153 private ProcessStatus m_webServer2Status; 154 private Button m_webServer2Control; 155 private WebServer2StartupListener m_webServer2StartupListener; 156 private WebServer2ShutdownListener m_webServer2ShutdownListener; 157 private WebServerShutdownMonitor m_webServer2Monitor; 158 159 private ImageIcon m_waitingIcon; 160 private ImageIcon m_readyIcon; 161 private ImageIcon m_stoppedIcon; 162 163 private Icon m_startIcon; 164 private Icon m_stopIcon; 165 166 private InstrumentedClassesPanel m_instrumentedClassesPanel; 167 private TransientFieldsPanel m_transientFieldsPanel; 168 private BootClassesPanel m_bootClassesPanel; 169 private ModulesPanel m_modulesPanel; 170 171 private ServersAction m_serversAction; 172 private ImportWebAppAction m_importAction; 173 private HelpAction m_helpAction; 174 175 private boolean m_askRestart; 176 private boolean m_restarting; 177 private boolean m_quitting; 178 179 private ServerSelection m_serverSelection; 180 181 private static String SHOW_SPLASH_PREF_KEY = "ShowSplash"; 182 private static String LAST_DIR_PREF_KEY = "LastDirectory"; 183 private static String DSO_ENABLED_PREF_KEY = "DsoEnabled"; 184 private static String WEBSERVER1_ENABLED_PREF_KEY = "WebServer1Enabled"; 185 private static String WEBSERVER2_ENABLED_PREF_KEY = "WebServer2Enabled"; 186 187 private static final String BAT_EXTENSION = ".bat"; 188 private static final String SH_EXTENSION = ".sh"; 189 private static final String SCRIPT_EXTENSION = getScriptExtension(); 190 private static final String FS = System.getProperty("file.separator"); 191 private static final String DEFAULT_TC_INSTALL_DIR = getDefaultInstallDir(); 192 private static final String TC_INSTALL_DIR = System.getProperty("tc.install.dir", 193 DEFAULT_TC_INSTALL_DIR); 194 private static final String DEFAULT_SANDBOX_ROOT = TC_INSTALL_DIR + FS + "tools" + FS + "sessions" + FS 195 + "configurator-sandbox"; 196 private static final String SANDBOX_ROOT = System.getProperty("configurator.sandbox", 197 DEFAULT_SANDBOX_ROOT); 198 private static final String L2_LABEL = "Terracotta Server"; 199 private static final String L2_STARTUP_SCRIPT = "start-tc-server" + SCRIPT_EXTENSION; 200 private static final String L2_SHUTDOWN_SCRIPT = "stop-tc-server" + SCRIPT_EXTENSION; 201 private static final String L2_STARTUP_TRIGGER = "Terracotta Server has started up"; 202 private static final int SERVER1_PORT = 9081; 203 private static final String WEBSERVER_STARTUP_SCRIPT = "start-web-server" + SCRIPT_EXTENSION; 204 private static final String WEBSERVER_SHUTDOWN_SCRIPT = "stop-web-server" + SCRIPT_EXTENSION; 205 private static final int SERVER2_PORT = 9082; 206 private static final String HELP_DOC = TC_INSTALL_DIR + FS + "docs" + FS 207 + "TerracottaSessionsQuickStart.html"; 208 209 private static final Cursor LINK_CURSOR = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); 210 private static final Cursor STANDARD_CURSOR = Cursor.getDefaultCursor(); 211 212 private static final int CONTROL_TAB_INDEX = 0; 213 private static final int CONFIG_TAB_INDEX = 1; 214 private static final int MONITOR_TAB_INDEX = 2; 215 216 private static final int XML_TAB_INDEX = 4; 217 private static final String XML_TAB_LABEL = "tc-config.xml"; 218 219 private static final String QUERY_START_MSG = "Start the system?"; 220 private static final String QUERY_RESTART_MSG = "Restart the system?"; 221 222 private static final String WAITING_LABEL = " [Waiting...]"; 223 private static final String STARTING_LABEL = " [Starting...]"; 224 private static final String STOPPING_LABEL = " [Stopping...]"; 225 private static final String READY_LABEL = " [Ready]"; 226 private static final String STOPPED_LABEL = " [Stopped]"; 227 private static final String FAILED_LABEL = " [Failed]"; 228 private static final String DISABLED_LABEL = " [Disabled]"; 229 230 public SessionIntegratorFrame() { 231 super(SessionIntegrator.getContext().topRes.getFrame("MainFrame")); 232 233 setTitle(getBundleString("title")); 234 setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 235 236 m_serverSelection = ServerSelection.getInstance(); 237 m_configHelper = new ConfigHelper(m_serverSelection); 238 239 initMenubar(); 240 loadIcons(); 241 242 m_tabbedPane = (TabbedPane) findComponent("MainTabbedPane"); 243 m_tabbedPane.addChangeListener(new ChangeListener () { 244 public void stateChanged(ChangeEvent e) { 245 if (m_lastSelectedTabIndex == CONFIG_TAB_INDEX && isXmlModified()) { 246 if (querySaveConfig(JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { 247 m_askRestart = isL2Ready(); 248 } 249 } 250 if (m_askRestart) { 251 String msg = "Configuration has been modified.\n\n" + QUERY_RESTART_MSG; 252 queryRestart(msg); 253 } 254 m_askRestart = false; 255 m_lastSelectedTabIndex = m_tabbedPane.getSelectedIndex(); 256 } 257 }); 258 259 m_startButton = (Button) findComponent("StartButton"); 260 m_startButton.addActionListener(new ActionListener () { 261 public void actionPerformed(ActionEvent ae) { 262 startSystem(); 263 } 264 }); 265 m_startIcon = m_startButton.getIcon(); 266 267 m_stopButton = (Button) findComponent("StopButton"); 268 m_stopButton.addActionListener(new ActionListener () { 269 public void actionPerformed(ActionEvent ae) { 270 stopSystem(); 271 } 272 }); 273 m_stopIcon = m_stopButton.getIcon(); 274 275 m_dsoEnabledToggle = (CheckBox) findComponent("DSOEnabledToggle"); 276 m_dsoEnabledToggle.addActionListener(new ActionListener () { 277 public void actionPerformed(ActionEvent ae) { 278 setDsoEnabled(m_dsoEnabledToggle.isSelected()); 279 } 280 }); 281 Preferences prefs = getPreferences(); 282 m_dsoEnabled = prefs.getBoolean(DSO_ENABLED_PREF_KEY, false); 283 m_dsoEnabledToggle.setSelected(m_dsoEnabled); 284 285 m_webAppTree = (XTree) findComponent("WebAppTree"); 286 m_webAppTreeModel = new WebAppTreeModel(this, getWebApps()); 287 m_webAppTree.setModel(m_webAppTreeModel); 288 m_webAppTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); 289 m_webAppTree.addMouseListener(new MouseAdapter () { 290 public void mouseClicked(MouseEvent me) { 291 if (me.getClickCount() == 1) { 292 TreePath path = m_webAppTree.getPathForLocation(me.getX(), me.getY()); 293 294 if (path != null) { 295 Object leaf = path.getLastPathComponent(); 296 297 if (leaf instanceof WebAppLinkNode) { 298 WebAppLinkNode node = (WebAppLinkNode) leaf; 299 300 if (node.isReady()) { 301 openPage(node.getLink()); 302 } 303 } 304 } 305 } 306 } 307 }); 308 m_webAppTree.addMouseMotionListener(new MouseMotionAdapter () { 309 public void mouseMoved(MouseEvent me) { 310 TreePath path = m_webAppTree.getPathForLocation(me.getX(), me.getY()); 311 312 if (path != null) { 313 Object leaf = path.getLastPathComponent(); 314 315 if (leaf instanceof WebAppLinkNode) { 316 WebAppLinkNode node = (WebAppLinkNode) leaf; 317 Cursor c = m_webAppTree.getCursor(); 318 319 if (m_lastArmedLink != node) { 320 if (m_lastArmedLink != null) { 321 m_lastArmedLink.setArmed(false); 322 } 323 node.setArmed(true); 324 m_lastArmedLink = node; 325 } 326 327 if (node.isReady() && c != LINK_CURSOR) { 328 m_webAppTree.setCursor(LINK_CURSOR); 329 } 330 return; 331 } 332 } 333 334 if (m_lastArmedLink != null) { 335 m_lastArmedLink.setArmed(false); 336 m_lastArmedLink = null; 337 } 338 339 m_webAppTree.setCursor(null); 340 } 341 }); 342 343 m_configTabbedPane = (TabbedPane) findComponent("ConfigTabbedPane"); 344 m_configProblemTable = (ConfigProblemTable) findComponent("ConfigProblemTable"); 345 m_configProblemTableModel = new ConfigProblemTableModel(); 346 m_configProblemTable.setModel(m_configProblemTableModel); 347 m_configProblemTable.addMouseListener(new MouseAdapter () { 348 public void mouseClicked(MouseEvent me) { 349 if (me.getClickCount() == 2) { 350 int row = m_configProblemTable.getSelectedRow(); 351 XmlError error = m_configProblemTableModel.getError(row); 352 353 m_xmlPane.selectError(error); 354 } 355 } 356 }); 357 358 m_xmlPane = (ConfigTextPane) findComponent("XMLPane"); 359 m_xmlChangeListener = new XmlChangeListener(); 360 initXmlPane(); 361 362 Container configPaneToolbar = (Container) findComponent("ConfigPaneToolbar"); 363 Button button; 364 Insets emptyInsets = new Insets (1,1,1,1); 365 button = (Button) configPaneToolbar.findComponent("SaveButton"); 366 button.setAction(m_xmlPane.getSaveAction()); 367 button.setText(null); 368 button.setMargin(emptyInsets); 369 button = (Button) configPaneToolbar.findComponent("UndoButton"); 370 button.setAction(m_xmlPane.getUndoAction()); 371 button.setText(null); 372 button.setMargin(emptyInsets); 373 button = (Button) configPaneToolbar.findComponent("RedoButton"); 374 button.setAction(m_xmlPane.getRedoAction()); 375 button.setText(null); 376 button.setMargin(emptyInsets); 377 378 button = (Button) configPaneToolbar.findComponent("CutButton"); 379 button.setAction(m_xmlPane.getCutAction()); 380 button.setText(null); 381 button.setMargin(emptyInsets); 382 button = (Button) configPaneToolbar.findComponent("CopyButton"); 383 button.setAction(m_xmlPane.getCopyAction()); 384 button.setText(null); 385 button.setMargin(emptyInsets); 386 button = (Button) configPaneToolbar.findComponent("PasteButton"); 387 button.setAction(m_xmlPane.getPasteAction()); 388 button.setText(null); 389 button.setMargin(emptyInsets); 390 391 m_l2OutView = (ProcessOutputView) findComponent("L2OutView"); 392 m_l2Label = (Label) findComponent("L2Label"); 393 m_l2Status = new ProcessStatus("L2"); 394 m_l2StartupListener = new L2StartupListener(); 395 m_l2ShutdownListener = new L2ShutdownListener(); 396 397 m_webServer1EnabledToggle = (CheckBox) findComponent("Tomcat1EnabledToggle"); 398 m_webServer1OutView = (ProcessOutputView) findComponent("Tomcat1OutView"); 399 m_webServer1Label = (Label) findComponent("Tomcat1Label"); 400 m_webServer1Status = new ProcessStatus(getWebServer1Label()); 401 m_webServer1Control = (Button) findComponent("Tomcat1Control"); 402 m_webServer1StartupListener = new WebServer1StartupListener(); 403 m_webServer1ShutdownListener = new WebServer1ShutdownListener(); 404 405 m_webServer1Enabled = prefs.getBoolean(WEBSERVER1_ENABLED_PREF_KEY, true); 406 m_webServer1EnabledToggle.setSelected(m_webServer1Enabled); 407 m_webServer1EnabledToggle.addActionListener(new ActionListener () { 408 public void actionPerformed(ActionEvent ae) { 409 setWebServer1Enabled(m_webServer1EnabledToggle.isSelected()); 410 } 411 }); 412 m_webServer1Label.setText(getWebServer1Label()); 413 m_webServer1Control.setMargin(new Insets (0, 0, 0, 0)); 414 m_webServer1Control.addActionListener(new ActionListener () { 415 public void actionPerformed(ActionEvent ae) { 416 disableControls(); 417 m_webAppTreeModel.updateLinks(false, isWebServer2Ready()); 418 toggleWebServer1(); 419 } 420 }); 421 422 m_webServer2EnabledToggle = (CheckBox) findComponent("Tomcat2EnabledToggle"); 423 m_webServer2OutView = (ProcessOutputView) findComponent("Tomcat2OutView"); 424 m_webServer2Label = (Label) findComponent("Tomcat2Label"); 425 m_webServer2Status = new ProcessStatus(getWebServer1Label()); 426 m_webServer2Control = (Button) findComponent("Tomcat2Control"); 427 m_webServer2StartupListener = new WebServer2StartupListener(); 428 m_webServer2ShutdownListener = new WebServer2ShutdownListener(); 429 430 m_webServer2Enabled = prefs.getBoolean(WEBSERVER2_ENABLED_PREF_KEY, true); 431 m_webServer2EnabledToggle.setSelected(m_webServer2Enabled); 432 m_webServer2EnabledToggle.addActionListener(new ActionListener () { 433 public void actionPerformed(ActionEvent ae) { 434 setWebServer2Enabled(m_webServer2EnabledToggle.isSelected()); 435 } 436 }); 437 m_webServer2Label.setText(getWebServer2Label()); 438 m_webServer2Control.setMargin(new Insets (0, 0, 0, 0)); 439 m_webServer2Control.addActionListener(new ActionListener () { 440 public void actionPerformed(ActionEvent ae) { 441 disableControls(); 442 m_webAppTreeModel.updateLinks(isWebServer1Ready(), false); 443 toggleWebServer2(); 444 } 445 }); 446 447 m_instrumentedClassesPanel = (InstrumentedClassesPanel) findComponent("InstrumentedClassesPanel"); 448 m_transientFieldsPanel = (TransientFieldsPanel) findComponent("TransientFieldsPanel"); 449 m_bootClassesPanel = (BootClassesPanel) findComponent("BootClassesPanel"); 450 m_modulesPanel = (ModulesPanel) findComponent("ModulesPanel"); 451 452 setupEditorPanels(); 453 454 m_startButton.setEnabled(isWebServer1Enabled() || isWebServer2Enabled() || isDsoEnabled()); 455 m_stopButton.setEnabled(isWebServer1Enabled() || isWebServer2Enabled() || isDsoEnabled()); 456 457 if (prefs.getBoolean(SHOW_SPLASH_PREF_KEY, true)) { 458 addComponentListener(new ComponentAdapter () { 459 public void componentShown(ComponentEvent e) { 460 openSplashDialog(this); 461 } 462 }); 463 } 464 465 addWindowListener(new WindowAdapter () { 466 public void windowClosing(WindowEvent we) { 467 quit(); 468 } 469 }); 470 471 m_l2ConnectListener = new L2ConnectListener(); 472 m_l2ConnectManager = new ServerConnectionManager("localhost", m_configHelper.getJmxPort(), false, 473 m_l2ConnectListener); 474 testShutdownL2(); 475 testShutdownWebServer1(); 476 testShutdownWebServer2(); 477 } 478 479 static String getBundleString(String key) { 480 return SessionIntegrator.getContext().getMessage(key); 481 } 482 483 static String formatBundleString(String key, Object [] args) { 484 return MessageFormat.format(getBundleString(key), args); 485 } 486 487 static String getTCInstallDir() { 488 return TC_INSTALL_DIR; 489 } 490 491 public static String getSandBoxRoot() { 492 return SANDBOX_ROOT; 493 } 494 495 ConfigHelper getConfigHelper() { 496 return m_configHelper; 497 } 498 499 private static String getScriptExtension() { 500 return Os.isWindows() ? BAT_EXTENSION : SH_EXTENSION; 501 } 502 503 private static String getDefaultInstallDir() { 504 try { 505 return Directories.getInstallationRoot().getAbsolutePath(); 506 } catch (Exception e) { 507 String msg = e.getMessage(); 508 String title = getBundleString("title"); 509 int msgType = JOptionPane.ERROR_MESSAGE; 510 511 JOptionPane.showMessageDialog(null, msg, title, msgType); 512 e.printStackTrace(); 513 System.exit(-1); 514 } 515 516 return null; 517 } 518 519 private void openSplashDialog(ComponentAdapter splashListener) { 520 DictionaryResource topRes = SessionIntegrator.getContext().topRes; 521 DialogResource dialogRes = topRes.getDialog("SplashDialog"); 522 523 m_splashDialog = new SplashDialog(this, true); 524 525 m_splashDialog.load(dialogRes); 526 ((Button) m_splashDialog.findComponent("HelpButton")).addActionListener(m_helpAction); 527 ((Button) m_splashDialog.findComponent("ImportButton")).addActionListener(m_importAction); 528 ((Button) m_splashDialog.findComponent("SkipButton")).addActionListener(new ActionListener () { 529 public void actionPerformed(ActionEvent ae) { 530 checkShowSplashToggle(); 531 m_splashDialog.setVisible(false); 532 } 533 }); 534 m_splashDialog.center(this); 535 m_splashDialog.addWindowListener(new WindowAdapter () { 536 public void windowClosed(WindowEvent we) { 537 checkShowSplashToggle(); 538 } 539 }); 540 if (splashListener != null) { 541 removeComponentListener(splashListener); 542 } 543 m_splashDialog.setVisible(true); 544 } 545 546 private void checkShowSplashToggle() { 547 if (m_splashDialog != null) { 548 CheckBox toggle = (CheckBox) m_splashDialog.findComponent("NoShowSplash"); 549 Preferences prefs = getPreferences(); 550 551 prefs.putBoolean(SHOW_SPLASH_PREF_KEY, !toggle.isSelected()); 552 storePreferences(); 553 } 554 } 555 556 private void loadIcons() { 557 URL url; 558 String iconsPrefix = "/com/tc/admin/icons/"; 559 Class clas = getClass(); 560 561 if ((url = clas.getResource(iconsPrefix + "progress_task_yellow.gif")) != null) { 562 m_waitingIcon = new ImageIcon (url); 563 } 564 565 if ((url = clas.getResource(iconsPrefix + "progress_task_green.gif")) != null) { 566 m_readyIcon = new ImageIcon (url); 567 } 568 569 if ((url = clas.getResource(iconsPrefix + "progress_task_red.gif")) != null) { 570 m_stoppedIcon = new ImageIcon (url); 571 } 572 } 573 574 private void initMenubar() { 575 MenuBar menuBar = new MenuBar(); 576 Menu menu = new Menu(getBundleString("file.menu.label")); 577 578 menu.add(m_serversAction = new ServersAction()); 579 580 menu.add(m_importAction = new ImportWebAppAction()); 581 menu.add(new ExportConfigurationAction()); 582 menu.add(new QuitAction()); 583 menuBar.add(menu); 584 585 menu = new Menu(getBundleString("output.menu.label")); 586 menu.add(new ClearOutputAction()); 587 menuBar.add(menu); 588 589 menu = new Menu(getBundleString("help.menu.label")); 590 menu.add(m_helpAction = new HelpAction()); 591 menu.add(new ShowSplashAction()); 592 menu.addSeparator(); 593 menu.add(new ContactTerracottaAction(getBundleString("visit.forums.title"), getBundleString("forums.url"))); 594 menu.add(new ContactTerracottaAction(getBundleString("contact.support.title"), getBundleString("support.url"))); 595 600 menu.addSeparator(); 601 menu.add(new AboutAction()); 602 menuBar.add(menu); 603 604 setMenubar(menuBar); 605 } 606 607 class ClearOutputAction extends XAbstractAction { 608 ClearOutputAction() { 609 super(getBundleString("clear.all.action.name")); 610 String uri = "/com/tc/admin/icons/clear_co.gif"; 611 setSmallIcon(new ImageIcon (getClass().getResource(uri))); 612 } 613 614 public void actionPerformed(ActionEvent e) { 615 m_l2OutView.setText(""); 616 m_webServer1OutView.setText(""); 617 m_webServer2OutView.setText(""); 618 } 619 } 620 621 class HelpAction extends XAbstractAction { 622 HelpAction() { 623 super(getBundleString("help.action.name")); 624 String uri = "/com/tc/admin/icons/help.gif"; 625 setSmallIcon(new ImageIcon (getClass().getResource(uri))); 626 } 627 628 public void actionPerformed(ActionEvent e) { 629 showHelp(); 630 } 631 } 632 633 class ShowSplashAction extends XAbstractAction { 634 ShowSplashAction() { 635 super(getBundleString("show.splash.action.name")); 636 } 637 638 public void actionPerformed(ActionEvent e) { 639 if (m_splashDialog != null) { 640 m_splashDialog.center(SessionIntegratorFrame.this); 641 m_splashDialog.setVisible(true); 642 } else { 643 openSplashDialog(null); 644 } 645 } 646 } 647 648 class AboutAction extends XAbstractAction { 649 Dialog m_aboutDialog; 650 651 AboutAction() { 652 super(getBundleString("about.action.label")); 653 } 654 655 public void actionPerformed(ActionEvent ae) { 656 if (m_aboutDialog == null) { 657 SessionIntegratorContext cntx = SessionIntegrator.getContext(); 658 659 m_aboutDialog = new Dialog(SessionIntegratorFrame.this, true); 660 m_aboutDialog.load((DialogResource) cntx.topRes.child("AboutDialog")); 661 662 ConfiguratorInfoPanel info; 663 String title = SessionIntegratorFrame.this.getTitle(); 664 info = (ConfiguratorInfoPanel) m_aboutDialog.findComponent("ConfiguratorInfoPanel"); 665 info.init(title, new ProductInfo()); 666 Label monikerLabel = (Label) m_aboutDialog.findComponent("MonikerLabel"); 667 monikerLabel.setText(title); 668 Button okButton = (Button) m_aboutDialog.findComponent("OKButton"); 669 m_aboutDialog.getRootPane().setDefaultButton(okButton); 670 okButton.addActionListener(new ActionListener () { 671 public void actionPerformed(ActionEvent ae2) { 672 m_aboutDialog.setVisible(false); 673 } 674 }); 675 } 676 677 m_aboutDialog.pack(); 678 m_aboutDialog.center(SessionIntegratorFrame.this); 679 m_aboutDialog.setVisible(true); 680 } 681 } 682 683 private void showHelp() { 684 try { 685 openPage("file://" + StringUtils.replace(HELP_DOC, FS, "/")); 686 } catch (Exception e) { 687 m_configHelper.openError(getBundleString("show.help.error"), e); 688 } 689 } 690 691 class ServersAction extends XAbstractAction { 692 ServersAction() { 693 super(getBundleString("servers.action.name")); 694 String uri = "/com/tc/admin/icons/thread_obj.gif"; 695 setSmallIcon(new ImageIcon (getClass().getResource(uri))); 696 } 697 698 public void actionPerformed(ActionEvent e) { 699 if (m_serversDialog == null) { 700 DialogResource dialogRes = SessionIntegrator.getContext().topRes.getDialog("ServersDialog"); 701 m_serversDialog = new ServersDialog(SessionIntegratorFrame.this); 702 m_serversDialog.load(dialogRes); 703 m_serversDialog.addAcceptListener(new ActionListener () { 704 public void actionPerformed(ActionEvent ae) { 705 int oldSelectedServerIndex = m_serverSelection.getSelectedServerIndex(); 706 m_serversDialog.finishEditing(); 707 m_serversDialog.setVisible(false); 708 m_serverSelection.setServers(m_serversDialog.getServers()); 709 m_serverSelection.setSelectedServerIndex(m_serversDialog.getSelectedServerIndex()); 710 711 m_webServer1Label.setText(getWebServer1Label()); 712 m_webServer2Label.setText(getWebServer2Label()); 713 714 if(oldSelectedServerIndex != m_serverSelection.getSelectedServerIndex()) { 716 m_webAppTreeModel = new WebAppTreeModel(SessionIntegratorFrame.this, getWebApps()); 717 m_webAppTree.setModel(m_webAppTreeModel); 718 } 719 720 WebApp[] webApps = getWebApps(); 722 for (int i = 0; i < webApps.length; i++) { 723 touch(webApps[i]); 724 } 725 726 m_configHelper = new ConfigHelper(m_serverSelection); 727 m_l2ConnectManager.setJMXPortNumber(m_configHelper.getJmxPort()); 728 initXmlPane(); 729 setupEditorPanels(); 730 } 731 }); 732 } 733 734 m_serversDialog.setSelection(m_serverSelection); 735 m_serversDialog.center(SessionIntegratorFrame.this); 736 m_serversDialog.setVisible(true); 737 m_serversDialog.toFront(); 738 } 739 740 } 741 742 class ImportWebAppAction extends XAbstractAction { 743 ImportWebAppAction() { 744 super(getBundleString("import.webapp.action.name")); 745 String uri = "/com/tc/admin/icons/import_wiz.gif"; 746 setSmallIcon(new ImageIcon (getClass().getResource(uri))); 747 } 748 749 public void actionPerformed(ActionEvent e) { 750 SwingUtilities.invokeLater(new Runnable () { 751 public void run() { 752 importWebApp(); 753 } 754 }); 755 } 756 } 757 758 void exportConfiguration() { 759 JFileChooser chooser = new JFileChooser (); 760 File currentDir = getLastDirectory(); 761 762 chooser.setMultiSelectionEnabled(false); 763 if (currentDir != null) { 764 chooser.setCurrentDirectory(currentDir); 765 } 766 767 int returnVal = chooser.showSaveDialog(this); 768 if (returnVal == JFileChooser.APPROVE_OPTION) { 769 File file = chooser.getSelectedFile(); 770 m_configHelper.saveAs(file, m_xmlPane.getText()); 771 } 772 } 773 774 class ExportConfigurationAction extends XAbstractAction { 775 ExportConfigurationAction() { 776 super(getBundleString("export.configuration.action.name")); 777 String uri = "/com/tc/admin/icons/export_wiz.gif"; 778 setSmallIcon(new ImageIcon (getClass().getResource(uri))); 779 } 780 781 public void actionPerformed(ActionEvent e) { 782 SwingUtilities.invokeLater(new Runnable () { 783 public void run() { 784 exportConfiguration(); 785 } 786 }); 787 } 788 } 789 790 class QuitAction extends XAbstractAction { 791 QuitAction() { 792 super(getBundleString("quit.action.name")); 793 } 794 795 public void actionPerformed(ActionEvent ae) { 796 quit(); 797 } 798 } 799 800 private void quit() { 801 if (m_quitting) { return; } 802 803 if (isXmlModified()) { 804 if (querySaveConfig() == JOptionPane.CANCEL_OPTION) { return; } 805 } 806 807 if (anyWaiting()) { 808 m_quitting = true; 809 showQuittingDialog(); 810 } else if (anyReady()) { 811 m_quitting = true; 812 showQuittingDialog(); 813 814 try { 815 m_webAppTreeModel.updateLinks(false, false); 816 disableControls(); 817 stopAll(); 818 } catch (Exception e) { 819 SessionIntegrator.getContext().client.shutdown(); 820 } 821 } else { 822 SessionIntegrator.getContext().client.shutdown(); 823 } 824 } 825 826 void showQuittingDialog() { 827 Dialog dialog = new Dialog(this, getTitle()); 828 Label label = new Label(getBundleString("quitting.dialog.msg")); 829 830 label.setBorder(new EmptyBorder(10, 20, 10, 20)); 831 dialog.getContentPane().add(label); 832 dialog.pack(); 833 dialog.center(this); 834 dialog.setVisible(true); 835 } 836 837 class XmlChangeListener extends DocumentAdapter { 838 public void insertUpdate(DocumentEvent e) { 839 setXmlModified(true); 840 } 841 842 public void removeUpdate(DocumentEvent e) { 843 setXmlModified(true); 844 } 845 } 846 847 private void setXmlModified(boolean xmlModified) { 848 m_xmlModified = xmlModified; 849 850 if (m_configTabbedPane != null) { 851 String label = XML_TAB_LABEL + (xmlModified ? "*" : ""); 852 m_configTabbedPane.setTitleAt(XML_TAB_INDEX, label); 853 } 854 } 855 856 private boolean m_xmlModified; 857 858 private boolean isXmlModified() { 859 return m_xmlModified; 860 } 861 862 private File getLastDirectory() { 863 String lastDir = getPreferences().get(LAST_DIR_PREF_KEY, null); 864 return lastDir != null ? new File (lastDir) : null; 865 } 866 867 private void setLastDirectory(File dir) { 868 getPreferences().put(LAST_DIR_PREF_KEY, dir.getAbsolutePath()); 869 storePreferences(); 870 } 871 872 private void importWebApp() { 873 JFileChooser chooser = new JFileChooser (); 874 File currentDir = getLastDirectory(); 875 876 chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); 877 chooser.setMultiSelectionEnabled(false); 878 chooser.setFileFilter(WebAppFileFilter.getInstance()); 879 if (currentDir != null) { 880 chooser.setCurrentDirectory(currentDir); 881 } 882 883 int returnVal = chooser.showOpenDialog(this); 884 if (returnVal == JFileChooser.APPROVE_OPTION) { 885 File file = chooser.getSelectedFile(); 886 887 setLastDirectory(chooser.getCurrentDirectory()); 888 if ((file.isDirectory() && !isWebAppDir(file)) || (file.isFile() && !file.getName().endsWith(".war"))) { 889 showPlainMessage(getBundleString("not.war.msg")); 890 return; 891 } 892 893 installWebApp(file); 894 } 895 } 896 897 private static boolean isWebAppDir(File dir) { 898 File webInf = new File (dir, "WEB-INF"); 899 return webInf.exists() && new File (webInf, "web.xml").exists(); 900 } 901 902 private com.tc.servers.ServerInfo getSelectedServer() { 903 return m_serverSelection.getSelectedServer(); 904 } 905 906 private String getSelectedServerName() { 907 return getSelectedServer().getName(); 908 } 909 910 private String getSelectedServerLabel() { 911 return getSelectedServer().getLabel(); 912 } 913 914 private String getSelectedServerStartupTrigger() { 915 return getSelectedServer().getStartupTrigger(); 916 } 917 918 private String getSelectedServerApplicationPath() { 919 return getSelectedServer().getApplicationPath(); 920 } 921 922 private Map getenv() { 923 try { 924 Method method = System .class.getMethod("getenv", new Class [] {}); 925 926 if (method != null) { return (Map ) method.invoke(null, new Object [] {}); } 927 } catch (Throwable e) { 928 } 929 930 return null; 931 } 932 933 private String [] getSelectedServerEnvironment() { 934 Map sysEnv = getenv(); 935 936 if (sysEnv != null) { 937 Map env = new HashMap (); 938 Properties serverEnv = getSelectedServer().toProperties(); 939 940 env.putAll(sysEnv); 941 env.putAll(serverEnv); 942 943 ArrayList list = new ArrayList (); 944 Iterator iter = env.keySet().iterator(); 945 String key; 946 String val; 947 948 while (iter.hasNext()) { 949 key = (String ) iter.next(); 950 val = (String ) env.get(key); 951 952 list.add(key + "=" + val); 953 } 954 955 try { 956 File tmpfile = File.createTempFile("terracotta", null); 957 list.add("TMPFILE=" + tmpfile.getAbsolutePath()); 958 tmpfile.delete(); 959 } catch (IOException ioe) { 960 ioe.printStackTrace(); 961 } 962 963 return (String []) list.toArray(new String [env.size()]); 964 } 965 966 return getSelectedServer().toEnvironment(); 967 } 968 969 private String getWebServer1Area() { 970 return SANDBOX_ROOT + FS + getSelectedServerName() + FS + SERVER1_PORT + FS + getSelectedServerApplicationPath(); 971 } 972 973 private String getWebServer2Area() { 974 return SANDBOX_ROOT + FS + getSelectedServerName() + FS + SERVER2_PORT + FS + getSelectedServerApplicationPath(); 975 } 976 977 private void installWebApp(File file) { 978 try { 979 boolean exists = new File (getWebServer1Area(), file.getName()).exists(); 980 981 installWebAppFile(file); 982 addToModel(file); 983 984 String msg = formatBundleString("install.webapp.success.msg", new Object [] { file }); 985 if (exists && anyReady()) { 986 String explainMsg = getBundleString("install.webapp.restart.msg"); 987 queryRestart(msg + "\n\n" + explainMsg + "\n\n" + QUERY_RESTART_MSG); 988 } else { 989 showPlainMessage(msg); 990 } 991 992 if (m_splashDialog != null) { 993 m_splashDialog.setVisible(false); 994 m_splashDialog = null; 995 } 996 } catch (Exception e) { 997 String msg = formatBundleString("install.webapp.failure.msg", new Object [] { file }); 998 m_configHelper.openError(msg, e); 999 } 1000 } 1001 1002 private void installWebAppFile(File file) throws Exception { 1003 String webServer1Area = getWebServer1Area(); 1004 String webServer2Area = getWebServer2Area(); 1005 1006 if (file.isFile()) { 1007 copyFileToDirectory(file, new File (webServer1Area), false); 1008 copyFileToDirectory(file, new File (webServer2Area), false); 1009 } else if (file.isDirectory()) { 1010 copyDirectory(file, new File (webServer1Area)); 1011 copyDirectory(file, new File (webServer2Area)); 1012 } 1013 } 1014 1015 private static void copyFileToDirectory(File file, File dir, boolean keepDate) throws IOException { 1016 if (dir.exists() && !dir.isDirectory()) { 1017 throw new IllegalArgumentException (getBundleString("destination.not.directory.msg")); 1018 } else { 1019 FileUtils.copyFile(file, new File (dir, file.getName()), keepDate); 1020 } 1021 } 1022 1023 private void removeWebApp(WebApp webApp) throws Exception { 1024 removeWebAppFile(webApp); 1025 removeFromModel(webApp); 1026 } 1027 1028 private void removeWebAppFile(WebApp webApp) throws Exception { 1029 File file = new File (webApp.getPath()); 1030 String fileName = file.getName(); 1031 String webServer1Area = getWebServer1Area(); 1032 String webServer2Area = getWebServer2Area(); 1033 1034 safeDeleteFile(new File (webServer1Area, fileName)); 1035 safeDeleteFile(new File (webServer2Area, fileName)); 1036 1037 if (fileName.endsWith(".war")) { 1038 String name = webApp.getName(); 1039 1040 safeDeleteFile(new File (webServer1Area, name)); 1041 safeDeleteFile(new File (webServer2Area, name)); 1042 } 1043 } 1044 1045 private static void safeDeleteFile(File file) { 1046 if (file.exists()) { 1047 try { 1048 FileUtils.forceDelete(file); 1049 } catch (IOException ioe) { 1050 } 1051 } 1052 } 1053 1054 private static void safeCloseSocket(Socket socket) { 1055 try { 1056 socket.close(); 1057 } catch (Exception e) { 1058 } 1059 } 1060 1061 void refresh(WebApp webApp) { 1062 File srcFile = new File (webApp.getPath()); 1063 1064 if (!srcFile.exists()) { 1065 Object [] args = { webApp.getName(), srcFile.getAbsolutePath() }; 1066 String msg = formatBundleString("src.webapp.not.found.msg", args); 1067 int type = JOptionPane.YES_NO_OPTION; 1068 int answer = showConfirmDialog(msg, type); 1069 1070 if (answer == JOptionPane.YES_OPTION) { 1071 remove(webApp); 1072 } 1073 } else { 1074 try { 1075 removeWebAppFile(webApp); 1076 installWebAppFile(srcFile); 1077 1078 String msg = formatBundleString("refresh.success.msg", new Object [] { webApp.getPath() }); 1079 queryRestart(msg + "\n\n" + (anyReady() ? QUERY_RESTART_MSG : QUERY_START_MSG)); 1080 } catch (Exception e) { 1081 String msg = formatBundleString("refresh.failure.msg", new Object [] { webApp }); 1082 m_configHelper.openError(msg, e); 1083 } 1084 } 1085 } 1086 1087 1092 void touch(WebApp webApp) { 1093 long time = System.currentTimeMillis(); 1094 String [] serverAreas = new String [] { getWebServer1Area(), getWebServer2Area() }; 1095 1096 for (int j = 0; j < serverAreas.length; j++) { 1097 File destFile = new File (serverAreas[j], webApp.getName()); 1098 1099 if (!destFile.isDirectory()) { 1100 destFile.setLastModified(time); 1101 } else { 1102 Collection fileSet = FileUtils.listFiles(destFile, new String [] { "jsp" }, true); 1103 File [] files = FileUtils.convertFileCollectionToFileArray(fileSet); 1104 1105 for (int i = 0; i < files.length; i++) { 1106 files[i].setLastModified(time); 1107 } 1108 } 1109 } 1110 } 1111 1112 void remove(WebApp webApp) { 1113 if (anyReady()) { 1114 showPlainMessage(getBundleString("cannot.remove.while.running.msg")); 1115 } else { 1116 try { 1117 removeWebApp(webApp); 1118 1119 File srcFile = new File (webApp.getPath()); 1120 String msg = formatBundleString("remove.success.msg", new Object [] { srcFile.getAbsolutePath() }); 1121 showPlainMessage(msg); 1122 } catch (Exception e) { 1123 String msg = formatBundleString("remove.failure.msg", new Object [] { webApp }); 1124 m_configHelper.openError(msg, e); 1125 } 1126 } 1127 } 1128 1129 private static void copyDirectory(File fromDir, File toDir) throws Exception { 1130 File destDir = new File (toDir, fromDir.getName()); 1131 1132 if (destDir.exists()) { 1133 FileUtils.cleanDirectory(destDir); 1134 } 1135 1136 Collection fileSet = FileUtils.listFiles(fromDir, null, true); 1137 File [] files = FileUtils.convertFileCollectionToFileArray(fileSet); 1138 String prefix = fromDir.getAbsolutePath() + FS; 1139 int prefixLen = prefix.length(); 1140 String relPath; 1141 1142 for (int i = 0; i < files.length; i++) { 1143 relPath = files[i].getAbsolutePath().substring(prefixLen); 1144 FileUtils.copyFile(files[i], new File (destDir, relPath)); 1145 } 1146 } 1147 1148 private void addToModel(File file) throws Exception { 1149 String name = file.getName(); 1150 String path = file.getAbsolutePath(); 1151 int dot = name.lastIndexOf('.'); 1152 1153 if (dot != -1) { 1154 name = name.substring(0, dot); 1155 } 1156 1157 path = StringUtils.replace(path, FS, "/"); 1158 m_properties.setProperty(name, path); 1159 1160 File webAppProps = m_serverSelection.getSelectedServerWebAppProperties(); 1161 FileOutputStream out = new FileOutputStream (webAppProps); 1162 Exception err = null; 1163 1164 try { 1165 m_properties.store(out, null); 1166 1167 WebAppNode webAppNode = m_webAppTreeModel.add(new WebApp(name, path)); 1168 TreePath webAppPath = new TreePath (webAppNode.getPath()); 1169 1170 m_webAppTree.expandPath(webAppPath); 1171 m_webAppTree.setSelectionPath(webAppPath); 1172 1173 if (m_configHelper.ensureWebApplication(name)) { 1174 m_configHelper.save(); 1175 initXmlPane(); 1176 } 1177 } catch (Exception e) { 1178 err = e; 1179 } finally { 1180 IOUtils.closeQuietly(out); 1181 } 1182 1183 if (err != null) { throw err; } 1184 } 1185 1186 private void removeFromModel(WebApp webApp) throws Exception { 1187 File file = new File (webApp.getPath()); 1188 String name = file.getName(); 1189 int dot = name.lastIndexOf('.'); 1190 1191 if (dot != -1) { 1192 name = name.substring(0, dot); 1193 } 1194 1195 m_properties.remove(name); 1196 1197 File webAppProps = m_serverSelection.getSelectedServerWebAppProperties(); 1198 FileOutputStream out = new FileOutputStream (webAppProps); 1199 Exception err = null; 1200 1201 try { 1202 m_properties.store(out, null); 1203 m_webAppTreeModel.remove(name); 1204 if (m_configHelper.removeWebApplication(name)) { 1205 m_configHelper.save(); 1206 initXmlPane(); 1207 } 1208 } catch (Exception e) { 1209 err = e; 1210 } finally { 1211 IOUtils.closeQuietly(out); 1212 } 1213 1214 if (err != null) { throw err; } 1215 } 1216 1217 private boolean isDsoEnabled() { 1218 return m_dsoEnabled; 1219 } 1220 1221 private void setDsoEnabled(boolean enabled) { 1222 getPreferences().putBoolean(DSO_ENABLED_PREF_KEY, m_dsoEnabled = enabled); 1223 storePreferences(); 1224 1225 m_l2Label.setIcon(null); 1226 m_l2Label.setText(L2_LABEL + (enabled ? "" : DISABLED_LABEL)); 1227 m_l2Label.setEnabled(m_dsoEnabled); 1228 m_l2OutView.setEnabled(m_dsoEnabled); 1229 1230 setMonitorTabEnabled(enabled); 1231 1232 m_startButton.setEnabled(enabled || isWebServer1Enabled() || isWebServer2Enabled()); 1233 1234 if (isL2Ready()) { 1235 queryRestart(); 1236 } 1237 } 1238 1239 private void selectControlTab() { 1240 m_tabbedPane.setSelectedIndex(CONTROL_TAB_INDEX); 1241 } 1242 1243 private boolean isConfigTabSelected() { 1244 return (m_tabbedPane.getSelectedIndex() == CONFIG_TAB_INDEX); 1245 } 1246 1247 private void setConfigTabEnabled(boolean enabled) { 1248 m_tabbedPane.setEnabledAt(CONFIG_TAB_INDEX, enabled); 1249 } 1250 1251 private void setConfigTabForeground(Color fg) { 1252 m_tabbedPane.setForegroundAt(CONFIG_TAB_INDEX, fg); 1253 } 1254 1255 private void setMonitorTabEnabled(boolean enabled) { 1256 m_tabbedPane.setEnabledAt(MONITOR_TAB_INDEX, enabled); 1257 } 1258 1259 private int querySaveConfig() { 1260 return querySaveConfig(JOptionPane.YES_NO_CANCEL_OPTION); 1261 } 1262 1263 private int querySaveConfig(int msgType) { 1264 String msg = getBundleString("query.save.config.msg"); 1265 int answer = showConfirmDialog(msg, msgType); 1266 1267 if (answer == JOptionPane.YES_OPTION) { 1268 saveConfig(); 1269 } 1270 1271 return answer; 1272 } 1273 1274 private int queryRestart() { 1275 return queryRestart(QUERY_RESTART_MSG); 1276 } 1277 1278 private int queryRestart(String msg) { 1279 int type = JOptionPane.YES_NO_OPTION; 1280 int answer = showConfirmDialog(msg, type); 1281 1282 if (answer == JOptionPane.YES_OPTION) { 1283 m_startButton.doClick(); 1284 } 1285 1286 return answer; 1287 } 1288 1289 private WebApp[] getWebApps() { 1290 File webAppProps = m_serverSelection.getSelectedServerWebAppProperties(); 1291 1292 m_properties = new Properties (); 1293 1294 try { 1295 m_properties.load(new FileInputStream (webAppProps)); 1296 } catch (IOException ioe) { 1297 m_properties.setProperty("Cart", ""); 1298 m_properties.setProperty("DepartmentTaskList", ""); 1299 m_properties.setProperty("Townsend", ""); 1300 } 1301 1302 Enumeration names = m_properties.keys(); 1303 ArrayList appList = new ArrayList (); 1304 String name; 1305 1306 while (names.hasMoreElements()) { 1307 name = (String ) names.nextElement(); 1308 appList.add(new WebApp(name, m_properties.getProperty(name))); 1309 } 1310 1311 return WebAppComparable.sort((WebApp[]) appList.toArray(new WebApp[0])); 1312 } 1313 1314 private void setupEditorPanels() { 1315 try { 1316 TcConfig config = m_configHelper.getConfig(); 1317 1318 if (config == null) { 1319 config = m_configHelper.ensureConfig(); 1320 m_configHelper.save(); 1321 setXmlModified(false); 1322 } 1323 1324 DsoApplication dsoApp = config.getApplication().getDso(); 1325 1326 m_instrumentedClassesPanel.setup(dsoApp); 1327 m_transientFieldsPanel.setup(dsoApp); 1328 m_bootClassesPanel.setup(dsoApp); 1329 m_modulesPanel.setup(config.getClients()); 1330 } catch (Exception e) { 1331 m_configHelper.openError(getBundleString("configuration.load.failure.msg"), e); 1332 } 1333 } 1334 1335 private void initXmlPane() { 1336 Document xmlDocument = m_xmlPane.getDocument(); 1337 1338 xmlDocument.removeDocumentListener(m_xmlChangeListener); 1339 m_xmlPane.load(m_configHelper.getConfigFilePath()); 1340 xmlDocument.addDocumentListener(m_xmlChangeListener); 1341 setXmlModified(false); 1342 } 1343 1344 private void updateXmlPane() { 1345 Document xmlDocument = m_xmlPane.getDocument(); 1346 1347 xmlDocument.removeDocumentListener(m_xmlChangeListener); 1348 m_xmlPane.set(m_configHelper.getConfigText()); 1349 xmlDocument.addDocumentListener(m_xmlChangeListener); 1350 setXmlModified(true); 1351 } 1352 1353 void setConfigErrors(List errorList) { 1354 m_configProblemTableModel.setErrors(errorList); 1355 setConfigTabForeground(errorList.size() > 0 ? Color.RED : null); 1356 } 1357 1358 public static void openPath(String path) throws IOException { 1359 if (Os.isWindows()) { 1360 String [] cmd = { "cmd.exe", "/C", path }; 1361 Runtime.getRuntime().exec(cmd); 1362 } else { 1363 openPage(path); 1364 } 1365 } 1366 1367 public static void openPage(String page) { 1368 BrowserLauncher.openURL(page); 1369 } 1370 1371 private void startSystem() { 1372 try { 1373 if (isXmlModified()) { 1374 if (querySaveConfig() == JOptionPane.CANCEL_OPTION) { return; } 1375 } 1376 m_webAppTreeModel.updateLinks(false, false); 1377 disableControls(); 1378 startAll(); 1379 } catch (Exception e) { 1380 e.printStackTrace(); 1381 } 1382 } 1383 1384 private void startAll() throws Exception { 1385 m_restarting = anyReady(); 1386 startServers(); 1387 } 1388 1389 private void startServers() { 1390 trace("startServers"); 1391 1392 m_l2Label.setIcon(m_l2Status.isReady() ? m_waitingIcon : null); 1393 1394 if (m_restarting) { 1395 if (isL2Ready()) { 1396 m_l2Label.setIcon(m_waitingIcon); 1397 m_l2Label.setText(L2_LABEL + WAITING_LABEL); 1398 1399 if (m_webServer1Status.isReady() || m_webServer2Status.isReady()) { 1400 stopWebServers(); 1401 } else { 1402 startL2(); 1403 } 1404 } else { 1405 startWebServers(); 1406 } 1407 } else { 1408 if (isDsoEnabled()) { 1409 if (isWebServer1Enabled()) { 1410 m_webServer1Label.setIcon(m_waitingIcon); 1411 m_webServer1Label.setText(getWebServer1Label() + WAITING_LABEL); 1412 } 1413 if (isWebServer2Enabled()) { 1414 m_webServer2Label.setIcon(m_waitingIcon); 1415 m_webServer2Label.setText(getWebServer2Label() + WAITING_LABEL); 1416 } 1417 startL2(); 1418 } else { 1419 startWebServers(); 1420 } 1421 } 1422 } 1423 1424 private boolean isWebServer1Enabled() { 1425 return m_webServer1Enabled; 1426 } 1427 1428 private void setWebServer1Enabled(boolean enabled) { 1429 getPreferences().putBoolean(WEBSERVER1_ENABLED_PREF_KEY, m_webServer1Enabled = enabled); 1430 storePreferences(); 1431 1432 m_startButton.setEnabled(enabled || isWebServer2Enabled() || isDsoEnabled()); 1433 } 1434 1435 private boolean isWebServer2Enabled() { 1436 return m_webServer2Enabled; 1437 } 1438 1439 private void setWebServer2Enabled(boolean enabled) { 1440 getPreferences().putBoolean(WEBSERVER2_ENABLED_PREF_KEY, m_webServer2Enabled = enabled); 1441 storePreferences(); 1442 1443 m_startButton.setEnabled(enabled || isWebServer1Enabled() || isDsoEnabled()); 1444 } 1445 1446 private String getWebServer1Label() { 1447 return getSelectedServerLabel() + "-" + SERVER1_PORT; 1448 } 1449 1450 private String getWebServer2Label() { 1451 return getSelectedServerLabel() + "-" + SERVER2_PORT; 1452 } 1453 1454 private void startWebServers() { 1455 if (isWebServer1Enabled()) { 1456 startWebServer1(); 1457 } 1458 if (isWebServer2Enabled()) { 1459 startWebServer2(); 1460 } 1461 } 1462 1463 private void stopWebServers() { 1464 trace("stopWebServers"); 1465 1466 if (isWebServer1Ready()) { 1467 stopWebServer1(); 1468 } 1469 if (isWebServer2Ready()) { 1470 stopWebServer2(); 1471 } 1472 } 1473 1474 1476 private boolean isL2Accessible() { 1477 try { 1478 if (m_l2ConnectManager.testIsConnected()) { return true; } 1479 } catch (Exception e) { 1480 } 1481 1482 return false; 1483 } 1484 1485 private void testShutdownL2() { 1486 if (isL2Accessible()) { 1487 stopL2(); 1488 } 1489 } 1490 1491 private void startL2() { 1492 trace("startL2"); 1493 1494 if (m_l2Monitor != null) { 1495 m_l2Monitor.cancel(); 1496 while (true) { 1497 try { 1498 m_l2Monitor.join(0); 1499 break; 1500 } catch (InterruptedException ie) { 1501 } 1502 } 1503 m_l2Monitor = null; 1504 } 1505 1506 if (isL2Ready()) { 1507 m_l2Status.setRestarting(true); 1508 restartL2(); 1509 return; 1510 } 1511 1512 if (isDsoEnabled()) { 1513 _startL2(); 1514 } 1515 } 1516 1517 private void _startL2() { 1518 trace("_startL2"); 1519 1520 m_l2Status.setWaiting(); 1521 m_l2Label.setIcon(m_waitingIcon); 1522 m_l2Label.setText(L2_LABEL + STARTING_LABEL); 1523 m_l2OutView.setListener(m_l2StartupListener); 1524 m_l2OutView.setListenerTrigger(L2_STARTUP_TRIGGER); 1525 startL2AndNotify(L2_STARTUP_SCRIPT, m_l2OutView, m_l2StartupListener); 1526 } 1527 1528 private void startL2AndNotify(final String startScript, final ProcessOutputView outView, 1529 final StartupListener startupListener) { 1530 trace("Starting L2"); 1531 1532 Process process; 1533 try { 1534 process = invokeScript(startScript, new String [] { getSelectedServerName() }); 1535 IOUtils.closeQuietly(process.getOutputStream()); 1536 new ProcessMonitor(process, new ProcessTerminationListener() { 1537 public void processTerminated(int exitCode) { 1538 if (m_debug) { 1539 outView.append("L2 terminated with exitCode=" + exitCode); 1540 } 1541 if (exitCode != 0) { 1542 SwingUtilities.invokeLater(new Runnable () { 1543 public void run() { 1544 startupListener.processFailed(); 1545 } 1546 }); 1547 } 1548 } 1549 }); 1550 } catch (Exception e) { 1551 startupListener.startupError(e); 1552 return; 1553 } 1554 1555 m_l2OutView.start(process); 1556 1557 new L2StartupMonitor(process, startupListener).start(); 1558 } 1559 1560 class L2StartupMonitor extends Thread { 1561 private Process m_process; 1562 private StartupListener m_startupListener; 1563 1564 L2StartupMonitor(Process process, StartupListener listener) { 1565 super(); 1566 1567 m_process = process; 1568 m_startupListener = listener; 1569 } 1570 1571 public void run() { 1572 while (true) { 1573 if (m_process != null) { 1574 try { 1575 int exitCode = m_process.exitValue(); 1576 1577 if (exitCode != 0) { 1578 SwingUtilities.invokeLater(new Runnable () { 1579 public void run() { 1580 m_startupListener.processFailed(); 1581 } 1582 }); 1583 return; 1584 } else { 1585 m_process = null; 1586 } 1587 } catch (IllegalThreadStateException itse) { 1588 } 1589 1590 if (isL2Accessible()) { return; } 1591 1592 try { 1593 sleep(1000); 1594 } catch (InterruptedException ignore) { 1595 } 1596 } 1597 } 1598 } 1599 } 1600 1601 class L2StartupListener implements StartupListener, OutputStreamListener { 1602 public void processFailed() { 1603 trace("L2.processFailed"); 1604 1605 if (m_webServer1Status.isReady()) { 1606 stopWebServer1(); 1607 } else { 1608 m_webServer1Label.setIcon(null); 1609 m_webServer1Label.setText(getWebServer1Label()); 1610 } 1611 1612 if (m_webServer2Status.isReady()) { 1613 stopWebServer2(); 1614 } else { 1615 m_webServer2Label.setIcon(null); 1616 m_webServer2Label.setText(getWebServer2Label()); 1617 } 1618 1619 m_l2Label.setIcon(m_stoppedIcon); 1620 m_l2Label.setText(L2_LABEL + FAILED_LABEL); 1621 m_l2Status.setFailed(); 1622 1623 testEnableControls(); 1624 } 1625 1626 public void startupError(Exception e) { 1627 trace("L2.startupError exception=" + e.getMessage()); 1628 if (m_debug) e.printStackTrace(); 1629 1630 m_webServer1Label.setIcon(null); 1631 m_webServer1Label.setText(getWebServer1Label()); 1632 m_webServer2Label.setIcon(null); 1633 m_webServer2Label.setText(getWebServer2Label()); 1634 1635 m_l2Label.setIcon(m_stoppedIcon); 1636 m_l2Label.setText(L2_LABEL + FAILED_LABEL); 1637 m_l2Status.setFailed(); 1638 1639 testEnableControls(); 1640 } 1641 1642 public void triggerEncountered() { 1643 m_l2OutView.setListener(null); 1644 processReady(); 1645 } 1646 1647 public void processReady() { 1648 trace("L2.processReady"); 1649 1650 m_l2Label.setIcon(m_readyIcon); 1651 m_l2Label.setText(L2_LABEL + READY_LABEL); 1652 m_l2Status.setReady(); 1653 1654 startWebServers(); 1655 waitForMBean(); 1656 1657 m_l2Monitor = new L2ShutdownMonitor(m_l2ShutdownListener); 1658 m_l2Monitor.start(); 1659 1660 testEnableControls(); 1661 } 1662 } 1663 1664 private void restartL2() { 1665 stopL2(isDsoEnabled()); 1666 } 1667 1668 private void stopL2() { 1669 stopL2(false); 1670 } 1671 1672 private void stopL2(boolean restart) { 1673 if (m_l2Monitor != null) { 1674 m_l2Monitor.cancel(); 1675 while (true) { 1676 try { 1677 m_l2Monitor.join(0); 1678 break; 1679 } catch (InterruptedException ie) { 1680 } 1681 } 1682 m_l2Monitor = null; 1683 } 1684 1685 m_l2Status.setWaiting(); 1686 m_l2Label.setIcon(m_waitingIcon); 1687 m_l2Label.setText(L2_LABEL + STOPPING_LABEL); 1688 m_l2ShutdownListener.setRestart(restart); 1689 1690 stopL2AndNotify(L2_SHUTDOWN_SCRIPT, m_l2OutView, m_configHelper.getJmxPort(), m_l2ShutdownListener); 1691 } 1692 1693 private void stopL2AndNotify(final String stopScript, final ProcessOutputView outView, final int port, 1694 final ShutdownListener shutdownListener) { 1695 trace("Stopping L2"); 1696 1697 Process process; 1698 try { 1699 process = invokeScript(stopScript, new String [] { getSelectedServerName() }); 1700 } catch (Exception e) { 1701 shutdownListener.processError(e); 1702 return; 1703 } 1704 1705 m_l2Monitor = new L2ShutdownMonitor(process, shutdownListener); 1706 m_l2Monitor.start(); 1707 } 1708 1709 class L2ShutdownListener implements ShutdownListener { 1710 boolean m_restart = false; 1711 1712 void setRestart(boolean restart) { 1713 m_restart = restart; 1714 } 1715 1716 public void processError(Exception e) { 1717 trace("L2.processError"); 1718 if (m_debug) e.printStackTrace(); 1719 1720 if (m_quitting) { 1721 m_l2Label.setIcon(m_readyIcon); 1722 m_l2Label.setText(L2_LABEL + READY_LABEL); 1723 m_l2Status.setReady(); 1724 } else { 1725 m_l2Label.setIcon(m_stoppedIcon); 1726 m_l2Label.setText(L2_LABEL + FAILED_LABEL); 1727 m_l2Status.setFailed(); 1728 } 1729 1730 testEnableControls(); 1731 } 1732 1733 public void processFailed(String errorBuf) { 1734 trace("L2.processFailed"); 1735 1736 m_l2OutView.append(errorBuf); 1737 1738 if (m_quitting) { 1739 m_l2Label.setIcon(m_readyIcon); 1740 m_l2Label.setText(L2_LABEL + READY_LABEL); 1741 m_l2Status.setReady(); 1742 } else { 1743 m_l2Label.setIcon(m_stoppedIcon); 1744 m_l2Label.setText(L2_LABEL + FAILED_LABEL); 1745 m_l2Status.setFailed(); 1746 } 1747 1748 testEnableControls(); 1749 } 1750 1751 public void processStopped() { 1752 m_l2Monitor = null; 1753 m_l2ConnectManager.getConnectionContext().reset(); 1754 m_l2Status.setInactive(); 1755 1756 if (m_restart) { 1757 startL2(); 1758 m_restart = false; 1759 } else { 1760 if (m_webServer1Status.isReady() || m_webServer2Status.isReady()) { 1761 stopWebServers(); 1762 } 1763 1764 m_l2Label.setIcon(m_stoppedIcon); 1765 m_l2Label.setText(L2_LABEL + STOPPED_LABEL); 1766 } 1767 1768 testEnableControls(); 1769 } 1770 } 1771 1772 class L2ShutdownMonitor extends Thread { 1773 private Process m_process; 1774 private ShutdownListener m_shutdownListener; 1775 private boolean m_stop; 1776 1777 L2ShutdownMonitor(ShutdownListener listener) { 1778 this(null, listener); 1779 } 1780 1781 L2ShutdownMonitor(Process process, ShutdownListener listener) { 1782 super(); 1783 1784 m_process = process; 1785 m_shutdownListener = listener; 1786 } 1787 1788 public void run() { 1789 ProcessWaiter waiter = null; 1790 1791 if (m_process != null) { 1792 waiter = new ProcessWaiter(m_process); 1793 waiter.start(); 1794 } 1795 1796 while (!m_stop) { 1797 if (m_process != null) { 1798 try { 1799 int exitCode = m_process.exitValue(); 1800 1801 if (exitCode != 0) { 1802 final String errorBuf = waiter.getErrorBuffer(); 1803 SwingUtilities.invokeLater(new Runnable () { 1804 public void run() { 1805 m_shutdownListener.processFailed(errorBuf); 1806 } 1807 }); 1808 return; 1809 } else { 1810 m_process = null; 1811 } 1812 } catch (IllegalThreadStateException itse) { 1813 } 1814 } 1815 1816 if (!m_stop) { 1817 if (!isL2Accessible()) { 1818 SwingUtilities.invokeLater(new Runnable () { 1819 public void run() { 1820 m_shutdownListener.processStopped(); 1821 } 1822 }); 1823 return; 1824 } 1825 } 1826 1827 try { 1828 sleep(1000); 1829 } catch (InterruptedException ignore) { 1830 } 1831 } 1832 } 1833 1834 void cancel() { 1835 m_stop = true; 1836 } 1837 } 1838 1839 class DSOAppEventListener implements NotificationListener { 1840 public void handleNotification(Notification notification, Object handback) { 1841 final Object event = notification.getSource(); 1842 1843 if (!m_handlingAppEvent && event instanceof NonPortableObjectEvent) { 1844 m_handlingAppEvent = true; 1845 1846 SwingUtilities.invokeLater(new Runnable () { 1847 public void run() { 1848 SessionIntegratorFrame.this.toFront(); 1849 handleNonPortableReason((NonPortableObjectEvent) event); 1850 } 1851 }); 1852 } 1853 } 1854 } 1855 1856 private void handleNonPortableReason(NonPortableObjectEvent event) { 1857 NonPortableReason reason = event.getReason(); 1858 1859 switch (reason.getReason()) { 1860 case NonPortableReason.CLASS_NOT_IN_BOOT_JAR: { 1861 handleClassNotInBootJar(event); 1862 break; 1863 } 1864 case NonPortableReason.CLASS_NOT_INCLUDED_IN_CONFIG: { 1865 handleClassNotIncludedInConfig(event); 1866 break; 1867 } 1868 case NonPortableReason.SUPER_CLASS_NOT_INSTRUMENTED: { 1869 handleSuperClassNotInstrumented(event); 1870 break; 1871 } 1872 case NonPortableReason.SUBCLASS_OF_LOGICALLY_MANAGED_CLASS: { 1873 handleSubclassOfLocicallyManagedClass(event); 1874 break; 1875 } 1876 case NonPortableReason.CLASS_NOT_ADAPTABLE: { 1877 handleClassNotAdaptable(event); 1878 break; 1879 } 1880 default: { 1881 handleNonPortable(event); 1882 break; 1883 } 1884 } 1885 1886 m_handlingAppEvent = false; 1887 } 1888 1889 private void handleClassNotAdaptable(NonPortableObjectEvent event) { 1890 NonPortableReason reason = event.getReason(); 1891 NonPortableEventContext cntx = event.getContext(); 1892 String msg = reason.getMessage(); 1893 String targetClass = cntx.getTargetClassName(); 1894 String className = reason.getClassName(); 1895 1896 msg = "<html><p>Attempted to share an instance of type <b>" + targetClass + "</b>,<br>" 1897 + "containing an instance of type <b>" + className + "</b><br>" + "which inherently cannot be shared in DSO."; 1898 1899 String fieldName = null; 1900 1901 if (reason.hasUltimateNonPortableFieldName()) { 1902 fieldName = reason.getUltimateNonPortableFieldName(); 1903 } else if (cntx instanceof NonPortableFieldSetContext) { 1904 fieldName = ((NonPortableFieldSetContext) cntx).getFieldName(); 1905 } 1906 1907 if (fieldName != null) { 1908 msg += "<br><br>Update the configuration to add <b>" + fieldName + "</b><br>" 1909 + "as a transient field and restart the system?"; 1910 1911 int answer = showConfirmDialog(msg, JOptionPane.YES_NO_OPTION); 1912 if (answer == JOptionPane.YES_OPTION) { 1913 m_transientFieldsPanel.ensureTransient(fieldName); 1914 m_configHelper.save(); 1915 setXmlModified(false); 1916 m_startButton.doClick(); 1917 } 1918 } else { 1919 showPlainMessage(msg); 1920 } 1921 } 1922 1923 1925 private void handleSubclassOfLocicallyManagedClass(NonPortableObjectEvent event) { 1926 NonPortableReason reason = event.getReason(); 1927 NonPortableEventContext cntx = event.getContext(); 1928 String msg = reason.getMessage(); 1929 String targetClass = cntx.getTargetClassName(); 1930 String className = reason.getClassName(); 1931 List bootClasses = reason.getErroneousBootJarSuperClasses(); 1932 List nonBootClasses = reason.getErroneousSuperClasses(); 1933 String logicalType = bootClasses.size() > 0 ? (String ) bootClasses.get(0) : (String ) nonBootClasses.get(0); 1934 1935 if (cntx instanceof NonPortableLogicalInvokeContext) { 1936 msg = "<html><p>Attempted to share an instance of type <b>" + className + "</b><br>" 1937 + "that extends the logically-managed type <b>" + targetClass + "</b>.<br><br>" 1938 + "Subclasses of logically-managed types cannot be shared in DSO."; 1939 } else { 1940 msg = "<html><p>Attempted to share an instance of type <b>" + targetClass + "</b>,<br>" 1941 + "containing an instance of type <b>" + className + "</b><br>" 1942 + "that extends the logically-managed type <b>" + logicalType + "</b>.<br><br>" 1943 + "Subclasses of logically-managed types cannot be shared in DSO."; 1944 } 1945 1946 if (reason.hasUltimateNonPortableFieldName()) { 1947 String fieldName = reason.getUltimateNonPortableFieldName(); 1948 1949 msg += "<br><br>Update the configuration to add <b>" + fieldName + "</b><br>" 1950 + "as a transient field and restart the system?"; 1951 1952 int answer = showConfirmDialog(msg, JOptionPane.YES_NO_OPTION); 1953 if (answer == JOptionPane.YES_OPTION) { 1954 m_transientFieldsPanel.ensureTransient(fieldName); 1955 m_configHelper.save(); 1956 setXmlModified(false); 1957 m_startButton.doClick(); 1958 } 1959 } else { 1960 showPlainMessage(msg); 1961 } 1962 } 1963 1964 private void handleNonPortable(NonPortableObjectEvent event) { 1965 NonPortableReason reason = event.getReason(); 1966 NonPortableEventContext cntx = event.getContext(); 1967 String msg = reason.getMessage(); 1968 String className = reason.getClassName(); 1969 1970 if (cntx instanceof NonPortableFieldSetContext) { 1971 NonPortableFieldSetContext npfsc = (NonPortableFieldSetContext) cntx; 1972 String targetClass = cntx.getTargetClassName(); 1973 String fieldName = npfsc.getFieldName(); 1974 1975 msg = "<html><p>Attempted to share an instance of type <b>" + targetClass + "</b>,<br>" 1976 + "containing an instance of type <b>" + className + "</b><br>" 1977 + "which inherently cannot be shared in DSO.<br><br>" + "Update the configuration to add <b>" + fieldName 1978 + "</b><br>" + "as a transient field and restart the system?"; 1979 1980 int answer = showConfirmDialog(msg, JOptionPane.YES_NO_OPTION); 1981 if (answer == JOptionPane.YES_OPTION) { 1982 m_transientFieldsPanel.ensureTransient(fieldName); 1983 m_configHelper.save(); 1984 setXmlModified(false); 1985 m_startButton.doClick(); 1986 } 1987 } else if (cntx instanceof NonPortableLogicalInvokeContext) { 1988 List bootClasses = reason.getErroneousBootJarSuperClasses(); 1989 List nonBootClasses = reason.getErroneousSuperClasses(); 1990 String nonPortableType = bootClasses.size() > 0 ? (String ) bootClasses.get(0) : (String ) nonBootClasses.get(0); 1991 1992 msg = "<html><p>Attempted to share an instance of type <b>" + className + "</b>,<br>" 1993 + "containing an instance of type <b>" + nonPortableType + "</b><br>" 1994 + "which is inherently not sharable in DSO."; 1995 1996 if (reason.hasUltimateNonPortableFieldName()) { 1997 String fieldName = reason.getUltimateNonPortableFieldName(); 1998 1999 msg += "<br><br>Update the configuration to add <b>" + fieldName + "</b><br>" 2000 + "as a transient field and restart the system?"; 2001 2002 int answer = showConfirmDialog(msg, JOptionPane.YES_NO_OPTION); 2003 if (answer == JOptionPane.YES_OPTION) { 2004 2005 m_transientFieldsPanel.ensureTransient(fieldName); 2006 m_configHelper.save(); 2007 setXmlModified(false); 2008 m_startButton.doClick(); 2009 } 2010 } else { 2011 showPlainMessage(msg); 2012 } 2013 } else { 2014 showPlainMessage(msg); 2015 } 2016 } 2017 2018 private String getClassNotInBootJarMessage(NonPortableObjectEvent event) { 2019 NonPortableReason reason = event.getReason(); 2020 NonPortableEventContext cntx = event.getContext(); 2021 String targetClass = cntx.getTargetClassName(); 2022 String className = reason.getClassName(); 2023 List bootTypes = reason.getErroneousBootJarSuperClasses(); 2024 2025 if (cntx instanceof NonPortableLogicalInvokeContext) { 2026 if (bootTypes.size() > 0) { 2027 return "<html><p>An instance of type <b>" + className + "</b> cannot be shared until<br>" 2028 + "it, and some of its parent types, are added to the DSO boot jar.</html>"; 2029 } else { 2030 return "<html><p>An instance of type <b>" + className + "</b> cannot be shared until<br>" 2031 + "it is added to the DSO boot jar.<br><br>" + "Update the configuration to add <b>" + className 2032 + "</b> to the<br>" + "DSO boot-jar and restart the system?"; 2033 } 2034 } else { 2035 if (bootTypes.size() > 0) { 2036 return "<html><p>Cannot share an instance of type <b>" + targetClass + "</b><br>" 2037 + "because it contains an instance of type <b>" + className + "</b>,<br>" 2038 + "and some parent types, that must be added to the DSO boot-jar.</html>"; 2039 } else { 2040 return "<html><p>Cannot share an instance of type <b>" + targetClass + "</b><br>" 2041 + "because it contains an instance of type <b>" + className + "</b><br>" 2042 + "that must be added to the DSO boot-jar.<br><br>" + "Update the configuration to add <b>" + className 2043 + "</b> to the<br>" + "DSO boot-jar and restart the system?"; 2044 } 2045 } 2046 } 2047 2048 private void handleClassNotInBootJar(NonPortableObjectEvent event) { 2049 NonPortableReason reason = event.getReason(); 2050 String className = reason.getClassName(); 2051 List bootTypes = reason.getErroneousBootJarSuperClasses(); 2052 List superTypes = reason.getErroneousSuperClasses(); 2053 String msg = getClassNotInBootJarMessage(event); 2054 int type = JOptionPane.YES_NO_OPTION; 2055 2056 if (bootTypes.size() > 0) { 2057 bootTypes.add(0, className); 2058 2059 InstrumentSuperTypesPanel panel = getInstrumentSuperTypesPanel(msg, className, bootTypes, superTypes); 2060 2061 if (showConfirmDialog(panel, type) == JOptionPane.OK_OPTION) { 2062 for (int i = 0; i < bootTypes.size(); i++) { 2063 m_bootClassesPanel.ensureBootClass((String ) bootTypes.get(i)); 2064 } 2065 2066 m_configHelper.save(); 2067 setXmlModified(false); 2068 2069 if (panel.restartSystem()) { 2070 m_startButton.doClick(); 2071 } 2072 } 2073 } else { 2074 if (showConfirmDialog(msg, type) == JOptionPane.YES_OPTION) { 2075 m_bootClassesPanel.ensureBootClass(className); 2076 m_configHelper.save(); 2077 setXmlModified(false); 2078 m_startButton.doClick(); 2079 } 2080 } 2081 } 2082 2083 private InstrumentTypePanel m_instrumentPanel; 2084 2085 private InstrumentTypePanel getInstrumentPanel(String msg, String className, List bootTypes, List superTypes) { 2086 if (m_instrumentPanel == null) { 2087 DictionaryResource topRes = SessionIntegrator.getContext().topRes; 2088 ContainerResource res = (ContainerResource) topRes.getComponent("InstrumentPanel"); 2089 2090 m_instrumentPanel = new InstrumentTypePanel(res); 2091 } 2092 m_instrumentPanel.setup(msg, className, bootTypes, superTypes); 2093 2094 return m_instrumentPanel; 2095 } 2096 2097 private void handleClassNotIncludedInConfig(NonPortableObjectEvent event) { 2098 NonPortableReason reason = event.getReason(); 2099 List bootTypes = reason.getErroneousBootJarSuperClasses(); 2100 List superTypes = reason.getErroneousSuperClasses(); 2101 2102 String className = reason.getClassName(); 2103 String msg = "<html><p>Cannot share an instance of type <b>" + className + "</b>,<br> " 2104 + "because it is not instrumented for use with DSO."; 2105 int type = JOptionPane.OK_CANCEL_OPTION; 2106 InstrumentTypePanel panel = getInstrumentPanel(msg, className, bootTypes, superTypes); 2107 int answer = showConfirmDialog(panel, type); 2108 2109 if (answer == JOptionPane.OK_OPTION) { 2110 m_instrumentedClassesPanel.ensureAdaptable(panel.getPattern()); 2111 2112 for (int i = 0; i < bootTypes.size(); i++) { 2113 m_bootClassesPanel.ensureBootClass((String ) bootTypes.get(i)); 2114 } 2115 2116 if (!panel.includeAll()) { 2117 for (int i = 0; i < superTypes.size(); i++) { 2118 m_instrumentedClassesPanel.ensureAdaptable((String ) superTypes.get(i)); 2119 } 2120 } 2121 2122 m_configHelper.save(); 2123 setXmlModified(false); 2124 2125 if (panel.restartSystem()) { 2126 m_startButton.doClick(); 2127 } 2128 } 2129 } 2130 2131 private InstrumentSuperTypesPanel m_instrumentSuperTypesPanel; 2132 2133 private InstrumentSuperTypesPanel getInstrumentSuperTypesPanel(String msg, String className, List bootTypes, 2134 List superTypes) { 2135 if (m_instrumentSuperTypesPanel == null) { 2136 DictionaryResource topRes = SessionIntegrator.getContext().topRes; 2137 ContainerResource res = (ContainerResource) topRes.getComponent("InstrumentSuperTypesPanel"); 2138 2139 m_instrumentSuperTypesPanel = new InstrumentSuperTypesPanel(res); 2140 } 2141 m_instrumentSuperTypesPanel.setup(msg, className, bootTypes, superTypes); 2142 2143 return m_instrumentSuperTypesPanel; 2144 } 2145 2146 private void handleSuperClassNotInstrumented(NonPortableObjectEvent event) { 2147 NonPortableReason reason = event.getReason(); 2148 String className = reason.getClassName(); 2149 String msg = "<html><p>An instance of type <b>" + className + "</b> cannot be shared because<br>" 2150 + "some of its base classes are not instrumented for use with DSO.</html>"; 2151 int type = JOptionPane.OK_CANCEL_OPTION; 2152 List bootTypes = reason.getErroneousBootJarSuperClasses(); 2153 List superTypes = reason.getErroneousSuperClasses(); 2154 InstrumentSuperTypesPanel panel = getInstrumentSuperTypesPanel(msg, className, bootTypes, superTypes); 2155 int answer = showConfirmDialog(panel, type); 2156 2157 if (answer == JOptionPane.OK_OPTION) { 2158 for (int i = 0; i < bootTypes.size(); i++) { 2159 m_bootClassesPanel.ensureBootClass((String ) bootTypes.get(i)); 2160 } 2161 2162 for (int i = 0; i < superTypes.size(); i++) { 2163 m_instrumentedClassesPanel.ensureAdaptable((String ) superTypes.get(i)); 2164 } 2165 2166 m_configHelper.save(); 2167 setXmlModified(false); 2168 2169 if (panel.restartSystem()) { 2170 m_startButton.doClick(); 2171 } 2172 } 2173 } 2174 2175 private int showConfirmDialog(Object msg, int msgType) { 2176 return JOptionPane.showConfirmDialog(this, msg, getTitle(), msgType); 2177 } 2178 2179 private void showPlainMessage(Object msg) { 2180 JOptionPane.showConfirmDialog(this, msg, getTitle(), JOptionPane.PLAIN_MESSAGE); 2181 } 2182 2183 class L2ConnectListener implements ConnectionListener { 2184 public void handleConnection() { 2185 } 2186 2187 public void handleException() { 2188 } 2189 } 2190 2191 private void waitForMBean() { 2192 new Thread () { 2193 public void run() { 2194 while (true) { 2195 try { 2196 if (m_l2ConnectManager.testIsConnected()) { 2197 ConnectionContext cc = m_l2ConnectManager.getConnectionContext(); 2198 ObjectName on = cc.queryName(L2MBeanNames.DSO_APP_EVENTS.getCanonicalName()); 2199 2200 if (on != null) { 2201 cc.addNotificationListener(on, new DSOAppEventListener()); 2202 return; 2203 } 2204 } 2205 } catch (Exception e) { 2206 } 2207 2208 try { 2209 sleep(500); 2210 } catch (InterruptedException ie) { 2211 } 2212 } 2213 } 2214 }.start(); 2215 } 2216 2217 private boolean isL2Ready() { 2218 return m_l2Status.isReady(); 2219 } 2220 2221 2223 2225 private void testShutdownWebServer1() { 2226 try { 2227 safeCloseSocket(new Socket ("localhost", SERVER1_PORT)); 2228 stopWebServer1(); 2229 } catch (IOException ioe) { 2230 } 2231 } 2232 2233 private void startWebServer1() { 2234 if (m_webServer1Monitor != null) { 2235 m_webServer1Monitor.cancel(); 2236 m_webServer1Monitor = null; 2237 } 2238 2239 if (isWebServer1Ready()) { 2240 m_webServer1Status.setRestarting(true); 2241 restartWebServer1(); 2242 return; 2243 } 2244 2245 m_webServer1Label.setIcon(m_waitingIcon); 2246 m_webServer1Label.setText(getWebServer1Label() + STARTING_LABEL); 2247 m_webServer1Status.setWaiting(); 2248 m_webServer1OutView.setListener(m_webServer1StartupListener); 2249 m_webServer1OutView.setListenerTrigger(getSelectedServerStartupTrigger()); 2250 startWebServerAndNotify(m_webServer1OutView, SERVER1_PORT, m_webServer1StartupListener); 2251 } 2252 2253 class WebServer1StartupListener implements StartupListener, OutputStreamListener { 2254 public void startupError(Exception e) { 2255 trace(getSelectedServerLabel() + "1.startupError exception=" + e.getMessage()); 2256 2257 m_webServer1Label.setIcon(m_stoppedIcon); 2258 m_webServer1Label.setText(getWebServer1Label() + FAILED_LABEL); 2259 m_webServer1Status.setFailed(); 2260 2261 testEnableControls(); 2262 } 2263 2264 public void processFailed() { 2265 trace(getSelectedServerLabel() + ".processFailed"); 2266 2267 m_webServer1Label.setIcon(m_stoppedIcon); 2268 m_webServer1Label.setText(getWebServer1Label() + FAILED_LABEL); 2269 m_webServer1Status.setFailed(); 2270 2271 testEnableControls(); 2272 } 2273 2274 public void triggerEncountered() { 2275 m_webServer1OutView.setListener(null); 2276 processReady(); 2277 } 2278 2279 public void processReady() { 2280 trace(getSelectedServerLabel() + "1.processReady"); 2281 2282 m_webServer1Status.setReady(); 2283 m_webServer1Label.setIcon(m_readyIcon); 2284 m_webServer1Label.setText(getWebServer1Label() + READY_LABEL); 2285 2286 m_webServer1Monitor = new WebServerShutdownMonitor(SERVER1_PORT, m_webServer1ShutdownListener); 2287 m_webServer1Monitor.start(); 2288 2289 testEnableControls(); 2290 } 2291 } 2292 2293 private void restartWebServer1() { 2294 stopWebServer1(true); 2295 } 2296 2297 private boolean isWebServer1Ready() { 2298 return m_webServer1Status.isReady(); 2299 } 2300 2301 private void stopWebServer1() { 2302 stopWebServer1(false); 2303 } 2304 2305 private void stopWebServer1(boolean restart) { 2306 if (m_webServer1Monitor != null) { 2307 m_webServer1Monitor.cancel(); 2308 m_webServer1Monitor = null; 2309 } 2310 2311 m_webServer1Label.setIcon(m_waitingIcon); 2312 m_webServer1Label.setText(getWebServer1Label() + STOPPING_LABEL); 2313 m_webServer1Status.setWaiting(); 2314 m_webServer1ShutdownListener.setRestart(restart); 2315 2316 stopWebServerAndNotify(m_webServer1OutView, SERVER1_PORT, m_webServer1ShutdownListener); 2317 } 2318 2319 class WebServer1ShutdownListener implements ShutdownListener { 2320 boolean m_restart = false; 2321 2322 void setRestart(boolean restart) { 2323 m_restart = restart; 2324 } 2325 2326 public void processError(Exception e) { 2327 trace(getSelectedServerLabel() + "1.processError exception=" + e.getMessage()); 2328 if (m_debug) e.printStackTrace(); 2329 2330 if (!m_quitting) { 2331 m_webServer1Status.setReady(); 2332 m_webServer1Label.setIcon(m_readyIcon); 2333 m_webServer1Label.setText(getWebServer1Label() + READY_LABEL); 2334 } else { 2335 m_webServer1Status.setFailed(); 2336 m_webServer1Label.setIcon(m_stoppedIcon); 2337 m_webServer1Label.setText(getWebServer1Label() + FAILED_LABEL); 2338 } 2339 2340 testEnableControls(); 2341 } 2342 2343 public void processFailed(String errorBuf) { 2344 trace(getSelectedServerLabel() + "1.processFailed"); 2345 2346 m_webServer1OutView.append(errorBuf); 2347 2348 if (!m_quitting) { 2349 m_webServer1Status.setReady(); 2350 m_webServer1Label.setIcon(m_readyIcon); 2351 m_webServer1Label.setText(getWebServer1Label() + READY_LABEL); 2352 } else { 2353 m_webServer1Status.setFailed(); 2354 m_webServer1Label.setIcon(m_stoppedIcon); 2355 m_webServer1Label.setText(getWebServer1Label() + FAILED_LABEL); 2356 } 2357 2358 testEnableControls(); 2359 } 2360 2361 public void processStopped() { 2362 trace(getSelectedServerLabel() + "1.processStopped"); 2363 2364 m_webServer1Monitor = null; 2365 m_webServer1Status.setInactive(); 2366 if (m_restarting && isDsoEnabled()) { 2367 m_webServer1Label.setText(getWebServer1Label() + WAITING_LABEL); 2368 if (m_webServer2Status.isInactive()) { 2369 startL2(); 2370 } 2371 } else { 2372 if (m_restart) { 2373 startWebServer1(); 2374 } else { 2375 m_webServer1Label.setIcon(m_stoppedIcon); 2376 m_webServer1Label.setText(getWebServer1Label() + STOPPED_LABEL); 2377 } 2378 } 2379 2380 testEnableControls(); 2381 } 2382 } 2383 2384 private void toggleWebServer1() { 2385 if (isWebServer1Ready()) { 2386 stopWebServer1(); 2387 } else { 2388 startWebServer1(); 2389 } 2390 } 2391 2392 2394 2396 private void testShutdownWebServer2() { 2397 try { 2398 safeCloseSocket(new Socket ("localhost", SERVER2_PORT)); 2399 stopWebServer2(); 2400 } catch (IOException ioe) { 2401 } 2402 } 2403 2404 private void startWebServer2() { 2405 if (m_webServer2Monitor != null) { 2406 m_webServer2Monitor.cancel(); 2407 m_webServer2Monitor = null; 2408 } 2409 2410 if (isWebServer2Ready()) { 2411 m_webServer2Status.setRestarting(true); 2412 restartWebServer2(); 2413 return; 2414 } 2415 2416 m_webServer2Label.setIcon(m_waitingIcon); 2417 m_webServer2Label.setText(getWebServer2Label() + STARTING_LABEL); 2418 m_webServer2Status.setWaiting(); 2419 m_webServer2OutView.setListener(m_webServer2StartupListener); 2420 m_webServer2OutView.setListenerTrigger(getSelectedServerStartupTrigger()); 2421 startWebServerAndNotify(m_webServer2OutView, SERVER2_PORT, m_webServer2StartupListener); 2422 } 2423 2424 class WebServer2StartupListener implements StartupListener, OutputStreamListener { 2425 public void startupError(Exception e) { 2426 trace(getSelectedServerLabel() + "2.startupError exception=" + e.getMessage()); 2427 2428 m_webServer2Label.setIcon(m_stoppedIcon); 2429 m_webServer2Label.setText(getWebServer2Label() + FAILED_LABEL); 2430 m_webServer2Status.setFailed(); 2431 2432 testEnableControls(); 2433 } 2434 2435 public void processFailed() { 2436 trace(getSelectedServerLabel() + "2.processFailed"); 2437 2438 m_webServer2Label.setIcon(m_stoppedIcon); 2439 m_webServer2Label.setText(getWebServer2Label() + FAILED_LABEL); 2440 m_webServer2Status.setFailed(); 2441 2442 testEnableControls(); 2443 } 2444 2445 public void triggerEncountered() { 2446 m_webServer2OutView.setListener(null); 2447 processReady(); 2448 } 2449 2450 public void processReady() { 2451 trace(getSelectedServerLabel() + "2.processReady"); 2452 2453 m_webServer2Status.setReady(); 2454 m_webServer2Label.setIcon(m_readyIcon); 2455 m_webServer2Label.setText(getWebServer2Label() + READY_LABEL); 2456 2457 m_webServer2Monitor = new WebServerShutdownMonitor(SERVER2_PORT, m_webServer2ShutdownListener); 2458 m_webServer2Monitor.start(); 2459 2460 testEnableControls(); 2461 } 2462 } 2463 2464 private void restartWebServer2() { 2465 stopWebServer2(true); 2466 } 2467 2468 private boolean isWebServer2Ready() { 2469 return m_webServer2Status.isReady(); 2470 } 2471 2472 private void stopWebServer2() { 2473 stopWebServer2(false); 2474 } 2475 2476 private void stopWebServer2(boolean restart) { 2477 if (m_webServer2Monitor != null) { 2478 m_webServer2Monitor.cancel(); 2479 m_webServer2Monitor = null; 2480 } 2481 2482 m_webServer2Label.setIcon(m_waitingIcon); 2483 m_webServer2Label.setText(getWebServer2Label() + STOPPING_LABEL); 2484 m_webServer2Status.setWaiting(); 2485 m_webServer2ShutdownListener.setRestart(restart); 2486 2487 stopWebServerAndNotify(m_webServer2OutView, SERVER2_PORT, m_webServer2ShutdownListener); 2488 } 2489 2490 class WebServer2ShutdownListener implements ShutdownListener { 2491 boolean m_restart = false; 2492 2493 void setRestart(boolean restart) { 2494 m_restart = restart; 2495 } 2496 2497 public void processError(Exception e) { 2498 trace(getSelectedServerLabel() + "2.processError"); 2499 if (m_debug) e.printStackTrace(); 2500 2501 if (!m_quitting) { 2502 m_webServer2Status.setReady(); 2503 m_webServer2Label.setIcon(m_readyIcon); 2504 m_webServer2Label.setText(getWebServer2Label() + READY_LABEL); 2505 } else { 2506 m_webServer2Status.setFailed(); 2507 m_webServer2Label.setIcon(m_stoppedIcon); 2508 m_webServer2Label.setText(getWebServer2Label() + FAILED_LABEL); 2509 } 2510 2511 testEnableControls(); 2512 } 2513 2514 public void processFailed(String errorBuf) { 2515 trace(getSelectedServerLabel() + "2.processFailed"); 2516 2517 m_webServer2OutView.append(errorBuf); 2518 2519 if (!m_quitting) { 2520 m_webServer2Status.setReady(); 2521 m_webServer2Label.setIcon(m_readyIcon); 2522 m_webServer2Label.setText(getWebServer2Label() + READY_LABEL); 2523 } else { 2524 m_webServer2Status.setFailed(); 2525 m_webServer2Label.setIcon(m_stoppedIcon); 2526 m_webServer2Label.setText(getWebServer2Label() + FAILED_LABEL); 2527 } 2528 2529 testEnableControls(); 2530 } 2531 2532 public void processStopped() { 2533 trace(getSelectedServerLabel() + "2.processStopped"); 2534 2535 m_webServer2Monitor = null; 2536 m_webServer2Status.setInactive(); 2537 if (m_restarting && isDsoEnabled()) { 2538 m_webServer2Label.setText(getWebServer2Label() + WAITING_LABEL); 2539 if (m_webServer1Status.isInactive()) { 2540 startL2(); 2541 } 2542 } else { 2543 if (m_restart) { 2544 startWebServer2(); 2545 } else { 2546 m_webServer2Label.setIcon(m_stoppedIcon); 2547 m_webServer2Label.setText(getWebServer2Label() + STOPPED_LABEL); 2548 } 2549 } 2550 2551 testEnableControls(); 2552 } 2553 } 2554 2555 private void toggleWebServer2() { 2556 if (isWebServer2Ready()) { 2557 stopWebServer2(); 2558 } else { 2559 startWebServer2(); 2560 } 2561 } 2562 2563 2565 2567 private Process startWebServerAndNotify(final ProcessOutputView outView, final int port, 2568 final StartupListener startupListener) { 2569 trace("Starting " + getSelectedServerLabel() + "-" + port); 2570 2571 Process process; 2572 try { 2573 String dso = isDsoEnabled() ? "dso" : "nodso"; 2574 String [] args = new String [] { getSelectedServerName(), Integer.toString(port), dso }; 2575 2576 process = invokeScript(WEBSERVER_STARTUP_SCRIPT, args); 2577 IOUtils.closeQuietly(process.getOutputStream()); 2578 new ProcessMonitor(process, new ProcessTerminationListener() { 2579 public void processTerminated(int exitCode) { 2580 if (m_debug) { 2581 outView.append(getSelectedServerLabel() + "-" + port + " terminated with exitCode=" + exitCode); 2582 } 2583 if (exitCode != 0) { 2584 SwingUtilities.invokeLater(new Runnable () { 2585 public void run() { 2586 startupListener.processFailed(); 2587 } 2588 }); 2589 } 2590 } 2591 }); 2592 } catch (Exception e) { 2593 startupListener.startupError(e); 2594 return null; 2595 } 2596 2597 outView.start(process); 2598 2599 new WebServerStartupMonitor(process, port, startupListener).start(); 2600 2601 return process; 2602 } 2603 2604 class WebServerStartupMonitor extends Thread { 2605 private Process m_process; 2606 private int m_port; 2607 private StartupListener m_startupListener; 2608 2609 WebServerStartupMonitor(Process process, int port, StartupListener listener) { 2610 super(); 2611 2612 m_process = process; 2613 m_port = port; 2614 m_startupListener = listener; 2615 } 2616 2617 public void run() { 2618 while (true) { 2619 try { 2620 m_process.exitValue(); 2621 SwingUtilities.invokeLater(new Runnable () { 2622 public void run() { 2623 m_startupListener.processFailed(); 2624 } 2625 }); 2626 return; 2627 } catch (IllegalThreadStateException itse) { 2628 } 2629 2630 try { 2631 safeCloseSocket(new Socket ("localhost", m_port)); 2632 return; 2633 } catch (IOException ioe) { 2634 } 2635 2636 try { 2637 sleep(1000); 2638 } catch (InterruptedException ignore) { 2639 } 2640 } 2641 } 2642 } 2643 2644 interface ProcessListener { 2645 void startupError(Exception e); 2646 2647 void startupFailed(String errorBuffer); 2648 2649 void shutdownError(Exception e); 2650 2651 void shutdownFailed(String errorBuffer); 2652 2653 void processReady(); 2654 2655 void processTerminated(int exitCode); 2656 } 2657 2658 interface StartupListener { 2659 void startupError(Exception e); 2660 2661 void processFailed(); 2662 2663 void processReady(); 2664 } 2665 2666 interface ShutdownListener { 2667 void processError(Exception e); 2668 2669 void processFailed(String errorBuffer); 2670 2671 void processStopped(); 2672 } 2673 2674 private void stopWebServerAndNotify(final ProcessOutputView outView, final int port, 2675 final ShutdownListener shutdownListener) { 2676 trace("Stopping " + getSelectedServerLabel() + "-" + port); 2677 2678 try { 2679 safeCloseSocket(new Socket ("localhost", port)); 2680 } catch (Exception e) { 2681 shutdownListener.processStopped(); 2682 return; 2683 } 2684 2685 Process process; 2686 try { 2687 String [] args = new String [] { getSelectedServerName(), Integer.toString(port) }; 2688 2689 process = invokeScript(WEBSERVER_SHUTDOWN_SCRIPT, args); 2690 IOUtils.closeQuietly(process.getOutputStream()); 2691 } catch (Exception e) { 2692 shutdownListener.processError(e); 2693 return; 2694 } 2695 2696 new WebServerShutdownMonitor(process, port, shutdownListener).start(); 2697 } 2698 2699 class WebServerShutdownMonitor extends Thread { 2700 private Process m_process; 2701 private int m_port; 2702 private ShutdownListener m_shutdownListener; 2703 private boolean m_stop; 2704 2705 WebServerShutdownMonitor(int port, ShutdownListener listener) { 2706 this(null, port, listener); 2707 } 2708 2709 WebServerShutdownMonitor(Process process, int port, ShutdownListener listener) { 2710 super(); 2711 2712 m_process = process; 2713 m_port = port; 2714 m_shutdownListener = listener; 2715 } 2716 2717 public void run() { 2718 ProcessWaiter waiter = null; 2719 2720 if (m_process != null) { 2721 waiter = new ProcessWaiter(m_process); 2722 waiter.start(); 2723 } 2724 2725 while (!m_stop) { 2726 if (m_process != null) { 2727 try { 2728 int exitCode = m_process.exitValue(); 2729 2730 if (exitCode != 0) { 2731 final String errorBuf = waiter.getErrorBuffer(); 2732 SwingUtilities.invokeLater(new Runnable () { 2733 public void run() { 2734 m_shutdownListener.processFailed(errorBuf); 2735 } 2736 }); 2737 return; 2738 } else { 2739 m_process = null; 2740 } 2741 } catch (IllegalThreadStateException itse) { 2742 } 2743 } 2744 2745 if (!m_stop) { 2746 try { 2747 safeCloseSocket(new Socket ("localhost", m_port)); 2748 } catch (Exception e) { 2749 SwingUtilities.invokeLater(new Runnable () { 2750 public void run() { 2751 m_shutdownListener.processStopped(); 2752 } 2753 }); 2754 return; 2755 } 2756 } 2757 2758 try { 2759 sleep(1000); 2760 } catch (InterruptedException ignore) { 2761 } 2762 } 2763 } 2764 2765 void cancel() { 2766 m_stop = true; 2767 } 2768 } 2769 2770 2772 private void stopAll() throws Exception { 2773 if (m_webServer1Status.isReady()) { 2774 stopWebServer1(); 2775 } 2776 if (m_webServer2Status.isReady()) { 2777 stopWebServer2(); 2778 } 2779 if (m_l2Status.isReady()) { 2780 stopL2(); 2781 } 2782 } 2783 2784 private String [] append(String [] array1, String [] array2) { 2785 int array1Len = array1.length; 2786 int array2Len = array2.length; 2787 String [] result = new String [array1Len + array2Len]; 2788 2789 for (int i = 0; i < array1Len; i++) { 2790 result[i] = array1[i]; 2791 } 2792 for (int i = 0, j = array1Len; i < array2Len; i++, j++) { 2793 result[j] = array2[i]; 2794 } 2795 2796 return result; 2797 } 2798 2799 private String [] buildScriptCommand(String scriptPath) { 2800 if (Os.isWindows()) { 2801 return new String [] { "cmd.exe", "/C", scriptPath }; 2802 } else { 2803 return new String [] { scriptPath }; 2804 } 2805 } 2806 2807 private String [] buildScriptArgs(String [] args) { 2808 return args; 2809 } 2810 2811 private Process invokeScript(String scriptName, String [] args) throws Exception { 2812 String [] cmd = buildScriptCommand(SANDBOX_ROOT + FS + "bin" + FS + scriptName); 2813 String [] env = getSelectedServerEnvironment(); 2814 File wd = new File (SANDBOX_ROOT); 2815 2816 return Runtime.getRuntime().exec(append(cmd, buildScriptArgs(args)), env, wd); 2817 } 2818 2819 private void stopSystem() { 2820 try { 2821 m_webAppTreeModel.updateLinks(false, false); 2822 disableControls(); 2823 stopAll(); 2824 } catch (Exception e) { 2825 e.printStackTrace(); 2826 } 2827 } 2828 2829 private boolean anyReady() { 2830 return m_l2Status.isReady() || m_webServer1Status.isReady() || m_webServer2Status.isReady(); 2831 } 2832 2833 private boolean anyRestarting() { 2834 return m_l2Status.isRestarting() || m_webServer1Status.isRestarting() || m_webServer2Status.isRestarting(); 2835 } 2836 2837 private boolean anyWaiting() { 2838 return m_l2Status.isWaiting() || m_webServer1Status.isWaiting() || m_webServer2Status.isWaiting(); 2839 } 2840 2841 private void disableControls() { 2842 m_webServer1EnabledToggle.setEnabled(false); 2843 m_webServer2EnabledToggle.setEnabled(false); 2844 m_dsoEnabledToggle.setEnabled(false); 2845 2846 m_startButton.setEnabled(false); 2847 m_stopButton.setEnabled(false); 2848 2849 m_webServer1Control.setVisible(false); 2850 m_webServer2Control.setVisible(false); 2851 2852 selectControlTab(); 2853 setConfigTabEnabled(false); 2854 setMonitorTabEnabled(false); 2855 2856 m_serversAction.setEnabled(false); 2857 m_importAction.setEnabled(false); 2858 m_webAppTreeModel.setRefreshEnabled(false); 2859 m_webAppTreeModel.setRemoveEnabled(false); 2860 2861 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 2862 } 2863 2864 private synchronized void testEnableControls() { 2865 boolean anyRestarting = anyRestarting(); 2866 boolean anyWaiting = anyWaiting(); 2867 2868 if (anyRestarting || anyWaiting) { return; } 2869 2870 m_restarting = false; 2871 2872 boolean anyReady = anyReady(); 2873 2874 if (!anyWaiting && !anyRestarting && anyReady && m_quitting) { 2875 stopSystem(); 2876 } 2877 2878 if (!anyWaiting && !anyRestarting && !anyReady) { 2879 if (m_quitting) { 2880 SessionIntegrator.getContext().client.shutdown(); 2881 return; 2882 } else { 2883 m_serversAction.setEnabled(true); 2884 m_importAction.setEnabled(true); 2885 m_webAppTreeModel.setRefreshEnabled(true); 2886 m_webAppTreeModel.setRemoveEnabled(true); 2887 } 2888 } 2889 2890 m_webServer1EnabledToggle.setEnabled(!anyWaiting && !anyRestarting && !anyReady); 2891 m_webServer2EnabledToggle.setEnabled(!anyWaiting && !anyRestarting && !anyReady); 2892 m_dsoEnabledToggle.setEnabled(!anyWaiting && !anyRestarting && !anyReady); 2893 m_startButton.setEnabled(!anyWaiting && !anyRestarting); 2894 m_stopButton.setEnabled(!anyWaiting && !anyRestarting && anyReady); 2895 2896 if ((!anyWaiting && !anyReady) || anyRestarting) { 2897 m_webServer1Control.setVisible(false); 2898 m_webServer2Control.setVisible(false); 2899 2900 m_startButton.setText(getBundleString("start.all.label")); 2901 } else { 2902 testEnableWebServer1Control(); 2903 testEnableWebServer2Control(); 2904 2905 m_startButton.setText(getBundleString("restart.all.label")); 2906 } 2907 2908 if (!anyWaiting && !anyRestarting) { 2909 updateLinks(); 2910 setConfigTabEnabled(true); 2911 setMonitorTabEnabled(isDsoEnabled()); 2912 setCursor(STANDARD_CURSOR); 2913 } 2914 } 2915 2916 private void testEnableWebServer1Control() { 2917 boolean webServer1NotWaiting = !m_webServer1Status.isWaiting(); 2918 m_webServer1Control.setVisible(webServer1NotWaiting); 2919 m_webServer1Control.setEnabled(webServer1NotWaiting); 2920 if (webServer1NotWaiting) { 2921 boolean webServer1Ready = isWebServer1Ready(); 2922 2923 m_webServer1Control.setIcon(webServer1Ready ? m_stopIcon : m_startIcon); 2924 2925 String tip = (webServer1Ready ? getBundleString("stop.label") : getBundleString("start.label")) + " " 2926 + getWebServer1Label(); 2927 m_webServer1Control.setToolTipText(tip); 2928 } 2929 } 2930 2931 private void testEnableWebServer2Control() { 2932 boolean webServer2NotWaiting = !m_webServer2Status.isWaiting(); 2933 m_webServer2Control.setVisible(webServer2NotWaiting); 2934 m_webServer2Control.setEnabled(webServer2NotWaiting); 2935 if (webServer2NotWaiting) { 2936 boolean webServer2Ready = isWebServer2Ready(); 2937 2938 m_webServer2Control.setIcon(webServer2Ready ? m_stopIcon : m_startIcon); 2939 2940 String tip = (webServer2Ready ? getBundleString("stop.label") : getBundleString("start.label")) + " " 2941 + getWebServer2Label(); 2942 m_webServer2Control.setToolTipText(tip); 2943 } 2944 } 2945 2946 private void updateLinks() { 2947 m_webAppTreeModel.updateLinks(isWebServer1Ready(), isWebServer2Ready()); 2948 } 2949 2950 private void saveConfig() { 2951 saveXML(m_xmlPane.getText()); 2952 } 2953 2954 public void modelChanged() { 2955 setupEditorPanels(); 2956 updateXmlPane(); 2957 2958 if (false && isL2Ready() && !m_handlingAppEvent) { 2959 queryRestart(); 2960 } 2961 } 2962 2963 public void saveXML(String xmlText) { 2964 m_configHelper.save(xmlText); 2965 setupEditorPanels(); 2966 setXmlModified(false); 2967 2968 if (isConfigTabSelected() && isL2Ready()) { 2969 m_askRestart = true; 2970 } 2971 } 2972 2973 private static void trace(String msg) { 2974 if (m_debug) { 2975 System.out.println(msg); 2976 } 2977 } 2978 2979 2981 private Preferences getPreferences() { 2982 SessionIntegratorContext cntx = SessionIntegrator.getContext(); 2983 return cntx.prefs.node("SessionIntegratorFrame"); 2984 } 2985 2986 private void storePreferences() { 2987 SessionIntegratorContext cntx = SessionIntegrator.getContext(); 2988 cntx.client.storePrefs(); 2989 } 2990 2991 public Rectangle getDefaultBounds() { 2992 Toolkit tk = Toolkit.getDefaultToolkit(); 2993 Dimension size = tk.getScreenSize(); 2994 GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); 2995 GraphicsDevice device = env.getDefaultScreenDevice(); 2996 GraphicsConfiguration config = device.getDefaultConfiguration(); 2997 Insets insets = tk.getScreenInsets(config); 2998 2999 size.width -= (insets.left + insets.right); 3000 size.height -= (insets.top + insets.bottom); 3001 3002 int width = (int) (size.width * 0.75f); 3003 int height = (int) (size.height * 0.66f); 3004 3005 int x = size.width / 2 - width / 2; 3007 int y = size.height / 2 - height / 2; 3008 3009 return new Rectangle (x, y, width, height); 3010 } 3011 3012 private String getBoundsString() { 3013 Rectangle b = getBounds(); 3014 return b.x + "," + b.y + "," + b.width + "," + b.height; 3015 } 3016 3017 private int parseInt(String s) { 3018 try { 3019 return Integer.parseInt(s); 3020 } catch (Exception e) { 3021 return 0; 3022 } 3023 } 3024 3025 private Rectangle parseBoundsString(String s) { 3026 String [] split = s.split(","); 3027 int x = parseInt(split[0]); 3028 int y = parseInt(split[1]); 3029 int width = parseInt(split[2]); 3030 int height = parseInt(split[3]); 3031 3032 return new Rectangle (x, y, width, height); 3033 } 3034 3035 public void storeBounds() { 3036 if (getName() != null && (getExtendedState() & NORMAL) == NORMAL) { 3037 getPreferences().put("Bounds", getBoundsString()); 3038 storePreferences(); 3039 } 3040 } 3041 3042 protected Rectangle getPreferredBounds() { 3043 Preferences prefs = getPreferences(); 3044 String s = prefs.get("Bounds", null); 3045 3046 return s != null ? parseBoundsString(s) : getDefaultBounds(); 3047 } 3048 3049 3051 private int getSplitPref(JSplitPane splitter) { 3052 Preferences prefs = getPreferences(); 3053 Preferences splitPrefs = prefs.node(splitter.getName()); 3054 3055 return splitPrefs.getInt("Split", -1); 3056 } 3057 3058 private JSplitPane getControlSplitter() { 3059 if (m_controlSplitter == null) { 3060 m_controlSplitter = (SplitPane) findComponent("ControlSplitter"); 3061 m_controlDividerLocation = new Integer (getSplitPref(m_controlSplitter)); 3062 3063 if (m_dividerListener == null) { 3064 m_dividerListener = new DividerListener(); 3065 } 3066 } 3067 3068 return m_controlSplitter; 3069 } 3070 3071 class DividerListener implements PropertyChangeListener { 3072 public void propertyChange(PropertyChangeEvent pce) { 3073 JSplitPane splitter = (JSplitPane ) pce.getSource(); 3074 String propName = pce.getPropertyName(); 3075 3076 if (splitter.isShowing() == false || JSplitPane.DIVIDER_LOCATION_PROPERTY.equals(propName) == false) { return; } 3077 3078 int divLoc = splitter.getDividerLocation(); 3079 Integer divLocObj = new Integer (divLoc); 3080 Preferences prefs = getPreferences(); 3081 String name = splitter.getName(); 3082 Preferences node = prefs.node(name); 3083 3084 node.putInt("Split", divLoc); 3085 storePreferences(); 3086 3087 if (m_controlSplitter.getName().equals(name)) { 3088 m_controlDividerLocation = divLocObj; 3089 } 3090 } 3091 } 3092 3093 public void doLayout() { 3094 super.doLayout(); 3095 3096 JSplitPane splitter = getControlSplitter(); 3097 if (m_controlDividerLocation != null) { 3098 splitter.setDividerLocation(m_controlDividerLocation.intValue()); 3099 } 3100 } 3101 3102 public void addNotify() { 3103 super.addNotify(); 3104 getControlSplitter().addPropertyChangeListener(m_dividerListener); 3105 } 3106 3107 public void removeNotify() { 3108 getControlSplitter().removePropertyChangeListener(m_dividerListener); 3109 super.removeNotify(); 3110 } 3111} 3112
| Popular Tags
|