0001: /*
0002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
0003: * notice. All rights reserved.
0004: */
0005: package com.tc;
0006:
0007: import org.apache.commons.io.FileUtils;
0008: import org.apache.commons.io.IOUtils;
0009: import org.apache.commons.lang.StringUtils;
0010: import org.apache.xmlbeans.XmlError;
0011: import org.dijon.Button;
0012: import org.dijon.CheckBox;
0013: import org.dijon.Container;
0014: import org.dijon.ContainerResource;
0015: import org.dijon.Dialog;
0016: import org.dijon.DialogResource;
0017: import org.dijon.DictionaryResource;
0018: import org.dijon.EmptyBorder;
0019: import org.dijon.Frame;
0020: import org.dijon.Label;
0021: import org.dijon.Menu;
0022: import org.dijon.MenuBar;
0023: import org.dijon.SplitPane;
0024: import org.dijon.TabbedPane;
0025:
0026: import com.tc.admin.ConnectionContext;
0027: import com.tc.admin.ConnectionListener;
0028: import com.tc.admin.ProductInfo;
0029: import com.tc.admin.ServerConnectionManager;
0030: import com.tc.admin.common.BrowserLauncher;
0031: import com.tc.admin.common.ContactTerracottaAction;
0032: import com.tc.admin.common.OutputStreamListener;
0033: import com.tc.admin.common.XAbstractAction;
0034: import com.tc.admin.common.XTree;
0035: import com.tc.config.Directories;
0036: import com.tc.management.beans.L2MBeanNames;
0037: import com.tc.object.appevent.NonPortableObjectEvent;
0038: import com.tc.servers.ServerSelection;
0039: import com.tc.servers.ServersDialog;
0040: import com.tc.util.runtime.Os;
0041: import com.terracottatech.config.DsoApplication;
0042: import com.terracottatech.config.TcConfigDocument.TcConfig;
0043:
0044: import java.awt.BorderLayout;
0045: import java.awt.Color;
0046: import java.awt.Cursor;
0047: import java.awt.Dimension;
0048: import java.awt.GraphicsConfiguration;
0049: import java.awt.GraphicsDevice;
0050: import java.awt.GraphicsEnvironment;
0051: import java.awt.Insets;
0052: import java.awt.Rectangle;
0053: import java.awt.Toolkit;
0054: import java.awt.event.ActionEvent;
0055: import java.awt.event.ActionListener;
0056: import java.awt.event.ComponentAdapter;
0057: import java.awt.event.ComponentEvent;
0058: import java.awt.event.MouseAdapter;
0059: import java.awt.event.MouseEvent;
0060: import java.awt.event.MouseMotionAdapter;
0061: import java.awt.event.WindowAdapter;
0062: import java.awt.event.WindowEvent;
0063: import java.beans.PropertyChangeEvent;
0064: import java.beans.PropertyChangeListener;
0065: import java.io.File;
0066: import java.io.FileInputStream;
0067: import java.io.FileOutputStream;
0068: import java.io.IOException;
0069: import java.lang.reflect.Method;
0070: import java.net.Socket;
0071: import java.net.URL;
0072: import java.text.MessageFormat;
0073: import java.util.ArrayList;
0074: import java.util.Arrays;
0075: import java.util.Collection;
0076: import java.util.Enumeration;
0077: import java.util.HashMap;
0078: import java.util.Iterator;
0079: import java.util.List;
0080: import java.util.Map;
0081: import java.util.Properties;
0082: import java.util.prefs.Preferences;
0083:
0084: import javax.management.Notification;
0085: import javax.management.NotificationListener;
0086: import javax.management.ObjectName;
0087: import javax.swing.Icon;
0088: import javax.swing.ImageIcon;
0089: import javax.swing.JFileChooser;
0090: import javax.swing.JOptionPane;
0091: import javax.swing.JSplitPane;
0092: import javax.swing.SwingUtilities;
0093: import javax.swing.WindowConstants;
0094: import javax.swing.event.ChangeEvent;
0095: import javax.swing.event.ChangeListener;
0096: import javax.swing.event.DocumentEvent;
0097: import javax.swing.text.Document;
0098: import javax.swing.tree.TreePath;
0099: import javax.swing.tree.TreeSelectionModel;
0100:
0101: public class SessionIntegratorFrame extends Frame {
0102: private static final boolean m_debug = Boolean
0103: .getBoolean("SessionIntegratorFrame.debug");
0104:
0105: private ConfigHelper m_configHelper;
0106: private SplashDialog m_splashDialog;
0107:
0108: private ServersDialog m_serversDialog;
0109: private Properties m_properties;
0110: private SplitPane m_controlSplitter;
0111: private Integer m_controlDividerLocation;
0112: private DividerListener m_dividerListener;
0113: private TabbedPane m_tabbedPane;
0114: private int m_lastSelectedTabIndex;
0115: private WebAppTreeModel m_webAppTreeModel;
0116: private Button m_startButton;
0117: private Button m_stopButton;
0118: private CheckBox m_dsoEnabledToggle;
0119: private boolean m_dsoEnabled;
0120: private XTree m_webAppTree;
0121: private WebAppLinkNode m_lastArmedLink;
0122: private TabbedPane m_configTabbedPane;
0123: private ConfigTextPane m_xmlPane;
0124: private XmlChangeListener m_xmlChangeListener;
0125: private ConfigProblemTable m_configProblemTable;
0126: private ConfigProblemTableModel m_configProblemTableModel;
0127:
0128: private ProcessOutputView m_l2OutView;
0129: private Label m_l2Label;
0130: private ProcessStatus m_l2Status;
0131: private boolean m_handlingAppEvent;
0132: private L2StartupListener m_l2StartupListener;
0133: private L2ShutdownListener m_l2ShutdownListener;
0134: private L2ShutdownMonitor m_l2Monitor;
0135: private L2ConnectListener m_l2ConnectListener;
0136: private ServerConnectionManager m_l2ConnectManager;
0137:
0138: private CheckBox m_webServer1EnabledToggle;
0139: private boolean m_webServer1Enabled;
0140: private ProcessOutputView m_webServer1OutView;
0141: private Label m_webServer1Label;
0142: private ProcessStatus m_webServer1Status;
0143: private Button m_webServer1Control;
0144: private WebServer1StartupListener m_webServer1StartupListener;
0145: private WebServer1ShutdownListener m_webServer1ShutdownListener;
0146: private WebServerShutdownMonitor m_webServer1Monitor;
0147:
0148: private CheckBox m_webServer2EnabledToggle;
0149: private boolean m_webServer2Enabled;
0150: private ProcessOutputView m_webServer2OutView;
0151: private Label m_webServer2Label;
0152: private ProcessStatus m_webServer2Status;
0153: private Button m_webServer2Control;
0154: private WebServer2StartupListener m_webServer2StartupListener;
0155: private WebServer2ShutdownListener m_webServer2ShutdownListener;
0156: private WebServerShutdownMonitor m_webServer2Monitor;
0157:
0158: private ImageIcon m_waitingIcon;
0159: private ImageIcon m_readyIcon;
0160: private ImageIcon m_stoppedIcon;
0161:
0162: private Icon m_startIcon;
0163: private Icon m_stopIcon;
0164:
0165: private InstrumentedClassesPanel m_instrumentedClassesPanel;
0166: private TransientFieldsPanel m_transientFieldsPanel;
0167: private BootClassesPanel m_bootClassesPanel;
0168: private ModulesPanel m_modulesPanel;
0169:
0170: private ServersAction m_serversAction;
0171: private ImportWebAppAction m_importAction;
0172: private HelpAction m_helpAction;
0173:
0174: private boolean m_askRestart;
0175: private boolean m_restarting;
0176: private boolean m_quitting;
0177:
0178: private ServerSelection m_serverSelection;
0179:
0180: private static String SHOW_SPLASH_PREF_KEY = "ShowSplash";
0181: private static String LAST_DIR_PREF_KEY = "LastDirectory";
0182: private static String DSO_ENABLED_PREF_KEY = "DsoEnabled";
0183: private static String WEBSERVER1_ENABLED_PREF_KEY = "WebServer1Enabled";
0184: private static String WEBSERVER2_ENABLED_PREF_KEY = "WebServer2Enabled";
0185:
0186: private static final String BAT_EXTENSION = ".bat";
0187: private static final String SH_EXTENSION = ".sh";
0188: private static final String SCRIPT_EXTENSION = getScriptExtension();
0189: private static final String FS = System
0190: .getProperty("file.separator");
0191: private static final String DEFAULT_TC_INSTALL_DIR = getDefaultInstallDir();
0192: private static final String TC_INSTALL_DIR = System.getProperty(
0193: "tc.install.dir", DEFAULT_TC_INSTALL_DIR);
0194: private static final String DEFAULT_SANDBOX_ROOT = TC_INSTALL_DIR
0195: + FS + "tools" + FS + "sessions" + FS
0196: + "configurator-sandbox";
0197: private static final String SANDBOX_ROOT = System.getProperty(
0198: "configurator.sandbox", DEFAULT_SANDBOX_ROOT);
0199: private static final String L2_LABEL = "Terracotta Server";
0200: private static final String L2_STARTUP_SCRIPT = "start-tc-server"
0201: + SCRIPT_EXTENSION;
0202: private static final String L2_SHUTDOWN_SCRIPT = "stop-tc-server"
0203: + SCRIPT_EXTENSION;
0204: private static final String L2_STARTUP_TRIGGER = "Terracotta Server has started up";
0205: private static final int SERVER1_PORT = 9081;
0206: private static final String WEBSERVER_STARTUP_SCRIPT = "start-web-server"
0207: + SCRIPT_EXTENSION;
0208: private static final String WEBSERVER_SHUTDOWN_SCRIPT = "stop-web-server"
0209: + SCRIPT_EXTENSION;
0210: private static final int SERVER2_PORT = 9082;
0211: private static final String HELP_DOC = TC_INSTALL_DIR + FS + "docs"
0212: + FS + "TerracottaSessionsQuickStart.html";
0213:
0214: private static final Cursor LINK_CURSOR = Cursor
0215: .getPredefinedCursor(Cursor.HAND_CURSOR);
0216: private static final Cursor STANDARD_CURSOR = Cursor
0217: .getDefaultCursor();
0218:
0219: private static final int CONTROL_TAB_INDEX = 0;
0220: private static final int CONFIG_TAB_INDEX = 1;
0221: private static final int MONITOR_TAB_INDEX = 2;
0222:
0223: private static final int XML_TAB_INDEX = 4;
0224: private static final String XML_TAB_LABEL = "tc-config.xml";
0225:
0226: private static final String QUERY_START_MSG = "Start the system?";
0227: private static final String QUERY_RESTART_MSG = "Restart the system?";
0228:
0229: private static final String WAITING_LABEL = " [Waiting...]";
0230: private static final String STARTING_LABEL = " [Starting...]";
0231: private static final String STOPPING_LABEL = " [Stopping...]";
0232: private static final String READY_LABEL = " [Ready]";
0233: private static final String STOPPED_LABEL = " [Stopped]";
0234: private static final String FAILED_LABEL = " [Failed]";
0235: private static final String DISABLED_LABEL = " [Disabled]";
0236:
0237: public SessionIntegratorFrame() {
0238: super (SessionIntegrator.getContext().topRes
0239: .getFrame("MainFrame"));
0240:
0241: setTitle(getBundleString("title"));
0242: setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
0243:
0244: m_serverSelection = ServerSelection.getInstance();
0245: m_configHelper = new ConfigHelper(m_serverSelection);
0246:
0247: initMenubar();
0248: loadIcons();
0249:
0250: m_tabbedPane = (TabbedPane) findComponent("MainTabbedPane");
0251: m_tabbedPane.addChangeListener(new ChangeListener() {
0252: public void stateChanged(ChangeEvent e) {
0253: if (m_lastSelectedTabIndex == CONFIG_TAB_INDEX
0254: && isXmlModified()) {
0255: if (querySaveConfig(JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
0256: m_askRestart = isL2Ready();
0257: }
0258: }
0259: if (m_askRestart) {
0260: String msg = "Configuration has been modified.\n\n"
0261: + QUERY_RESTART_MSG;
0262: queryRestart(msg);
0263: }
0264: m_askRestart = false;
0265: m_lastSelectedTabIndex = m_tabbedPane
0266: .getSelectedIndex();
0267: }
0268: });
0269:
0270: m_startButton = (Button) findComponent("StartButton");
0271: m_startButton.addActionListener(new ActionListener() {
0272: public void actionPerformed(ActionEvent ae) {
0273: startSystem();
0274: }
0275: });
0276: m_startIcon = m_startButton.getIcon();
0277:
0278: m_stopButton = (Button) findComponent("StopButton");
0279: m_stopButton.addActionListener(new ActionListener() {
0280: public void actionPerformed(ActionEvent ae) {
0281: stopSystem();
0282: }
0283: });
0284: m_stopIcon = m_stopButton.getIcon();
0285:
0286: m_dsoEnabledToggle = (CheckBox) findComponent("DSOEnabledToggle");
0287: m_dsoEnabledToggle.addActionListener(new ActionListener() {
0288: public void actionPerformed(ActionEvent ae) {
0289: setDsoEnabled(m_dsoEnabledToggle.isSelected());
0290: }
0291: });
0292:
0293: m_webAppTree = (XTree) findComponent("WebAppTree");
0294: m_webAppTreeModel = new WebAppTreeModel(this , getWebApps());
0295: m_webAppTree.setModel(m_webAppTreeModel);
0296: m_webAppTree.getSelectionModel().setSelectionMode(
0297: TreeSelectionModel.SINGLE_TREE_SELECTION);
0298: m_webAppTree.addMouseListener(new MouseAdapter() {
0299: public void mouseClicked(MouseEvent me) {
0300: if (me.getClickCount() == 1) {
0301: TreePath path = m_webAppTree.getPathForLocation(me
0302: .getX(), me.getY());
0303:
0304: if (path != null) {
0305: Object leaf = path.getLastPathComponent();
0306:
0307: if (leaf instanceof WebAppLinkNode) {
0308: WebAppLinkNode node = (WebAppLinkNode) leaf;
0309:
0310: if (node.isReady()) {
0311: openPage(node.getLink());
0312: }
0313: }
0314: }
0315: }
0316: }
0317: });
0318: m_webAppTree.addMouseMotionListener(new MouseMotionAdapter() {
0319: public void mouseMoved(MouseEvent me) {
0320: TreePath path = m_webAppTree.getPathForLocation(me
0321: .getX(), me.getY());
0322:
0323: if (path != null) {
0324: Object leaf = path.getLastPathComponent();
0325:
0326: if (leaf instanceof WebAppLinkNode) {
0327: WebAppLinkNode node = (WebAppLinkNode) leaf;
0328: Cursor c = m_webAppTree.getCursor();
0329:
0330: if (m_lastArmedLink != node) {
0331: if (m_lastArmedLink != null) {
0332: m_lastArmedLink.setArmed(false);
0333: }
0334: node.setArmed(true);
0335: m_lastArmedLink = node;
0336: }
0337:
0338: if (node.isReady() && c != LINK_CURSOR) {
0339: m_webAppTree.setCursor(LINK_CURSOR);
0340: }
0341: return;
0342: }
0343: }
0344:
0345: if (m_lastArmedLink != null) {
0346: m_lastArmedLink.setArmed(false);
0347: m_lastArmedLink = null;
0348: }
0349:
0350: m_webAppTree.setCursor(null);
0351: }
0352: });
0353:
0354: m_configTabbedPane = (TabbedPane) findComponent("ConfigTabbedPane");
0355: m_configProblemTable = (ConfigProblemTable) findComponent("ConfigProblemTable");
0356: m_configProblemTableModel = new ConfigProblemTableModel();
0357: m_configProblemTable.setModel(m_configProblemTableModel);
0358: m_configProblemTable.addMouseListener(new MouseAdapter() {
0359: public void mouseClicked(MouseEvent me) {
0360: if (me.getClickCount() == 2) {
0361: int row = m_configProblemTable.getSelectedRow();
0362: XmlError error = m_configProblemTableModel
0363: .getError(row);
0364:
0365: m_xmlPane.selectError(error);
0366: }
0367: }
0368: });
0369:
0370: m_xmlPane = (ConfigTextPane) findComponent("XMLPane");
0371: m_xmlChangeListener = new XmlChangeListener();
0372: initXmlPane();
0373:
0374: Container configPaneToolbar = (Container) findComponent("ConfigPaneToolbar");
0375: Button button;
0376: Insets emptyInsets = new Insets(1, 1, 1, 1);
0377: button = (Button) configPaneToolbar.findComponent("SaveButton");
0378: button.setAction(m_xmlPane.getSaveAction());
0379: button.setText(null);
0380: button.setMargin(emptyInsets);
0381: button = (Button) configPaneToolbar.findComponent("UndoButton");
0382: button.setAction(m_xmlPane.getUndoAction());
0383: button.setText(null);
0384: button.setMargin(emptyInsets);
0385: button = (Button) configPaneToolbar.findComponent("RedoButton");
0386: button.setAction(m_xmlPane.getRedoAction());
0387: button.setText(null);
0388: button.setMargin(emptyInsets);
0389:
0390: button = (Button) configPaneToolbar.findComponent("CutButton");
0391: button.setAction(m_xmlPane.getCutAction());
0392: button.setText(null);
0393: button.setMargin(emptyInsets);
0394: button = (Button) configPaneToolbar.findComponent("CopyButton");
0395: button.setAction(m_xmlPane.getCopyAction());
0396: button.setText(null);
0397: button.setMargin(emptyInsets);
0398: button = (Button) configPaneToolbar
0399: .findComponent("PasteButton");
0400: button.setAction(m_xmlPane.getPasteAction());
0401: button.setText(null);
0402: button.setMargin(emptyInsets);
0403:
0404: m_l2OutView = (ProcessOutputView) findComponent("L2OutView");
0405: m_l2Label = (Label) findComponent("L2Label");
0406: m_l2Status = new ProcessStatus("L2");
0407: m_l2StartupListener = new L2StartupListener();
0408: m_l2ShutdownListener = new L2ShutdownListener();
0409:
0410: m_webServer1EnabledToggle = (CheckBox) findComponent("Tomcat1EnabledToggle");
0411: m_webServer1OutView = (ProcessOutputView) findComponent("Tomcat1OutView");
0412: m_webServer1Label = (Label) findComponent("Tomcat1Label");
0413: m_webServer1Status = new ProcessStatus(getWebServer1Label());
0414: m_webServer1Control = (Button) findComponent("Tomcat1Control");
0415: m_webServer1StartupListener = new WebServer1StartupListener();
0416: m_webServer1ShutdownListener = new WebServer1ShutdownListener();
0417:
0418: Preferences prefs = getPreferences();
0419:
0420: m_webServer1Enabled = prefs.getBoolean(
0421: WEBSERVER1_ENABLED_PREF_KEY, true);
0422: m_webServer1EnabledToggle.setSelected(m_webServer1Enabled);
0423: m_webServer1EnabledToggle
0424: .addActionListener(new ActionListener() {
0425: public void actionPerformed(ActionEvent ae) {
0426: setWebServer1Enabled(m_webServer1EnabledToggle
0427: .isSelected());
0428: }
0429: });
0430: m_webServer1Label.setText(getWebServer1Label());
0431: m_webServer1Control.setMargin(new Insets(0, 0, 0, 0));
0432: m_webServer1Control.addActionListener(new ActionListener() {
0433: public void actionPerformed(ActionEvent ae) {
0434: disableControls();
0435: m_webAppTreeModel.updateLinks(false,
0436: isWebServer2Ready());
0437: toggleWebServer1();
0438: }
0439: });
0440:
0441: m_webServer2EnabledToggle = (CheckBox) findComponent("Tomcat2EnabledToggle");
0442: m_webServer2OutView = (ProcessOutputView) findComponent("Tomcat2OutView");
0443: m_webServer2Label = (Label) findComponent("Tomcat2Label");
0444: m_webServer2Status = new ProcessStatus(getWebServer1Label());
0445: m_webServer2Control = (Button) findComponent("Tomcat2Control");
0446: m_webServer2StartupListener = new WebServer2StartupListener();
0447: m_webServer2ShutdownListener = new WebServer2ShutdownListener();
0448:
0449: m_webServer2Enabled = prefs.getBoolean(
0450: WEBSERVER2_ENABLED_PREF_KEY, true);
0451: m_webServer2EnabledToggle.setSelected(m_webServer2Enabled);
0452: m_webServer2EnabledToggle
0453: .addActionListener(new ActionListener() {
0454: public void actionPerformed(ActionEvent ae) {
0455: setWebServer2Enabled(m_webServer2EnabledToggle
0456: .isSelected());
0457: }
0458: });
0459: m_webServer2Label.setText(getWebServer2Label());
0460: m_webServer2Control.setMargin(new Insets(0, 0, 0, 0));
0461: m_webServer2Control.addActionListener(new ActionListener() {
0462: public void actionPerformed(ActionEvent ae) {
0463: disableControls();
0464: m_webAppTreeModel.updateLinks(isWebServer1Ready(),
0465: false);
0466: toggleWebServer2();
0467: }
0468: });
0469:
0470: m_instrumentedClassesPanel = (InstrumentedClassesPanel) findComponent("InstrumentedClassesPanel");
0471: m_transientFieldsPanel = (TransientFieldsPanel) findComponent("TransientFieldsPanel");
0472: m_bootClassesPanel = (BootClassesPanel) findComponent("BootClassesPanel");
0473: m_modulesPanel = (ModulesPanel) findComponent("ModulesPanel");
0474:
0475: setupEditorPanels();
0476:
0477: m_startButton.setEnabled(isWebServer1Enabled()
0478: || isWebServer2Enabled() || isDsoEnabled());
0479:
0480: if (prefs.getBoolean(SHOW_SPLASH_PREF_KEY, true)) {
0481: addComponentListener(new ComponentAdapter() {
0482: public void componentShown(ComponentEvent e) {
0483: openSplashDialog(this );
0484: }
0485: });
0486: }
0487:
0488: addWindowListener(new WindowAdapter() {
0489: public void windowClosing(WindowEvent we) {
0490: quit();
0491: }
0492: });
0493:
0494: m_l2ConnectListener = new L2ConnectListener();
0495: m_l2ConnectManager = new ServerConnectionManager("localhost",
0496: m_configHelper.getJmxPort(), false, m_l2ConnectListener);
0497: testShutdownL2();
0498: testShutdownWebServer1();
0499: testShutdownWebServer2();
0500:
0501: setDsoEnabled(m_dsoEnabled = prefs.getBoolean(
0502: DSO_ENABLED_PREF_KEY, false));
0503: }
0504:
0505: static String getBundleString(String key) {
0506: return SessionIntegrator.getContext().getMessage(key);
0507: }
0508:
0509: static String formatBundleString(String key, Object[] args) {
0510: return MessageFormat.format(getBundleString(key), args);
0511: }
0512:
0513: static String getTCInstallDir() {
0514: return TC_INSTALL_DIR;
0515: }
0516:
0517: public static String getSandBoxRoot() {
0518: return SANDBOX_ROOT;
0519: }
0520:
0521: ConfigHelper getConfigHelper() {
0522: return m_configHelper;
0523: }
0524:
0525: private static String getScriptExtension() {
0526: return Os.isWindows() ? BAT_EXTENSION : SH_EXTENSION;
0527: }
0528:
0529: private static String getDefaultInstallDir() {
0530: try {
0531: return Directories.getInstallationRoot().getAbsolutePath();
0532: } catch (Exception e) {
0533: String msg = e.getMessage();
0534: String title = getBundleString("title");
0535: int msgType = JOptionPane.ERROR_MESSAGE;
0536:
0537: JOptionPane.showMessageDialog(null, msg, title, msgType);
0538: e.printStackTrace();
0539: System.exit(-1);
0540: }
0541:
0542: return null;
0543: }
0544:
0545: private void openSplashDialog(ComponentAdapter splashListener) {
0546: DictionaryResource topRes = SessionIntegrator.getContext().topRes;
0547: DialogResource dialogRes = topRes.getDialog("SplashDialog");
0548:
0549: m_splashDialog = new SplashDialog(this , true);
0550:
0551: m_splashDialog.load(dialogRes);
0552: ((Button) m_splashDialog.findComponent("HelpButton"))
0553: .addActionListener(m_helpAction);
0554: ((Button) m_splashDialog.findComponent("ImportButton"))
0555: .addActionListener(m_importAction);
0556: ((Button) m_splashDialog.findComponent("SkipButton"))
0557: .addActionListener(new ActionListener() {
0558: public void actionPerformed(ActionEvent ae) {
0559: checkShowSplashToggle();
0560: m_splashDialog.setVisible(false);
0561: }
0562: });
0563: m_splashDialog.center(this );
0564: m_splashDialog.addWindowListener(new WindowAdapter() {
0565: public void windowClosed(WindowEvent we) {
0566: checkShowSplashToggle();
0567: }
0568: });
0569: if (splashListener != null) {
0570: removeComponentListener(splashListener);
0571: }
0572: m_splashDialog.setVisible(true);
0573: }
0574:
0575: private void checkShowSplashToggle() {
0576: if (m_splashDialog != null) {
0577: CheckBox toggle = (CheckBox) m_splashDialog
0578: .findComponent("NoShowSplash");
0579: Preferences prefs = getPreferences();
0580:
0581: prefs
0582: .putBoolean(SHOW_SPLASH_PREF_KEY, !toggle
0583: .isSelected());
0584: storePreferences();
0585: }
0586: }
0587:
0588: private void loadIcons() {
0589: URL url;
0590: String iconsPrefix = "/com/tc/admin/icons/";
0591: Class clas = getClass();
0592:
0593: if ((url = clas.getResource(iconsPrefix
0594: + "progress_task_yellow.gif")) != null) {
0595: m_waitingIcon = new ImageIcon(url);
0596: }
0597:
0598: if ((url = clas.getResource(iconsPrefix
0599: + "progress_task_green.gif")) != null) {
0600: m_readyIcon = new ImageIcon(url);
0601: }
0602:
0603: if ((url = clas.getResource(iconsPrefix
0604: + "progress_task_red.gif")) != null) {
0605: m_stoppedIcon = new ImageIcon(url);
0606: }
0607: }
0608:
0609: private void initMenubar() {
0610: MenuBar menuBar = new MenuBar();
0611: Menu menu = new Menu(getBundleString("file.menu.label"));
0612:
0613: menu.add(m_serversAction = new ServersAction());
0614:
0615: menu.add(m_importAction = new ImportWebAppAction());
0616: menu.add(new ExportConfigurationAction());
0617: menu.add(new QuitAction());
0618: menuBar.add(menu);
0619:
0620: menu = new Menu(getBundleString("output.menu.label"));
0621: menu.add(new ClearOutputAction());
0622: menuBar.add(menu);
0623:
0624: menu = new Menu(getBundleString("help.menu.label"));
0625: menu.add(m_helpAction = new HelpAction());
0626: menu.add(new ShowSplashAction());
0627: menu.addSeparator();
0628: menu.add(new ContactTerracottaAction(
0629: getBundleString("visit.forums.title"),
0630: getBundleString("forums.url")));
0631: menu.add(new ContactTerracottaAction(
0632: getBundleString("contact.support.title"),
0633: getBundleString("support.url")));
0634: /*
0635: * menu.add(new ContactTerracottaAction(getBundleString("contact.field.eng.title"),
0636: * getBundleString("field.eng.url"))); menu.add(new ContactTerracottaAction(getBundleString("contact.sales.title"),
0637: * getBundleString("sales.url")));
0638: */
0639: menu.addSeparator();
0640: menu.add(new AboutAction());
0641: menuBar.add(menu);
0642:
0643: setMenubar(menuBar);
0644: }
0645:
0646: class ClearOutputAction extends XAbstractAction {
0647: ClearOutputAction() {
0648: super (getBundleString("clear.all.action.name"));
0649: String uri = "/com/tc/admin/icons/clear_co.gif";
0650: setSmallIcon(new ImageIcon(getClass().getResource(uri)));
0651: }
0652:
0653: public void actionPerformed(ActionEvent e) {
0654: m_l2OutView.setText("");
0655: m_webServer1OutView.setText("");
0656: m_webServer2OutView.setText("");
0657: }
0658: }
0659:
0660: class HelpAction extends XAbstractAction {
0661: HelpAction() {
0662: super (getBundleString("help.action.name"));
0663: String uri = "/com/tc/admin/icons/help.gif";
0664: setSmallIcon(new ImageIcon(getClass().getResource(uri)));
0665: }
0666:
0667: public void actionPerformed(ActionEvent e) {
0668: showHelp();
0669: }
0670: }
0671:
0672: class ShowSplashAction extends XAbstractAction {
0673: ShowSplashAction() {
0674: super (getBundleString("show.splash.action.name"));
0675: }
0676:
0677: public void actionPerformed(ActionEvent e) {
0678: if (m_splashDialog != null) {
0679: m_splashDialog.center(SessionIntegratorFrame.this );
0680: m_splashDialog.setVisible(true);
0681: } else {
0682: openSplashDialog(null);
0683: }
0684: }
0685: }
0686:
0687: class AboutAction extends XAbstractAction {
0688: Dialog m_aboutDialog;
0689:
0690: AboutAction() {
0691: super (getBundleString("about.action.label"));
0692: }
0693:
0694: public void actionPerformed(ActionEvent ae) {
0695: if (m_aboutDialog == null) {
0696: SessionIntegratorContext cntx = SessionIntegrator
0697: .getContext();
0698:
0699: m_aboutDialog = new Dialog(SessionIntegratorFrame.this ,
0700: true);
0701: m_aboutDialog.load((DialogResource) cntx.topRes
0702: .child("AboutDialog"));
0703:
0704: ConfiguratorInfoPanel info;
0705: String title = SessionIntegratorFrame.this .getTitle();
0706: info = (ConfiguratorInfoPanel) m_aboutDialog
0707: .findComponent("ConfiguratorInfoPanel");
0708: info.init(title, new ProductInfo());
0709: Label monikerLabel = (Label) m_aboutDialog
0710: .findComponent("MonikerLabel");
0711: monikerLabel.setText(title);
0712: Button okButton = (Button) m_aboutDialog
0713: .findComponent("OKButton");
0714: m_aboutDialog.getRootPane().setDefaultButton(okButton);
0715: okButton.addActionListener(new ActionListener() {
0716: public void actionPerformed(ActionEvent ae2) {
0717: m_aboutDialog.setVisible(false);
0718: }
0719: });
0720: }
0721:
0722: m_aboutDialog.pack();
0723: m_aboutDialog.center(SessionIntegratorFrame.this );
0724: m_aboutDialog.setVisible(true);
0725: }
0726: }
0727:
0728: private void showHelp() {
0729: try {
0730: openPage("file://" + StringUtils.replace(HELP_DOC, FS, "/"));
0731: } catch (Exception e) {
0732: m_configHelper.openError(
0733: getBundleString("show.help.error"), e);
0734: }
0735: }
0736:
0737: class ServersAction extends XAbstractAction {
0738: ServersAction() {
0739: super (getBundleString("servers.action.name"));
0740: String uri = "/com/tc/admin/icons/thread_obj.gif";
0741: setSmallIcon(new ImageIcon(getClass().getResource(uri)));
0742: }
0743:
0744: public void actionPerformed(ActionEvent e) {
0745: if (m_serversDialog == null) {
0746: DialogResource dialogRes = SessionIntegrator
0747: .getContext().topRes.getDialog("ServersDialog");
0748: m_serversDialog = new ServersDialog(
0749: SessionIntegratorFrame.this );
0750: m_serversDialog.load(dialogRes);
0751: m_serversDialog.addAcceptListener(new ActionListener() {
0752: public void actionPerformed(ActionEvent ae) {
0753: int oldSelectedServerIndex = m_serverSelection
0754: .getSelectedServerIndex();
0755: m_serversDialog.finishEditing();
0756: m_serversDialog.setVisible(false);
0757: m_serverSelection.setServers(m_serversDialog
0758: .getServers());
0759: m_serverSelection
0760: .setSelectedServerIndex(m_serversDialog
0761: .getSelectedServerIndex());
0762:
0763: m_webServer1Label.setText(getWebServer1Label());
0764: m_webServer2Label.setText(getWebServer2Label());
0765:
0766: // If the selected server changes, rebuild the webapp tree.
0767: if (oldSelectedServerIndex != m_serverSelection
0768: .getSelectedServerIndex()) {
0769: m_webAppTreeModel = new WebAppTreeModel(
0770: SessionIntegratorFrame.this ,
0771: getWebApps());
0772: m_webAppTree.setModel(m_webAppTreeModel);
0773: }
0774:
0775: // Each time the user changes anything in the ServersDialog, cause JSP's to be recompiled.
0776: WebApp[] webApps = getWebApps();
0777: for (int i = 0; i < webApps.length; i++) {
0778: touch(webApps[i]);
0779: }
0780:
0781: m_configHelper = new ConfigHelper(
0782: m_serverSelection);
0783: m_l2ConnectManager
0784: .setJMXPortNumber(m_configHelper
0785: .getJmxPort());
0786: initXmlPane();
0787: setupEditorPanels();
0788: }
0789: });
0790: }
0791:
0792: m_serversDialog.setSelection(m_serverSelection);
0793: m_serversDialog.center(SessionIntegratorFrame.this );
0794: m_serversDialog.setVisible(true);
0795: m_serversDialog.toFront();
0796: }
0797:
0798: }
0799:
0800: class ImportWebAppAction extends XAbstractAction {
0801: ImportWebAppAction() {
0802: super (getBundleString("import.webapp.action.name"));
0803: String uri = "/com/tc/admin/icons/import_wiz.gif";
0804: setSmallIcon(new ImageIcon(getClass().getResource(uri)));
0805: }
0806:
0807: public void actionPerformed(ActionEvent e) {
0808: SwingUtilities.invokeLater(new Runnable() {
0809: public void run() {
0810: importWebApp();
0811: }
0812: });
0813: }
0814: }
0815:
0816: void exportConfiguration() {
0817: JFileChooser chooser = new JFileChooser();
0818: File currentDir = getLastDirectory();
0819:
0820: chooser.setMultiSelectionEnabled(false);
0821: if (currentDir != null) {
0822: chooser.setCurrentDirectory(currentDir);
0823: }
0824:
0825: int returnVal = chooser.showSaveDialog(this );
0826: if (returnVal == JFileChooser.APPROVE_OPTION) {
0827: File file = chooser.getSelectedFile();
0828: m_configHelper.saveAs(file, m_xmlPane.getText());
0829: }
0830: }
0831:
0832: class ExportConfigurationAction extends XAbstractAction {
0833: ExportConfigurationAction() {
0834: super (getBundleString("export.configuration.action.name"));
0835: String uri = "/com/tc/admin/icons/export_wiz.gif";
0836: setSmallIcon(new ImageIcon(getClass().getResource(uri)));
0837: }
0838:
0839: public void actionPerformed(ActionEvent e) {
0840: SwingUtilities.invokeLater(new Runnable() {
0841: public void run() {
0842: exportConfiguration();
0843: }
0844: });
0845: }
0846: }
0847:
0848: class QuitAction extends XAbstractAction {
0849: QuitAction() {
0850: super (getBundleString("quit.action.name"));
0851: }
0852:
0853: public void actionPerformed(ActionEvent ae) {
0854: quit();
0855: }
0856: }
0857:
0858: private void quit() {
0859: if (m_quitting) {
0860: return;
0861: }
0862:
0863: if (isXmlModified()) {
0864: if (querySaveConfig() == JOptionPane.CANCEL_OPTION) {
0865: return;
0866: }
0867: }
0868:
0869: if (anyWaiting()) {
0870: m_quitting = true;
0871: showQuittingDialog();
0872: } else if (anyReady()) {
0873: m_quitting = true;
0874: showQuittingDialog();
0875:
0876: try {
0877: m_webAppTreeModel.updateLinks(false, false);
0878: disableControls();
0879: stopAll();
0880: } catch (Exception e) {
0881: SessionIntegrator.getContext().client.shutdown();
0882: }
0883: } else {
0884: SessionIntegrator.getContext().client.shutdown();
0885: }
0886: }
0887:
0888: void showQuittingDialog() {
0889: Dialog dialog = new Dialog(this , getTitle());
0890: Label label = new Label(getBundleString("quitting.dialog.msg"));
0891:
0892: label.setBorder(new EmptyBorder(10, 20, 10, 20));
0893: dialog.getContentPane().add(label);
0894: dialog.pack();
0895: dialog.center(this );
0896: dialog.setVisible(true);
0897: }
0898:
0899: class XmlChangeListener extends DocumentAdapter {
0900: public void insertUpdate(DocumentEvent e) {
0901: setXmlModified(true);
0902: }
0903:
0904: public void removeUpdate(DocumentEvent e) {
0905: setXmlModified(true);
0906: }
0907: }
0908:
0909: private void setXmlModified(boolean xmlModified) {
0910: m_xmlModified = xmlModified;
0911:
0912: if (m_configTabbedPane != null) {
0913: String label = XML_TAB_LABEL + (xmlModified ? "*" : "");
0914: m_configTabbedPane.setTitleAt(XML_TAB_INDEX, label);
0915: }
0916: }
0917:
0918: private boolean m_xmlModified;
0919:
0920: private boolean isXmlModified() {
0921: return m_xmlModified;
0922: }
0923:
0924: private File getLastDirectory() {
0925: String lastDir = getPreferences().get(LAST_DIR_PREF_KEY, null);
0926: return lastDir != null ? new File(lastDir) : null;
0927: }
0928:
0929: private void setLastDirectory(File dir) {
0930: getPreferences().put(LAST_DIR_PREF_KEY, dir.getAbsolutePath());
0931: storePreferences();
0932: }
0933:
0934: private void importWebApp() {
0935: JFileChooser chooser = new JFileChooser();
0936: File currentDir = getLastDirectory();
0937:
0938: chooser
0939: .setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
0940: chooser.setMultiSelectionEnabled(false);
0941: chooser.setFileFilter(WebAppFileFilter.getInstance());
0942: if (currentDir != null) {
0943: chooser.setCurrentDirectory(currentDir);
0944: }
0945:
0946: int returnVal = chooser.showOpenDialog(this );
0947: if (returnVal == JFileChooser.APPROVE_OPTION) {
0948: File file = chooser.getSelectedFile();
0949:
0950: setLastDirectory(chooser.getCurrentDirectory());
0951: if ((file.isDirectory() && !isWebAppDir(file))
0952: || (file.isFile() && !file.getName().endsWith(
0953: ".war"))) {
0954: showPlainMessage(getBundleString("not.war.msg"));
0955: return;
0956: }
0957:
0958: installWebApp(file);
0959: }
0960: }
0961:
0962: private static boolean isWebAppDir(File dir) {
0963: File webInf = new File(dir, "WEB-INF");
0964: return webInf.exists() && new File(webInf, "web.xml").exists();
0965: }
0966:
0967: private com.tc.servers.ServerInfo getSelectedServer() {
0968: return m_serverSelection.getSelectedServer();
0969: }
0970:
0971: private String getSelectedServerName() {
0972: return getSelectedServer().getName();
0973: }
0974:
0975: private String getSelectedServerLabel() {
0976: return getSelectedServer().getLabel();
0977: }
0978:
0979: private String getSelectedServerStartupTrigger() {
0980: return getSelectedServer().getStartupTrigger();
0981: }
0982:
0983: private String getSelectedServerApplicationPath() {
0984: return getSelectedServer().getApplicationPath();
0985: }
0986:
0987: private Map getenv() {
0988: try {
0989: Method method = System.class.getMethod("getenv",
0990: new Class[] {});
0991:
0992: if (method != null) {
0993: return (Map) method.invoke(null, new Object[] {});
0994: }
0995: } catch (Throwable e) {/**/
0996: }
0997:
0998: return null;
0999: }
1000:
1001: private String[] getSelectedServerEnvironment() {
1002: Map sysEnv = getenv();
1003:
1004: if (sysEnv != null) {
1005: Map env = new HashMap();
1006: Properties serverEnv = getSelectedServer().toProperties();
1007:
1008: env.putAll(sysEnv);
1009: env.putAll(serverEnv);
1010:
1011: ArrayList list = new ArrayList();
1012: Iterator iter = env.keySet().iterator();
1013: String key;
1014: String val;
1015:
1016: while (iter.hasNext()) {
1017: key = (String) iter.next();
1018: val = (String) env.get(key);
1019:
1020: list.add(key + "=" + val);
1021: }
1022:
1023: try {
1024: File tmpfile = File.createTempFile("terracotta", null);
1025: list.add("TMPFILE=" + tmpfile.getAbsolutePath());
1026: tmpfile.delete();
1027: } catch (IOException ioe) {
1028: ioe.printStackTrace();
1029: }
1030:
1031: return (String[]) list.toArray(new String[env.size()]);
1032: }
1033:
1034: return getSelectedServer().toEnvironment();
1035: }
1036:
1037: private String getWebServer1Area() {
1038: return SANDBOX_ROOT + FS + getSelectedServerName() + FS
1039: + SERVER1_PORT + FS
1040: + getSelectedServerApplicationPath();
1041: }
1042:
1043: private String getWebServer2Area() {
1044: return SANDBOX_ROOT + FS + getSelectedServerName() + FS
1045: + SERVER2_PORT + FS
1046: + getSelectedServerApplicationPath();
1047: }
1048:
1049: private void installWebApp(File file) {
1050: try {
1051: boolean exists = new File(getWebServer1Area(), file
1052: .getName()).exists();
1053:
1054: installWebAppFile(file);
1055: addToModel(file);
1056:
1057: String msg = formatBundleString(
1058: "install.webapp.success.msg", new Object[] { file });
1059: if (exists && anyReady()) {
1060: String explainMsg = getBundleString("install.webapp.restart.msg");
1061: queryRestart(msg + "\n\n" + explainMsg + "\n\n"
1062: + QUERY_RESTART_MSG);
1063: } else {
1064: showPlainMessage(msg);
1065: }
1066:
1067: if (m_splashDialog != null) {
1068: m_splashDialog.setVisible(false);
1069: m_splashDialog = null;
1070: }
1071: } catch (Exception e) {
1072: String msg = formatBundleString(
1073: "install.webapp.failure.msg", new Object[] { file });
1074: m_configHelper.openError(msg, e);
1075: }
1076: }
1077:
1078: private void installWebAppFile(File file) throws Exception {
1079: String webServer1Area = getWebServer1Area();
1080: String webServer2Area = getWebServer2Area();
1081:
1082: if (file.isFile()) {
1083: copyFileToDirectory(file, new File(webServer1Area), false);
1084: copyFileToDirectory(file, new File(webServer2Area), false);
1085: } else if (file.isDirectory()) {
1086: copyDirectory(file, new File(webServer1Area));
1087: copyDirectory(file, new File(webServer2Area));
1088: }
1089: }
1090:
1091: private static void copyFileToDirectory(File file, File dir,
1092: boolean keepDate) throws IOException {
1093: if (dir.exists() && !dir.isDirectory()) {
1094: throw new IllegalArgumentException(
1095: getBundleString("destination.not.directory.msg"));
1096: } else {
1097: FileUtils.copyFile(file, new File(dir, file.getName()),
1098: keepDate);
1099: }
1100: }
1101:
1102: private void removeWebApp(WebApp webApp) throws Exception {
1103: removeWebAppFile(webApp);
1104: removeFromModel(webApp);
1105: }
1106:
1107: private void removeWebAppFile(WebApp webApp) throws Exception {
1108: File file = new File(webApp.getPath());
1109: String fileName = file.getName();
1110: String webServer1Area = getWebServer1Area();
1111: String webServer2Area = getWebServer2Area();
1112:
1113: safeDeleteFile(new File(webServer1Area, fileName));
1114: safeDeleteFile(new File(webServer2Area, fileName));
1115:
1116: if (fileName.endsWith(".war")) {
1117: String name = webApp.getName();
1118:
1119: safeDeleteFile(new File(webServer1Area, name));
1120: safeDeleteFile(new File(webServer2Area, name));
1121: }
1122: }
1123:
1124: private static void safeDeleteFile(File file) {
1125: if (file.exists()) {
1126: try {
1127: FileUtils.forceDelete(file);
1128: } catch (IOException ioe) {/**/
1129: }
1130: }
1131: }
1132:
1133: private static void safeCloseSocket(Socket socket) {
1134: try {
1135: socket.close();
1136: } catch (Exception e) {/**/
1137: }
1138: }
1139:
1140: void refresh(WebApp webApp) {
1141: File srcFile = new File(webApp.getPath());
1142:
1143: if (!srcFile.exists()) {
1144: Object[] args = { webApp.getName(),
1145: srcFile.getAbsolutePath() };
1146: String msg = formatBundleString("src.webapp.not.found.msg",
1147: args);
1148: int type = JOptionPane.YES_NO_OPTION;
1149: int answer = showConfirmDialog(msg, type);
1150:
1151: if (answer == JOptionPane.YES_OPTION) {
1152: remove(webApp);
1153: }
1154: } else {
1155: try {
1156: removeWebAppFile(webApp);
1157: installWebAppFile(srcFile);
1158:
1159: String msg = formatBundleString("refresh.success.msg",
1160: new Object[] { webApp.getPath() });
1161: queryRestart(msg
1162: + "\n\n"
1163: + (anyReady() ? QUERY_RESTART_MSG
1164: : QUERY_START_MSG));
1165: } catch (Exception e) {
1166: String msg = formatBundleString("refresh.failure.msg",
1167: new Object[] { webApp });
1168: m_configHelper.openError(msg, e);
1169: }
1170: }
1171: }
1172:
1173: /**
1174: * Update the timestamp on archived webapps or JSP's from exploded WAR's so they get recompiled. We do this after the
1175: * user has used the 'Servers' dialog because they may have changed the Java runtime from 1.5+ down to 1.4. If we
1176: * don't force the JSP's to be recompiled, they'll get a ClassFormatVersion exception when they hit the page.
1177: */
1178: void touch(WebApp webApp) {
1179: long time = System.currentTimeMillis();
1180: String[] serverAreas = new String[] { getWebServer1Area(),
1181: getWebServer2Area() };
1182:
1183: for (int j = 0; j < serverAreas.length; j++) {
1184: File destFile = new File(serverAreas[j], webApp.getName());
1185:
1186: if (!destFile.isDirectory()) {
1187: destFile.setLastModified(time);
1188: } else {
1189: Collection fileSet = FileUtils.listFiles(destFile,
1190: new String[] { "jsp" }, true);
1191: File[] files = FileUtils
1192: .convertFileCollectionToFileArray(fileSet);
1193:
1194: for (int i = 0; i < files.length; i++) {
1195: files[i].setLastModified(time);
1196: }
1197: }
1198: }
1199: }
1200:
1201: void remove(WebApp webApp) {
1202: if (anyReady()) {
1203: showPlainMessage(getBundleString("cannot.remove.while.running.msg"));
1204: } else {
1205: try {
1206: removeWebApp(webApp);
1207:
1208: File srcFile = new File(webApp.getPath());
1209: String msg = formatBundleString("remove.success.msg",
1210: new Object[] { srcFile.getAbsolutePath() });
1211: showPlainMessage(msg);
1212: } catch (Exception e) {
1213: String msg = formatBundleString("remove.failure.msg",
1214: new Object[] { webApp });
1215: m_configHelper.openError(msg, e);
1216: }
1217: }
1218: }
1219:
1220: private static void copyDirectory(File fromDir, File toDir)
1221: throws Exception {
1222: File destDir = new File(toDir, fromDir.getName());
1223:
1224: if (destDir.exists()) {
1225: FileUtils.cleanDirectory(destDir);
1226: }
1227:
1228: Collection fileSet = FileUtils.listFiles(fromDir, null, true);
1229: File[] files = FileUtils
1230: .convertFileCollectionToFileArray(fileSet);
1231: String prefix = fromDir.getAbsolutePath() + FS;
1232: int prefixLen = prefix.length();
1233: String relPath;
1234:
1235: for (int i = 0; i < files.length; i++) {
1236: relPath = files[i].getAbsolutePath().substring(prefixLen);
1237: FileUtils.copyFile(files[i], new File(destDir, relPath));
1238: }
1239: }
1240:
1241: private void addToModel(File file) throws Exception {
1242: String name = file.getName();
1243: String path = file.getAbsolutePath();
1244: int dot = name.lastIndexOf('.');
1245:
1246: if (dot != -1) {
1247: name = name.substring(0, dot);
1248: }
1249:
1250: path = StringUtils.replace(path, FS, "/");
1251: m_properties.setProperty(name, path);
1252:
1253: File webAppProps = m_serverSelection
1254: .getSelectedServerWebAppProperties();
1255: FileOutputStream out = new FileOutputStream(webAppProps);
1256: Exception err = null;
1257:
1258: try {
1259: m_properties.store(out, null);
1260:
1261: WebAppNode webAppNode = m_webAppTreeModel.add(new WebApp(
1262: name, path));
1263: TreePath webAppPath = new TreePath(webAppNode.getPath());
1264:
1265: m_webAppTree.expandPath(webAppPath);
1266: m_webAppTree.setSelectionPath(webAppPath);
1267:
1268: if (m_configHelper.ensureWebApplication(name)) {
1269: m_configHelper.save();
1270: initXmlPane();
1271: }
1272: } catch (Exception e) {
1273: err = e;
1274: } finally {
1275: IOUtils.closeQuietly(out);
1276: }
1277:
1278: if (err != null) {
1279: throw err;
1280: }
1281: }
1282:
1283: private void removeFromModel(WebApp webApp) throws Exception {
1284: File file = new File(webApp.getPath());
1285: String name = file.getName();
1286: int dot = name.lastIndexOf('.');
1287:
1288: if (dot != -1) {
1289: name = name.substring(0, dot);
1290: }
1291:
1292: m_properties.remove(name);
1293:
1294: File webAppProps = m_serverSelection
1295: .getSelectedServerWebAppProperties();
1296: FileOutputStream out = new FileOutputStream(webAppProps);
1297: Exception err = null;
1298:
1299: try {
1300: m_properties.store(out, null);
1301: m_webAppTreeModel.remove(name);
1302: if (m_configHelper.removeWebApplication(name)) {
1303: m_configHelper.save();
1304: initXmlPane();
1305: }
1306: } catch (Exception e) {
1307: err = e;
1308: } finally {
1309: IOUtils.closeQuietly(out);
1310: }
1311:
1312: if (err != null) {
1313: throw err;
1314: }
1315: }
1316:
1317: void saveAndStart() {
1318: m_configHelper.save();
1319: setXmlModified(false);
1320: m_startButton.doClick();
1321: }
1322:
1323: private boolean isDsoEnabled() {
1324: return m_dsoEnabled;
1325: }
1326:
1327: private void setDsoEnabled(boolean enabled) {
1328: getPreferences().putBoolean(DSO_ENABLED_PREF_KEY,
1329: m_dsoEnabled = enabled);
1330: storePreferences();
1331:
1332: m_dsoEnabledToggle.setSelected(enabled);
1333:
1334: m_l2Label.setIcon(null);
1335: m_l2Label.setText(L2_LABEL + (enabled ? "" : DISABLED_LABEL));
1336: m_l2Label.setEnabled(m_dsoEnabled);
1337: m_l2OutView.setEnabled(m_dsoEnabled);
1338:
1339: setMonitorTabEnabled(enabled);
1340:
1341: m_startButton.setEnabled(enabled || isWebServer1Enabled()
1342: || isWebServer2Enabled());
1343:
1344: if (isL2Ready()) {
1345: queryRestart();
1346: }
1347: }
1348:
1349: private void selectControlTab() {
1350: m_tabbedPane.setSelectedIndex(CONTROL_TAB_INDEX);
1351: }
1352:
1353: private boolean isConfigTabSelected() {
1354: return (m_tabbedPane.getSelectedIndex() == CONFIG_TAB_INDEX);
1355: }
1356:
1357: private void setConfigTabEnabled(boolean enabled) {
1358: m_tabbedPane.setEnabledAt(CONFIG_TAB_INDEX, enabled);
1359: }
1360:
1361: private void setConfigTabForeground(Color fg) {
1362: m_tabbedPane.setForegroundAt(CONFIG_TAB_INDEX, fg);
1363: }
1364:
1365: private void setMonitorTabEnabled(boolean enabled) {
1366: m_tabbedPane.setEnabledAt(MONITOR_TAB_INDEX, enabled);
1367: }
1368:
1369: private int querySaveConfig() {
1370: return querySaveConfig(JOptionPane.YES_NO_CANCEL_OPTION);
1371: }
1372:
1373: private int querySaveConfig(int msgType) {
1374: String msg = getBundleString("query.save.config.msg");
1375: int answer = showConfirmDialog(msg, msgType);
1376:
1377: if (answer == JOptionPane.YES_OPTION) {
1378: saveConfig();
1379: }
1380:
1381: return answer;
1382: }
1383:
1384: private int queryRestart() {
1385: return queryRestart(QUERY_RESTART_MSG);
1386: }
1387:
1388: private int queryRestart(String msg) {
1389: int type = JOptionPane.YES_NO_OPTION;
1390: int answer = showConfirmDialog(msg, type);
1391:
1392: if (answer == JOptionPane.YES_OPTION) {
1393: m_startButton.doClick();
1394: }
1395:
1396: return answer;
1397: }
1398:
1399: private WebApp[] getWebApps() {
1400: File webAppProps = m_serverSelection
1401: .getSelectedServerWebAppProperties();
1402:
1403: m_properties = new Properties();
1404:
1405: try {
1406: m_properties.load(new FileInputStream(webAppProps));
1407: } catch (IOException ioe) {
1408: m_properties.setProperty("Cart", "");
1409: m_properties.setProperty("DepartmentTaskList", "");
1410: m_properties.setProperty("Townsend", "");
1411: }
1412:
1413: Enumeration names = m_properties.keys();
1414: ArrayList appList = new ArrayList();
1415: String name;
1416:
1417: while (names.hasMoreElements()) {
1418: name = (String) names.nextElement();
1419: appList
1420: .add(new WebApp(name, m_properties
1421: .getProperty(name)));
1422: }
1423:
1424: return WebAppComparable.sort((WebApp[]) appList
1425: .toArray(new WebApp[0]));
1426: }
1427:
1428: private void setupEditorPanels() {
1429: try {
1430: TcConfig config = m_configHelper.getConfig();
1431:
1432: if (config == null) {
1433: config = m_configHelper.ensureConfig();
1434: m_configHelper.save();
1435: setXmlModified(false);
1436: }
1437:
1438: DsoApplication dsoApp = config.getApplication().getDso();
1439:
1440: m_instrumentedClassesPanel.setup(dsoApp);
1441: m_transientFieldsPanel.setup(dsoApp);
1442: m_bootClassesPanel.setup(dsoApp);
1443: m_modulesPanel.setup(config.getClients());
1444: } catch (Exception e) {
1445: m_configHelper.openError(
1446: getBundleString("configuration.load.failure.msg"),
1447: e);
1448: }
1449: }
1450:
1451: private void initXmlPane() {
1452: Document xmlDocument = m_xmlPane.getDocument();
1453:
1454: xmlDocument.removeDocumentListener(m_xmlChangeListener);
1455: m_xmlPane.load(m_configHelper.getConfigFilePath());
1456: xmlDocument.addDocumentListener(m_xmlChangeListener);
1457: setXmlModified(false);
1458: }
1459:
1460: private void updateXmlPane() {
1461: Document xmlDocument = m_xmlPane.getDocument();
1462:
1463: xmlDocument.removeDocumentListener(m_xmlChangeListener);
1464: m_xmlPane.set(m_configHelper.getConfigText());
1465: xmlDocument.addDocumentListener(m_xmlChangeListener);
1466: setXmlModified(true);
1467: }
1468:
1469: void setConfigErrors(List errorList) {
1470: m_configProblemTableModel.setErrors(errorList);
1471: setConfigTabForeground(errorList.size() > 0 ? Color.RED : null);
1472: }
1473:
1474: public static void openPath(String path) throws IOException {
1475: if (Os.isWindows()) {
1476: String[] cmd = { "cmd.exe", "/C", path };
1477: Runtime.getRuntime().exec(cmd);
1478: } else {
1479: openPage(path);
1480: }
1481: }
1482:
1483: public static void openPage(String page) {
1484: BrowserLauncher.openURL(page);
1485: }
1486:
1487: void startSystem() {
1488: try {
1489: if (isXmlModified()) {
1490: if (querySaveConfig() == JOptionPane.CANCEL_OPTION) {
1491: return;
1492: }
1493: }
1494: m_webAppTreeModel.updateLinks(false, false);
1495: disableControls();
1496: startAll();
1497: } catch (Exception e) {
1498: e.printStackTrace();
1499: }
1500: }
1501:
1502: private void startAll() throws Exception {
1503: m_restarting = anyReady();
1504: startServers();
1505: }
1506:
1507: private void startServers() {
1508: trace("startServers");
1509:
1510: m_l2Label.setIcon(m_l2Status.isReady() ? m_waitingIcon : null);
1511:
1512: if (m_restarting) {
1513: if (isL2Ready()) {
1514: m_l2Label.setIcon(m_waitingIcon);
1515: m_l2Label.setText(L2_LABEL + WAITING_LABEL);
1516:
1517: if (m_webServer1Status.isReady()
1518: || m_webServer2Status.isReady()) {
1519: stopWebServers();
1520: } else {
1521: startL2();
1522: }
1523: } else {
1524: startWebServers();
1525: }
1526: } else {
1527: if (isDsoEnabled()) {
1528: if (isWebServer1Enabled()) {
1529: m_webServer1Label.setIcon(m_waitingIcon);
1530: m_webServer1Label.setText(getWebServer1Label()
1531: + WAITING_LABEL);
1532: }
1533: if (isWebServer2Enabled()) {
1534: m_webServer2Label.setIcon(m_waitingIcon);
1535: m_webServer2Label.setText(getWebServer2Label()
1536: + WAITING_LABEL);
1537: }
1538: startL2();
1539: } else {
1540: startWebServers();
1541: }
1542: }
1543: }
1544:
1545: private boolean isWebServer1Enabled() {
1546: return m_webServer1Enabled;
1547: }
1548:
1549: private void setWebServer1Enabled(boolean enabled) {
1550: getPreferences().putBoolean(WEBSERVER1_ENABLED_PREF_KEY,
1551: m_webServer1Enabled = enabled);
1552: storePreferences();
1553:
1554: m_startButton.setEnabled(enabled || isWebServer2Enabled()
1555: || isDsoEnabled());
1556: }
1557:
1558: private boolean isWebServer2Enabled() {
1559: return m_webServer2Enabled;
1560: }
1561:
1562: private void setWebServer2Enabled(boolean enabled) {
1563: getPreferences().putBoolean(WEBSERVER2_ENABLED_PREF_KEY,
1564: m_webServer2Enabled = enabled);
1565: storePreferences();
1566:
1567: m_startButton.setEnabled(enabled || isWebServer1Enabled()
1568: || isDsoEnabled());
1569: }
1570:
1571: private String getWebServer1Label() {
1572: return getSelectedServerLabel() + "-" + SERVER1_PORT;
1573: }
1574:
1575: private String getWebServer2Label() {
1576: return getSelectedServerLabel() + "-" + SERVER2_PORT;
1577: }
1578:
1579: private void startWebServers() {
1580: if (isWebServer1Enabled()) {
1581: startWebServer1();
1582: }
1583: if (isWebServer2Enabled()) {
1584: startWebServer2();
1585: }
1586: }
1587:
1588: private void stopWebServers() {
1589: trace("stopWebServers");
1590:
1591: if (isWebServer1Ready()) {
1592: stopWebServer1();
1593: }
1594: if (isWebServer2Ready()) {
1595: stopWebServer2();
1596: }
1597: }
1598:
1599: // Begin -- L2 process control support
1600:
1601: private boolean isL2Accessible() {
1602: try {
1603: if (m_l2ConnectManager.testIsConnected()) {
1604: return true;
1605: }
1606: } catch (Exception e) {/**/
1607: }
1608:
1609: return false;
1610: }
1611:
1612: private void testShutdownL2() {
1613: if (isL2Accessible()) {
1614: stopL2();
1615: }
1616: }
1617:
1618: private void startL2() {
1619: if (System.getProperty("tc.server") != null) {
1620: m_l2OutView.append("Using external Terracotta servers: "
1621: + System.getProperty("tc.server"));
1622: startWebServers();
1623: return;
1624: }
1625:
1626: trace("startL2");
1627:
1628: if (m_l2Monitor != null) {
1629: m_l2Monitor.cancel();
1630: while (true) {
1631: try {
1632: m_l2Monitor.join(0);
1633: break;
1634: } catch (InterruptedException ie) {/**/
1635: }
1636: }
1637: m_l2Monitor = null;
1638: }
1639:
1640: if (isL2Ready()) {
1641: m_l2Status.setRestarting(true);
1642: restartL2();
1643: return;
1644: }
1645:
1646: if (isDsoEnabled()) {
1647: _startL2();
1648: }
1649: }
1650:
1651: private void _startL2() {
1652: trace("_startL2");
1653:
1654: m_l2Status.setWaiting();
1655: m_l2Label.setIcon(m_waitingIcon);
1656: m_l2Label.setText(L2_LABEL + STARTING_LABEL);
1657: m_l2OutView.setListener(m_l2StartupListener);
1658: m_l2OutView.setListenerTrigger(L2_STARTUP_TRIGGER);
1659: startL2AndNotify(L2_STARTUP_SCRIPT, m_l2OutView,
1660: m_l2StartupListener);
1661: }
1662:
1663: private void startL2AndNotify(final String startScript,
1664: final ProcessOutputView outView,
1665: final StartupListener startupListener) {
1666: trace("Starting L2");
1667:
1668: Process process;
1669: try {
1670: process = invokeScript(startScript,
1671: new String[] { getSelectedServerName() });
1672: IOUtils.closeQuietly(process.getOutputStream());
1673: new ProcessMonitor(process,
1674: new ProcessTerminationListener() {
1675: public void processTerminated(int exitCode) {
1676: if (m_debug) {
1677: outView
1678: .append("L2 terminated with exitCode="
1679: + exitCode);
1680: }
1681: if (exitCode != 0) {
1682: SwingUtilities
1683: .invokeLater(new Runnable() {
1684: public void run() {
1685: startupListener
1686: .processFailed();
1687: }
1688: });
1689: }
1690: }
1691: });
1692: } catch (Exception e) {
1693: startupListener.startupError(e);
1694: return;
1695: }
1696:
1697: m_l2OutView.start(process);
1698:
1699: new L2StartupMonitor(process, startupListener).start();
1700: }
1701:
1702: class L2StartupMonitor extends Thread {
1703: private Process m_process;
1704: private StartupListener m_startupListener;
1705:
1706: L2StartupMonitor(Process process, StartupListener listener) {
1707: super ();
1708:
1709: m_process = process;
1710: m_startupListener = listener;
1711: }
1712:
1713: public void run() {
1714: while (true) {
1715: if (m_process != null) {
1716: try {
1717: int exitCode = m_process.exitValue();
1718:
1719: if (exitCode != 0) {
1720: SwingUtilities.invokeLater(new Runnable() {
1721: public void run() {
1722: m_startupListener.processFailed();
1723: }
1724: });
1725: return;
1726: } else {
1727: m_process = null;
1728: }
1729: } catch (IllegalThreadStateException itse) {/**/
1730: }
1731:
1732: if (isL2Accessible()) {
1733: return;
1734: }
1735:
1736: try {
1737: sleep(1000);
1738: } catch (InterruptedException ignore) {/**/
1739: }
1740: }
1741: }
1742: }
1743: }
1744:
1745: class L2StartupListener implements StartupListener,
1746: OutputStreamListener {
1747: public void processFailed() {
1748: trace("L2.processFailed");
1749:
1750: if (m_webServer1Status.isReady()) {
1751: stopWebServer1();
1752: } else {
1753: m_webServer1Label.setIcon(null);
1754: m_webServer1Label.setText(getWebServer1Label());
1755: }
1756:
1757: if (m_webServer2Status.isReady()) {
1758: stopWebServer2();
1759: } else {
1760: m_webServer2Label.setIcon(null);
1761: m_webServer2Label.setText(getWebServer2Label());
1762: }
1763:
1764: m_l2Label.setIcon(m_stoppedIcon);
1765: m_l2Label.setText(L2_LABEL + FAILED_LABEL);
1766: m_l2Status.setFailed();
1767:
1768: testEnableControls();
1769: }
1770:
1771: public void startupError(Exception e) {
1772: trace("L2.startupError exception=" + e.getMessage());
1773: if (m_debug)
1774: e.printStackTrace();
1775:
1776: m_webServer1Label.setIcon(null);
1777: m_webServer1Label.setText(getWebServer1Label());
1778: m_webServer2Label.setIcon(null);
1779: m_webServer2Label.setText(getWebServer2Label());
1780:
1781: m_l2Label.setIcon(m_stoppedIcon);
1782: m_l2Label.setText(L2_LABEL + FAILED_LABEL);
1783: m_l2Status.setFailed();
1784:
1785: testEnableControls();
1786: }
1787:
1788: public void triggerEncountered() {
1789: m_l2OutView.setListener(null);
1790: processReady();
1791: }
1792:
1793: public void processReady() {
1794: trace("L2.processReady");
1795:
1796: m_l2Label.setIcon(m_readyIcon);
1797: m_l2Label.setText(L2_LABEL + READY_LABEL);
1798: m_l2Status.setReady();
1799:
1800: startWebServers();
1801: waitForMBean();
1802:
1803: m_l2Monitor = new L2ShutdownMonitor(m_l2ShutdownListener);
1804: m_l2Monitor.start();
1805:
1806: testEnableControls();
1807: }
1808: }
1809:
1810: private void restartL2() {
1811: stopL2(isDsoEnabled());
1812: }
1813:
1814: private void stopL2() {
1815: stopL2(false);
1816: }
1817:
1818: private void stopL2(boolean restart) {
1819: if (System.getProperty("tc.server") != null) {
1820: if (m_webServer1Status.isReady()
1821: || m_webServer2Status.isReady()) {
1822: stopWebServers();
1823: }
1824: return;
1825: }
1826:
1827: if (m_l2Monitor != null) {
1828: m_l2Monitor.cancel();
1829: while (true) {
1830: try {
1831: m_l2Monitor.join(0);
1832: break;
1833: } catch (InterruptedException ie) {/**/
1834: }
1835: }
1836: m_l2Monitor = null;
1837: }
1838:
1839: m_l2Status.setWaiting();
1840: m_l2Label.setIcon(m_waitingIcon);
1841: m_l2Label.setText(L2_LABEL + STOPPING_LABEL);
1842: m_l2ShutdownListener.setRestart(restart);
1843:
1844: stopL2AndNotify(L2_SHUTDOWN_SCRIPT, m_l2OutView, m_configHelper
1845: .getJmxPort(), m_l2ShutdownListener);
1846: }
1847:
1848: private void stopL2AndNotify(final String stopScript,
1849: final ProcessOutputView outView, final int port,
1850: final ShutdownListener shutdownListener) {
1851: trace("Stopping L2");
1852:
1853: Process process;
1854: try {
1855: process = invokeScript(stopScript,
1856: new String[] { getSelectedServerName() });
1857: } catch (Exception e) {
1858: shutdownListener.processError(e);
1859: return;
1860: }
1861:
1862: m_l2Monitor = new L2ShutdownMonitor(process, shutdownListener);
1863: m_l2Monitor.start();
1864: }
1865:
1866: class L2ShutdownListener implements ShutdownListener {
1867: boolean m_restart = false;
1868:
1869: void setRestart(boolean restart) {
1870: m_restart = restart;
1871: }
1872:
1873: public void processError(Exception e) {
1874: trace("L2.processError");
1875: if (m_debug)
1876: e.printStackTrace();
1877:
1878: if (m_quitting) {
1879: m_l2Label.setIcon(m_readyIcon);
1880: m_l2Label.setText(L2_LABEL + READY_LABEL);
1881: m_l2Status.setReady();
1882: } else {
1883: m_l2Label.setIcon(m_stoppedIcon);
1884: m_l2Label.setText(L2_LABEL + FAILED_LABEL);
1885: m_l2Status.setFailed();
1886: }
1887:
1888: testEnableControls();
1889: }
1890:
1891: public void processFailed(String errorBuf) {
1892: trace("L2.processFailed");
1893:
1894: m_l2OutView.append(errorBuf);
1895:
1896: if (m_quitting) {
1897: m_l2Label.setIcon(m_readyIcon);
1898: m_l2Label.setText(L2_LABEL + READY_LABEL);
1899: m_l2Status.setReady();
1900: } else {
1901: m_l2Label.setIcon(m_stoppedIcon);
1902: m_l2Label.setText(L2_LABEL + FAILED_LABEL);
1903: m_l2Status.setFailed();
1904: }
1905:
1906: testEnableControls();
1907: }
1908:
1909: public void processStopped() {
1910: m_l2Monitor = null;
1911: m_l2ConnectManager.getConnectionContext().reset();
1912: m_l2Status.setInactive();
1913:
1914: if (m_restart) {
1915: startL2();
1916: m_restart = false;
1917: } else {
1918: if (m_webServer1Status.isReady()
1919: || m_webServer2Status.isReady()) {
1920: stopWebServers();
1921: }
1922:
1923: m_l2Label.setIcon(m_stoppedIcon);
1924: m_l2Label.setText(L2_LABEL + STOPPED_LABEL);
1925: }
1926:
1927: testEnableControls();
1928: }
1929: }
1930:
1931: class L2ShutdownMonitor extends Thread {
1932: private Process m_process;
1933: private ShutdownListener m_shutdownListener;
1934: private boolean m_stop;
1935:
1936: L2ShutdownMonitor(ShutdownListener listener) {
1937: this (null, listener);
1938: }
1939:
1940: L2ShutdownMonitor(Process process, ShutdownListener listener) {
1941: super ();
1942:
1943: m_process = process;
1944: m_shutdownListener = listener;
1945: }
1946:
1947: public void run() {
1948: ProcessWaiter waiter = null;
1949:
1950: if (m_process != null) {
1951: waiter = new ProcessWaiter(m_process);
1952: waiter.start();
1953: }
1954:
1955: while (!m_stop) {
1956: if (m_process != null) {
1957: try {
1958: int exitCode = m_process.exitValue();
1959:
1960: if (exitCode != 0) {
1961: final String errorBuf = waiter
1962: .getErrorBuffer();
1963: SwingUtilities.invokeLater(new Runnable() {
1964: public void run() {
1965: m_shutdownListener
1966: .processFailed(errorBuf);
1967: }
1968: });
1969: return;
1970: } else {
1971: m_process = null;
1972: }
1973: } catch (IllegalThreadStateException itse) {/**/
1974: }
1975: }
1976:
1977: if (!m_stop) {
1978: if (!isL2Accessible()) {
1979: SwingUtilities.invokeLater(new Runnable() {
1980: public void run() {
1981: m_shutdownListener.processStopped();
1982: }
1983: });
1984: return;
1985: }
1986: }
1987:
1988: try {
1989: sleep(1000);
1990: } catch (InterruptedException ignore) {/**/
1991: }
1992: }
1993: }
1994:
1995: void cancel() {
1996: m_stop = true;
1997: }
1998: }
1999:
2000: class DSOAppEventListener implements NotificationListener {
2001: public void handleNotification(Notification notification,
2002: Object handback) {
2003: final Object event = notification.getSource();
2004:
2005: if (event instanceof NonPortableObjectEvent) {
2006: m_handlingAppEvent = true;
2007:
2008: SwingUtilities.invokeLater(new Runnable() {
2009: public void run() {
2010: SessionIntegratorFrame.this .toFront();
2011: handleNonPortableReason((NonPortableObjectEvent) event);
2012: }
2013: });
2014: }
2015: }
2016: }
2017:
2018: private static final String NON_PORTABLE_DIALOG_SIZE = "NonPortableDialogSize";
2019: private static final String NON_PORTABLE_DIALOG_ISSUES_SPLIT_LOCATION = "NonPortableDialogIssuesSplitLocation";
2020:
2021: private void handleNonPortableReason(NonPortableObjectEvent event) {
2022: ContainerResource res = (ContainerResource) SessionIntegrator
2023: .getContext().topRes
2024: .getComponent("NonPortableObjectPanel");
2025: NonPortableObjectPanel panel = new NonPortableObjectPanel(res,
2026: this );
2027: Dialog dialog = new Dialog(this , this .getTitle(), true);
2028: Container cp = (Container) dialog.getContentPane();
2029: cp.setLayout(new BorderLayout());
2030: cp.add(panel);
2031: panel.setEvent(event);
2032: dialog.pack();
2033: SplitPane issuesSplitter = (SplitPane) panel
2034: .findComponent("IssuesSplitter");
2035: Preferences prefs = getPreferences();
2036: String s = prefs.get(NON_PORTABLE_DIALOG_ISSUES_SPLIT_LOCATION,
2037: null);
2038: if (s != null) {
2039: issuesSplitter.setDividerLocation(parseInt(s));
2040: }
2041: if ((s = prefs.get(NON_PORTABLE_DIALOG_SIZE, null)) != null) {
2042: dialog.setSize(parseSizeString(s));
2043: }
2044: dialog.center(this );
2045: dialog.setVisible(true);
2046: prefs.put(NON_PORTABLE_DIALOG_SIZE, getSizeString(dialog));
2047: prefs.put(NON_PORTABLE_DIALOG_ISSUES_SPLIT_LOCATION, Integer
2048: .toString(issuesSplitter.getDividerLocation()));
2049: storePreferences();
2050: m_handlingAppEvent = false;
2051: return;
2052: }
2053:
2054: private int showConfirmDialog(Object msg, int msgType) {
2055: return JOptionPane.showConfirmDialog(this , msg, getTitle(),
2056: msgType);
2057: }
2058:
2059: private void showPlainMessage(Object msg) {
2060: JOptionPane.showConfirmDialog(this , msg, getTitle(),
2061: JOptionPane.PLAIN_MESSAGE);
2062: }
2063:
2064: class L2ConnectListener implements ConnectionListener {
2065: public void handleConnection() {/**/
2066: }
2067:
2068: public void handleException() {/**/
2069: }
2070: }
2071:
2072: private void waitForMBean() {
2073: new Thread() {
2074: public void run() {
2075: while (true) {
2076: try {
2077: if (m_l2ConnectManager.testIsConnected()) {
2078: ConnectionContext cc = m_l2ConnectManager
2079: .getConnectionContext();
2080: ObjectName on = cc
2081: .queryName(L2MBeanNames.DSO_APP_EVENTS
2082: .getCanonicalName());
2083:
2084: if (on != null) {
2085: cc.addNotificationListener(on,
2086: new DSOAppEventListener());
2087: return;
2088: }
2089: }
2090: } catch (Exception e) {/**/
2091: }
2092:
2093: try {
2094: sleep(500);
2095: } catch (InterruptedException ie) {/**/
2096: }
2097: }
2098: }
2099: }.start();
2100: }
2101:
2102: private boolean isL2Ready() {
2103: return m_l2Status.isReady();
2104: }
2105:
2106: // End -- L2 process control support
2107:
2108: // Begin -- Server1 process control support
2109:
2110: private void testShutdownWebServer1() {
2111: try {
2112: safeCloseSocket(new Socket("localhost", SERVER1_PORT));
2113: stopWebServer1();
2114: } catch (IOException ioe) {/**/
2115: }
2116: }
2117:
2118: private void startWebServer1() {
2119: if (m_webServer1Monitor != null) {
2120: m_webServer1Monitor.cancel();
2121: m_webServer1Monitor = null;
2122: }
2123:
2124: if (isWebServer1Ready()) {
2125: m_webServer1Status.setRestarting(true);
2126: restartWebServer1();
2127: return;
2128: }
2129:
2130: m_webServer1Label.setIcon(m_waitingIcon);
2131: m_webServer1Label
2132: .setText(getWebServer1Label() + STARTING_LABEL);
2133: m_webServer1Status.setWaiting();
2134: m_webServer1OutView.setListener(m_webServer1StartupListener);
2135: m_webServer1OutView
2136: .setListenerTrigger(getSelectedServerStartupTrigger());
2137: startWebServerAndNotify(m_webServer1OutView, SERVER1_PORT,
2138: m_webServer1StartupListener);
2139: }
2140:
2141: class WebServer1StartupListener implements StartupListener,
2142: OutputStreamListener {
2143: public void startupError(Exception e) {
2144: trace(getSelectedServerLabel()
2145: + "1.startupError exception=" + e.getMessage());
2146:
2147: m_webServer1Label.setIcon(m_stoppedIcon);
2148: m_webServer1Label.setText(getWebServer1Label()
2149: + FAILED_LABEL);
2150: m_webServer1Status.setFailed();
2151:
2152: testEnableControls();
2153: }
2154:
2155: public void processFailed() {
2156: trace(getSelectedServerLabel() + ".processFailed");
2157:
2158: m_webServer1Label.setIcon(m_stoppedIcon);
2159: m_webServer1Label.setText(getWebServer1Label()
2160: + FAILED_LABEL);
2161: m_webServer1Status.setFailed();
2162:
2163: testEnableControls();
2164: }
2165:
2166: public void triggerEncountered() {
2167: m_webServer1OutView.setListener(null);
2168: processReady();
2169: }
2170:
2171: public void processReady() {
2172: trace(getSelectedServerLabel() + "1.processReady");
2173:
2174: m_webServer1Status.setReady();
2175: m_webServer1Label.setIcon(m_readyIcon);
2176: m_webServer1Label.setText(getWebServer1Label()
2177: + READY_LABEL);
2178:
2179: m_webServer1Monitor = new WebServerShutdownMonitor(
2180: SERVER1_PORT, m_webServer1ShutdownListener);
2181: m_webServer1Monitor.start();
2182:
2183: testEnableControls();
2184: }
2185: }
2186:
2187: private void restartWebServer1() {
2188: stopWebServer1(true);
2189: }
2190:
2191: private boolean isWebServer1Ready() {
2192: return m_webServer1Status.isReady();
2193: }
2194:
2195: private void stopWebServer1() {
2196: stopWebServer1(false);
2197: }
2198:
2199: private void stopWebServer1(boolean restart) {
2200: if (m_webServer1Monitor != null) {
2201: m_webServer1Monitor.cancel();
2202: m_webServer1Monitor = null;
2203: }
2204:
2205: m_webServer1Label.setIcon(m_waitingIcon);
2206: m_webServer1Label
2207: .setText(getWebServer1Label() + STOPPING_LABEL);
2208: m_webServer1Status.setWaiting();
2209: m_webServer1ShutdownListener.setRestart(restart);
2210:
2211: stopWebServerAndNotify(m_webServer1OutView, SERVER1_PORT,
2212: m_webServer1ShutdownListener);
2213: }
2214:
2215: class WebServer1ShutdownListener implements ShutdownListener {
2216: boolean m_restart = false;
2217:
2218: void setRestart(boolean restart) {
2219: m_restart = restart;
2220: }
2221:
2222: public void processError(Exception e) {
2223: trace(getSelectedServerLabel()
2224: + "1.processError exception=" + e.getMessage());
2225: if (m_debug)
2226: e.printStackTrace();
2227:
2228: if (!m_quitting) {
2229: m_webServer1Status.setReady();
2230: m_webServer1Label.setIcon(m_readyIcon);
2231: m_webServer1Label.setText(getWebServer1Label()
2232: + READY_LABEL);
2233: } else {
2234: m_webServer1Status.setFailed();
2235: m_webServer1Label.setIcon(m_stoppedIcon);
2236: m_webServer1Label.setText(getWebServer1Label()
2237: + FAILED_LABEL);
2238: }
2239:
2240: testEnableControls();
2241: }
2242:
2243: public void processFailed(String errorBuf) {
2244: trace(getSelectedServerLabel() + "1.processFailed");
2245:
2246: m_webServer1OutView.append(errorBuf);
2247:
2248: if (!m_quitting) {
2249: m_webServer1Status.setReady();
2250: m_webServer1Label.setIcon(m_readyIcon);
2251: m_webServer1Label.setText(getWebServer1Label()
2252: + READY_LABEL);
2253: } else {
2254: m_webServer1Status.setFailed();
2255: m_webServer1Label.setIcon(m_stoppedIcon);
2256: m_webServer1Label.setText(getWebServer1Label()
2257: + FAILED_LABEL);
2258: }
2259:
2260: testEnableControls();
2261: }
2262:
2263: public void processStopped() {
2264: trace(getSelectedServerLabel() + "1.processStopped");
2265:
2266: m_webServer1Monitor = null;
2267: m_webServer1Status.setInactive();
2268: if (m_restarting && isDsoEnabled()) {
2269: m_webServer1Label.setText(getWebServer1Label()
2270: + WAITING_LABEL);
2271: if (m_webServer2Status.isInactive()) {
2272: startL2();
2273: }
2274: } else {
2275: if (m_restart) {
2276: startWebServer1();
2277: } else {
2278: m_webServer1Label.setIcon(m_stoppedIcon);
2279: m_webServer1Label.setText(getWebServer1Label()
2280: + STOPPED_LABEL);
2281: }
2282: }
2283:
2284: testEnableControls();
2285: }
2286: }
2287:
2288: private void toggleWebServer1() {
2289: if (isWebServer1Ready()) {
2290: stopWebServer1();
2291: } else {
2292: startWebServer1();
2293: }
2294: }
2295:
2296: // End -- WebServer1 process control support
2297:
2298: // Begin -- WebServer2 process control support
2299:
2300: private void testShutdownWebServer2() {
2301: try {
2302: safeCloseSocket(new Socket("localhost", SERVER2_PORT));
2303: stopWebServer2();
2304: } catch (IOException ioe) {/**/
2305: }
2306: }
2307:
2308: private void startWebServer2() {
2309: if (m_webServer2Monitor != null) {
2310: m_webServer2Monitor.cancel();
2311: m_webServer2Monitor = null;
2312: }
2313:
2314: if (isWebServer2Ready()) {
2315: m_webServer2Status.setRestarting(true);
2316: restartWebServer2();
2317: return;
2318: }
2319:
2320: m_webServer2Label.setIcon(m_waitingIcon);
2321: m_webServer2Label
2322: .setText(getWebServer2Label() + STARTING_LABEL);
2323: m_webServer2Status.setWaiting();
2324: m_webServer2OutView.setListener(m_webServer2StartupListener);
2325: m_webServer2OutView
2326: .setListenerTrigger(getSelectedServerStartupTrigger());
2327: startWebServerAndNotify(m_webServer2OutView, SERVER2_PORT,
2328: m_webServer2StartupListener);
2329: }
2330:
2331: class WebServer2StartupListener implements StartupListener,
2332: OutputStreamListener {
2333: public void startupError(Exception e) {
2334: trace(getSelectedServerLabel()
2335: + "2.startupError exception=" + e.getMessage());
2336:
2337: m_webServer2Label.setIcon(m_stoppedIcon);
2338: m_webServer2Label.setText(getWebServer2Label()
2339: + FAILED_LABEL);
2340: m_webServer2Status.setFailed();
2341:
2342: testEnableControls();
2343: }
2344:
2345: public void processFailed() {
2346: trace(getSelectedServerLabel() + "2.processFailed");
2347:
2348: m_webServer2Label.setIcon(m_stoppedIcon);
2349: m_webServer2Label.setText(getWebServer2Label()
2350: + FAILED_LABEL);
2351: m_webServer2Status.setFailed();
2352:
2353: testEnableControls();
2354: }
2355:
2356: public void triggerEncountered() {
2357: m_webServer2OutView.setListener(null);
2358: processReady();
2359: }
2360:
2361: public void processReady() {
2362: trace(getSelectedServerLabel() + "2.processReady");
2363:
2364: m_webServer2Status.setReady();
2365: m_webServer2Label.setIcon(m_readyIcon);
2366: m_webServer2Label.setText(getWebServer2Label()
2367: + READY_LABEL);
2368:
2369: m_webServer2Monitor = new WebServerShutdownMonitor(
2370: SERVER2_PORT, m_webServer2ShutdownListener);
2371: m_webServer2Monitor.start();
2372:
2373: testEnableControls();
2374: }
2375: }
2376:
2377: private void restartWebServer2() {
2378: stopWebServer2(true);
2379: }
2380:
2381: private boolean isWebServer2Ready() {
2382: return m_webServer2Status.isReady();
2383: }
2384:
2385: private void stopWebServer2() {
2386: stopWebServer2(false);
2387: }
2388:
2389: private void stopWebServer2(boolean restart) {
2390: if (m_webServer2Monitor != null) {
2391: m_webServer2Monitor.cancel();
2392: m_webServer2Monitor = null;
2393: }
2394:
2395: m_webServer2Label.setIcon(m_waitingIcon);
2396: m_webServer2Label
2397: .setText(getWebServer2Label() + STOPPING_LABEL);
2398: m_webServer2Status.setWaiting();
2399: m_webServer2ShutdownListener.setRestart(restart);
2400:
2401: stopWebServerAndNotify(m_webServer2OutView, SERVER2_PORT,
2402: m_webServer2ShutdownListener);
2403: }
2404:
2405: class WebServer2ShutdownListener implements ShutdownListener {
2406: boolean m_restart = false;
2407:
2408: void setRestart(boolean restart) {
2409: m_restart = restart;
2410: }
2411:
2412: public void processError(Exception e) {
2413: trace(getSelectedServerLabel() + "2.processError");
2414: if (m_debug)
2415: e.printStackTrace();
2416:
2417: if (!m_quitting) {
2418: m_webServer2Status.setReady();
2419: m_webServer2Label.setIcon(m_readyIcon);
2420: m_webServer2Label.setText(getWebServer2Label()
2421: + READY_LABEL);
2422: } else {
2423: m_webServer2Status.setFailed();
2424: m_webServer2Label.setIcon(m_stoppedIcon);
2425: m_webServer2Label.setText(getWebServer2Label()
2426: + FAILED_LABEL);
2427: }
2428:
2429: testEnableControls();
2430: }
2431:
2432: public void processFailed(String errorBuf) {
2433: trace(getSelectedServerLabel() + "2.processFailed");
2434:
2435: m_webServer2OutView.append(errorBuf);
2436:
2437: if (!m_quitting) {
2438: m_webServer2Status.setReady();
2439: m_webServer2Label.setIcon(m_readyIcon);
2440: m_webServer2Label.setText(getWebServer2Label()
2441: + READY_LABEL);
2442: } else {
2443: m_webServer2Status.setFailed();
2444: m_webServer2Label.setIcon(m_stoppedIcon);
2445: m_webServer2Label.setText(getWebServer2Label()
2446: + FAILED_LABEL);
2447: }
2448:
2449: testEnableControls();
2450: }
2451:
2452: public void processStopped() {
2453: trace(getSelectedServerLabel() + "2.processStopped");
2454:
2455: m_webServer2Monitor = null;
2456: m_webServer2Status.setInactive();
2457: if (m_restarting && isDsoEnabled()) {
2458: m_webServer2Label.setText(getWebServer2Label()
2459: + WAITING_LABEL);
2460: if (m_webServer1Status.isInactive()) {
2461: startL2();
2462: }
2463: } else {
2464: if (m_restart) {
2465: startWebServer2();
2466: } else {
2467: m_webServer2Label.setIcon(m_stoppedIcon);
2468: m_webServer2Label.setText(getWebServer2Label()
2469: + STOPPED_LABEL);
2470: }
2471: }
2472:
2473: testEnableControls();
2474: }
2475: }
2476:
2477: private void toggleWebServer2() {
2478: if (isWebServer2Ready()) {
2479: stopWebServer2();
2480: } else {
2481: startWebServer2();
2482: }
2483: }
2484:
2485: // End -- WebServer2 process control support
2486:
2487: // Being -- Process control support
2488:
2489: private Process startWebServerAndNotify(
2490: final ProcessOutputView outView, final int port,
2491: final StartupListener startupListener) {
2492: trace("Starting " + getSelectedServerLabel() + "-" + port);
2493:
2494: Process process;
2495: try {
2496: String dso = isDsoEnabled() ? "dso" : "nodso";
2497: String[] args = new String[] { getSelectedServerName(),
2498: Integer.toString(port), dso };
2499:
2500: process = invokeScript(WEBSERVER_STARTUP_SCRIPT, args);
2501: IOUtils.closeQuietly(process.getOutputStream());
2502: new ProcessMonitor(process,
2503: new ProcessTerminationListener() {
2504: public void processTerminated(int exitCode) {
2505: if (m_debug) {
2506: outView.append(getSelectedServerLabel()
2507: + "-" + port
2508: + " terminated with exitCode="
2509: + exitCode);
2510: }
2511: if (exitCode != 0) {
2512: SwingUtilities
2513: .invokeLater(new Runnable() {
2514: public void run() {
2515: startupListener
2516: .processFailed();
2517: }
2518: });
2519: }
2520: }
2521: });
2522: } catch (Exception e) {
2523: startupListener.startupError(e);
2524: return null;
2525: }
2526:
2527: outView.start(process);
2528:
2529: new WebServerStartupMonitor(process, port, startupListener)
2530: .start();
2531:
2532: return process;
2533: }
2534:
2535: class WebServerStartupMonitor extends Thread {
2536: private Process m_process;
2537: private int m_port;
2538: private StartupListener m_startupListener;
2539:
2540: WebServerStartupMonitor(Process process, int port,
2541: StartupListener listener) {
2542: super ();
2543:
2544: m_process = process;
2545: m_port = port;
2546: m_startupListener = listener;
2547: }
2548:
2549: public void run() {
2550: while (true) {
2551: try {
2552: m_process.exitValue();
2553: SwingUtilities.invokeLater(new Runnable() {
2554: public void run() {
2555: m_startupListener.processFailed();
2556: }
2557: });
2558: return;
2559: } catch (IllegalThreadStateException itse) {/**/
2560: }
2561:
2562: try {
2563: safeCloseSocket(new Socket("localhost", m_port));
2564: return;
2565: } catch (IOException ioe) {/**/
2566: }
2567:
2568: try {
2569: sleep(1000);
2570: } catch (InterruptedException ignore) {/**/
2571: }
2572: }
2573: }
2574: }
2575:
2576: interface ProcessListener {
2577: void startupError(Exception e);
2578:
2579: void startupFailed(String errorBuffer);
2580:
2581: void shutdownError(Exception e);
2582:
2583: void shutdownFailed(String errorBuffer);
2584:
2585: void processReady();
2586:
2587: void processTerminated(int exitCode);
2588: }
2589:
2590: interface StartupListener {
2591: void startupError(Exception e);
2592:
2593: void processFailed();
2594:
2595: void processReady();
2596: }
2597:
2598: interface ShutdownListener {
2599: void processError(Exception e);
2600:
2601: void processFailed(String errorBuffer);
2602:
2603: void processStopped();
2604: }
2605:
2606: private void stopWebServerAndNotify(
2607: final ProcessOutputView outView, final int port,
2608: final ShutdownListener shutdownListener) {
2609: trace("Stopping " + getSelectedServerLabel() + "-" + port);
2610:
2611: try {
2612: safeCloseSocket(new Socket("localhost", port));
2613: } catch (Exception e) {
2614: shutdownListener.processStopped();
2615: return;
2616: }
2617:
2618: Process process;
2619: try {
2620: String[] args = new String[] { getSelectedServerName(),
2621: Integer.toString(port) };
2622:
2623: process = invokeScript(WEBSERVER_SHUTDOWN_SCRIPT, args);
2624: IOUtils.closeQuietly(process.getOutputStream());
2625: } catch (Exception e) {
2626: shutdownListener.processError(e);
2627: return;
2628: }
2629:
2630: new WebServerShutdownMonitor(process, port, shutdownListener)
2631: .start();
2632: }
2633:
2634: class WebServerShutdownMonitor extends Thread {
2635: private Process m_process;
2636: private int m_port;
2637: private ShutdownListener m_shutdownListener;
2638: private boolean m_stop;
2639:
2640: WebServerShutdownMonitor(int port, ShutdownListener listener) {
2641: this (null, port, listener);
2642: }
2643:
2644: WebServerShutdownMonitor(Process process, int port,
2645: ShutdownListener listener) {
2646: super ();
2647:
2648: m_process = process;
2649: m_port = port;
2650: m_shutdownListener = listener;
2651: }
2652:
2653: public void run() {
2654: ProcessWaiter waiter = null;
2655:
2656: if (m_process != null) {
2657: waiter = new ProcessWaiter(m_process);
2658: waiter.start();
2659: }
2660:
2661: while (!m_stop) {
2662: if (m_process != null) {
2663: try {
2664: int exitCode = m_process.exitValue();
2665:
2666: if (exitCode != 0) {
2667: final String errorBuf = waiter
2668: .getErrorBuffer();
2669: SwingUtilities.invokeLater(new Runnable() {
2670: public void run() {
2671: m_shutdownListener
2672: .processFailed(errorBuf);
2673: }
2674: });
2675: return;
2676: } else {
2677: m_process = null;
2678: }
2679: } catch (IllegalThreadStateException itse) {/**/
2680: }
2681: }
2682:
2683: if (!m_stop) {
2684: try {
2685: safeCloseSocket(new Socket("localhost", m_port));
2686: } catch (Exception e) {
2687: SwingUtilities.invokeLater(new Runnable() {
2688: public void run() {
2689: m_shutdownListener.processStopped();
2690: }
2691: });
2692: return;
2693: }
2694: }
2695:
2696: try {
2697: sleep(1000);
2698: } catch (InterruptedException ignore) {/**/
2699: }
2700: }
2701: }
2702:
2703: void cancel() {
2704: m_stop = true;
2705: }
2706: }
2707:
2708: // End -- Process control support
2709:
2710: private void stopAll() throws Exception {
2711: if (m_webServer1Status.isReady()) {
2712: stopWebServer1();
2713: }
2714: if (m_webServer2Status.isReady()) {
2715: stopWebServer2();
2716: }
2717: if (m_l2Status.isReady()) {
2718: stopL2();
2719: }
2720: }
2721:
2722: private String[] append(String[] array1, String[] array2) {
2723: int array1Len = array1.length;
2724: int array2Len = array2.length;
2725: String[] result = new String[array1Len + array2Len];
2726:
2727: for (int i = 0; i < array1Len; i++) {
2728: result[i] = array1[i];
2729: }
2730: for (int i = 0, j = array1Len; i < array2Len; i++, j++) {
2731: result[j] = array2[i];
2732: }
2733:
2734: return result;
2735: }
2736:
2737: private String[] buildScriptCommand(String scriptPath) {
2738: if (Os.isWindows()) {
2739: return new String[] { "cmd.exe", "/C", scriptPath };
2740: } else {
2741: return new String[] { scriptPath };
2742: }
2743: }
2744:
2745: private String[] buildScriptArgs(String[] args) {
2746: return args;
2747: }
2748:
2749: private Process invokeScript(String scriptName, String[] args)
2750: throws Exception {
2751: String[] cmd = buildScriptCommand(SANDBOX_ROOT + FS + "bin"
2752: + FS + scriptName);
2753: String[] env = getSelectedServerEnvironment();
2754: File wd = new File(SANDBOX_ROOT);
2755:
2756: final String[] fullCmd = append(cmd, buildScriptArgs(args));
2757: trace("Invoking script " + Arrays.asList(fullCmd)
2758: + " with working dir " + wd.getAbsolutePath());
2759: return Runtime.getRuntime().exec(fullCmd, env, wd);
2760: }
2761:
2762: private void stopSystem() {
2763: try {
2764: m_webAppTreeModel.updateLinks(false, false);
2765: disableControls();
2766: stopAll();
2767: } catch (Exception e) {
2768: e.printStackTrace();
2769: }
2770: }
2771:
2772: private boolean anyReady() {
2773: return m_l2Status.isReady() || m_webServer1Status.isReady()
2774: || m_webServer2Status.isReady();
2775: }
2776:
2777: private boolean anyRestarting() {
2778: return m_l2Status.isRestarting()
2779: || m_webServer1Status.isRestarting()
2780: || m_webServer2Status.isRestarting();
2781: }
2782:
2783: private boolean anyWaiting() {
2784: return m_l2Status.isWaiting() || m_webServer1Status.isWaiting()
2785: || m_webServer2Status.isWaiting();
2786: }
2787:
2788: private void disableControls() {
2789: m_webServer1EnabledToggle.setEnabled(false);
2790: m_webServer2EnabledToggle.setEnabled(false);
2791: m_dsoEnabledToggle.setEnabled(false);
2792:
2793: m_startButton.setEnabled(false);
2794: m_stopButton.setEnabled(false);
2795:
2796: m_webServer1Control.setVisible(false);
2797: m_webServer2Control.setVisible(false);
2798:
2799: selectControlTab();
2800: setConfigTabEnabled(false);
2801: setMonitorTabEnabled(false);
2802:
2803: m_serversAction.setEnabled(false);
2804: m_importAction.setEnabled(false);
2805: m_webAppTreeModel.setRefreshEnabled(false);
2806: m_webAppTreeModel.setRemoveEnabled(false);
2807:
2808: setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
2809: }
2810:
2811: private synchronized void testEnableControls() {
2812: boolean anyRestarting = anyRestarting();
2813: boolean anyWaiting = anyWaiting();
2814:
2815: if (anyRestarting || anyWaiting) {
2816: return;
2817: }
2818:
2819: m_restarting = false;
2820:
2821: boolean anyReady = anyReady();
2822:
2823: if (!anyWaiting && !anyRestarting && anyReady && m_quitting) {
2824: stopSystem();
2825: }
2826:
2827: if (!anyWaiting && !anyRestarting && !anyReady) {
2828: if (m_quitting) {
2829: SessionIntegrator.getContext().client.shutdown();
2830: return;
2831: } else {
2832: m_serversAction.setEnabled(true);
2833: m_importAction.setEnabled(true);
2834: m_webAppTreeModel.setRefreshEnabled(true);
2835: m_webAppTreeModel.setRemoveEnabled(true);
2836: }
2837: }
2838:
2839: m_webServer1EnabledToggle.setEnabled(!anyWaiting
2840: && !anyRestarting && !anyReady);
2841: m_webServer2EnabledToggle.setEnabled(!anyWaiting
2842: && !anyRestarting && !anyReady);
2843: m_dsoEnabledToggle.setEnabled(!anyWaiting && !anyRestarting
2844: && !anyReady);
2845: m_startButton.setEnabled(!anyWaiting && !anyRestarting);
2846: m_stopButton.setEnabled(!anyWaiting && !anyRestarting
2847: && anyReady);
2848:
2849: if ((!anyWaiting && !anyReady) || anyRestarting) {
2850: m_webServer1Control.setVisible(false);
2851: m_webServer2Control.setVisible(false);
2852:
2853: m_startButton.setText(getBundleString("start.all.label"));
2854: } else {
2855: testEnableWebServer1Control();
2856: testEnableWebServer2Control();
2857:
2858: m_startButton.setText(getBundleString("restart.all.label"));
2859: }
2860:
2861: if (!anyWaiting && !anyRestarting) {
2862: updateLinks();
2863: setConfigTabEnabled(true);
2864: setMonitorTabEnabled(isDsoEnabled());
2865: setCursor(STANDARD_CURSOR);
2866: }
2867: }
2868:
2869: private void testEnableWebServer1Control() {
2870: boolean webServer1NotWaiting = !m_webServer1Status.isWaiting();
2871: m_webServer1Control.setVisible(webServer1NotWaiting);
2872: m_webServer1Control.setEnabled(webServer1NotWaiting);
2873: if (webServer1NotWaiting) {
2874: boolean webServer1Ready = isWebServer1Ready();
2875:
2876: m_webServer1Control.setIcon(webServer1Ready ? m_stopIcon
2877: : m_startIcon);
2878:
2879: String tip = (webServer1Ready ? getBundleString("stop.label")
2880: : getBundleString("start.label"))
2881: + " " + getWebServer1Label();
2882: m_webServer1Control.setToolTipText(tip);
2883: }
2884: }
2885:
2886: private void testEnableWebServer2Control() {
2887: boolean webServer2NotWaiting = !m_webServer2Status.isWaiting();
2888: m_webServer2Control.setVisible(webServer2NotWaiting);
2889: m_webServer2Control.setEnabled(webServer2NotWaiting);
2890: if (webServer2NotWaiting) {
2891: boolean webServer2Ready = isWebServer2Ready();
2892:
2893: m_webServer2Control.setIcon(webServer2Ready ? m_stopIcon
2894: : m_startIcon);
2895:
2896: String tip = (webServer2Ready ? getBundleString("stop.label")
2897: : getBundleString("start.label"))
2898: + " " + getWebServer2Label();
2899: m_webServer2Control.setToolTipText(tip);
2900: }
2901: }
2902:
2903: private void updateLinks() {
2904: m_webAppTreeModel.updateLinks(isWebServer1Ready(),
2905: isWebServer2Ready());
2906: }
2907:
2908: private void saveConfig() {
2909: saveXML(m_xmlPane.getText());
2910: }
2911:
2912: public void modelChanged() {
2913: setupEditorPanels();
2914: updateXmlPane();
2915:
2916: if (false && isL2Ready() && !m_handlingAppEvent) {
2917: queryRestart();
2918: }
2919: }
2920:
2921: public void saveXML(String xmlText) {
2922: m_configHelper.save(xmlText);
2923: setupEditorPanels();
2924: setXmlModified(false);
2925:
2926: if (isConfigTabSelected() && isL2Ready()) {
2927: m_askRestart = true;
2928: }
2929: }
2930:
2931: private static void trace(String msg) {
2932: if (m_debug) {
2933: System.out.println(msg);
2934: System.out.flush();
2935: }
2936: }
2937:
2938: // Everything belows goes into com.tc.ui.common.Frame
2939:
2940: private Preferences getPreferences() {
2941: SessionIntegratorContext cntx = SessionIntegrator.getContext();
2942: return cntx.prefs.node("SessionIntegratorFrame");
2943: }
2944:
2945: private void storePreferences() {
2946: SessionIntegratorContext cntx = SessionIntegrator.getContext();
2947: cntx.client.storePrefs();
2948: }
2949:
2950: public Rectangle getDefaultBounds() {
2951: Toolkit tk = Toolkit.getDefaultToolkit();
2952: Dimension size = tk.getScreenSize();
2953: GraphicsEnvironment env = GraphicsEnvironment
2954: .getLocalGraphicsEnvironment();
2955: GraphicsDevice device = env.getDefaultScreenDevice();
2956: GraphicsConfiguration config = device.getDefaultConfiguration();
2957: Insets insets = tk.getScreenInsets(config);
2958:
2959: size.width -= (insets.left + insets.right);
2960: size.height -= (insets.top + insets.bottom);
2961:
2962: int width = (int) (size.width * 0.75f);
2963: int height = (int) (size.height * 0.66f);
2964:
2965: // center
2966: int x = size.width / 2 - width / 2;
2967: int y = size.height / 2 - height / 2;
2968:
2969: return new Rectangle(x, y, width, height);
2970: }
2971:
2972: private static String getSizeString(java.awt.Window window) {
2973: Dimension size = window.getSize();
2974: return size.width + "," + size.height;
2975: }
2976:
2977: private static String getBoundsString(java.awt.Window window) {
2978: Rectangle b = window.getBounds();
2979: return b.x + "," + b.y + "," + b.width + "," + b.height;
2980: }
2981:
2982: private String getBoundsString() {
2983: return getBoundsString(this );
2984: }
2985:
2986: private static int parseInt(String s) {
2987: try {
2988: return Integer.parseInt(s);
2989: } catch (Exception e) {
2990: return 0;
2991: }
2992: }
2993:
2994: private static Dimension parseSizeString(String s) {
2995: String[] split = s.split(",");
2996: int width = parseInt(split[0]);
2997: int height = parseInt(split[1]);
2998:
2999: return new Dimension(width, height);
3000: }
3001:
3002: private static Rectangle parseBoundsString(String s) {
3003: String[] split = s.split(",");
3004: int x = parseInt(split[0]);
3005: int y = parseInt(split[1]);
3006: int width = parseInt(split[2]);
3007: int height = parseInt(split[3]);
3008:
3009: return new Rectangle(x, y, width, height);
3010: }
3011:
3012: public void storeBounds() {
3013: if (getName() != null
3014: && (getExtendedState() & NORMAL) == NORMAL) {
3015: getPreferences().put("Bounds", getBoundsString());
3016: storePreferences();
3017: }
3018: }
3019:
3020: protected Rectangle getPreferredBounds() {
3021: Preferences prefs = getPreferences();
3022: String s = prefs.get("Bounds", null);
3023:
3024: return s != null ? parseBoundsString(s) : getDefaultBounds();
3025: }
3026:
3027: // TODO: make each SplitPane manage its own preference value.
3028:
3029: private int getSplitPref(JSplitPane splitter) {
3030: Preferences prefs = getPreferences();
3031: Preferences splitPrefs = prefs.node(splitter.getName());
3032:
3033: return splitPrefs.getInt("Split", -1);
3034: }
3035:
3036: private JSplitPane getControlSplitter() {
3037: if (m_controlSplitter == null) {
3038: m_controlSplitter = (SplitPane) findComponent("ControlSplitter");
3039: m_controlDividerLocation = new Integer(
3040: getSplitPref(m_controlSplitter));
3041:
3042: if (m_dividerListener == null) {
3043: m_dividerListener = new DividerListener();
3044: }
3045: }
3046:
3047: return m_controlSplitter;
3048: }
3049:
3050: class DividerListener implements PropertyChangeListener {
3051: public void propertyChange(PropertyChangeEvent pce) {
3052: JSplitPane splitter = (JSplitPane) pce.getSource();
3053: String propName = pce.getPropertyName();
3054:
3055: if (splitter.isShowing() == false
3056: || JSplitPane.DIVIDER_LOCATION_PROPERTY
3057: .equals(propName) == false) {
3058: return;
3059: }
3060:
3061: int divLoc = splitter.getDividerLocation();
3062: Integer divLocObj = new Integer(divLoc);
3063: Preferences prefs = getPreferences();
3064: String name = splitter.getName();
3065: Preferences node = prefs.node(name);
3066:
3067: node.putInt("Split", divLoc);
3068: storePreferences();
3069:
3070: if (m_controlSplitter.getName().equals(name)) {
3071: m_controlDividerLocation = divLocObj;
3072: }
3073: }
3074: }
3075:
3076: public void doLayout() {
3077: super .doLayout();
3078:
3079: JSplitPane splitter = getControlSplitter();
3080: if (m_controlDividerLocation != null) {
3081: splitter.setDividerLocation(m_controlDividerLocation
3082: .intValue());
3083: }
3084: }
3085:
3086: public void addNotify() {
3087: super .addNotify();
3088: getControlSplitter().addPropertyChangeListener(
3089: m_dividerListener);
3090: }
3091:
3092: public void removeNotify() {
3093: getControlSplitter().removePropertyChangeListener(
3094: m_dividerListener);
3095: super.removeNotify();
3096: }
3097: }
|