/** Returns an icon or null for default icon. */ protected ImageIcon icon() { return Tools.createImageIcon(Tools.getDefault("ConfigDialog.Icon")); }
/** This class holds info data for a host. It shows host view, just like in the host tab. */ public final class HostInfo extends Info { /** Host data. */ private final Host host; /** Host standby icon. */ static final ImageIcon HOST_STANDBY_ICON = Tools.createImageIcon(Tools.getDefault("CRMGraph.HostStandbyIcon")); /** Host standby off icon. */ static final ImageIcon HOST_STANDBY_OFF_ICON = Tools.createImageIcon(Tools.getDefault("CRMGraph.HostStandbyOffIcon")); /** Stop comm layer icon. */ static final ImageIcon HOST_STOP_COMM_LAYER_ICON = Tools.createImageIcon(Tools.getDefault("CRMGraph.HostStopCommLayerIcon")); /** Start comm layer icon. */ static final ImageIcon HOST_START_COMM_LAYER_ICON = Tools.createImageIcon(Tools.getDefault("CRMGraph.HostStartCommLayerIcon")); /** Offline subtext. */ private static final Subtext OFFLINE_SUBTEXT = new Subtext("offline", null, Color.BLUE); /** Pending subtext. */ private static final Subtext PENDING_SUBTEXT = new Subtext("pending", null, Color.BLUE); /** Fenced/unclean subtext. */ private static final Subtext FENCED_SUBTEXT = new Subtext("fencing...", null, Color.RED); /** Corosync stopped subtext. */ private static final Subtext CORO_STOPPED_SUBTEXT = new Subtext("stopped", null, Color.RED); /** Pacemaker stopped subtext. */ private static final Subtext PCMK_STOPPED_SUBTEXT = new Subtext("pcmk stopped", null, Color.RED); /** Unknown subtext. */ private static final Subtext UNKNOWN_SUBTEXT = new Subtext("wait...", null, Color.BLUE); /** Online subtext. */ private static final Subtext ONLINE_SUBTEXT = new Subtext("online", null, Color.BLUE); /** Standby subtext. */ private static final Subtext STANDBY_SUBTEXT = new Subtext("STANDBY", null, Color.RED); /** Stopping subtext. */ private static final Subtext STOPPING_SUBTEXT = new Subtext("stopping...", null, Color.RED); /** Starting subtext. */ private static final Subtext STARTING_SUBTEXT = new Subtext("starting...", null, Color.BLUE); /** String that is displayed as a tool tip for disabled menu item. */ static final String NO_PCMK_STATUS_STRING = "cluster status is not available"; /** whether crm info is showing. */ private volatile boolean crmInfo = false; /** whether crm show is in progress. */ private volatile boolean crmShowInProgress = true; /** Prepares a new <code>HostInfo</code> object. */ public HostInfo(final Host host, final Browser browser) { super(host.getName(), browser); this.host = host; } /** Returns browser object of this info. */ @Override protected HostBrowser getBrowser() { return (HostBrowser) super.getBrowser(); } /** Returns a host icon for the menu. */ @Override public ImageIcon getMenuIcon(final boolean testOnly) { final Cluster cl = host.getCluster(); if (cl != null) { return HostBrowser.HOST_IN_CLUSTER_ICON_RIGHT_SMALL; } return HostBrowser.HOST_ICON; } /** Returns id, which is name of the host. */ @Override public String getId() { return host.getName(); } /** Returns a host icon for the category in the menu. */ @Override public ImageIcon getCategoryIcon(final boolean testOnly) { return HostBrowser.HOST_ICON; } /** Returns tooltip for the host. */ @Override public String getToolTipForGraph(final boolean testOnly) { return getBrowser().getHostToolTip(host); } /** Returns info panel. */ @Override public JComponent getInfoPanel() { if (getBrowser().getClusterBrowser() == null) { return new JPanel(); } final Font f = new Font("Monospaced", Font.PLAIN, Tools.getConfigData().scaled(12)); crmShowInProgress = true; final JTextArea ta = new JTextArea(Tools.getString("HostInfo.crmShellLoading")); ta.setEditable(false); ta.setFont(f); final MyButton crmConfigureCommitButton = new MyButton(Tools.getString("HostInfo.crmShellCommitButton"), Browser.APPLY_ICON); registerComponentEnableAccessMode( crmConfigureCommitButton, new AccessMode(ConfigData.AccessType.ADMIN, false)); final MyButton hostInfoButton = new MyButton(Tools.getString("HostInfo.crmShellStatusButton")); hostInfoButton.miniButton(); final MyButton crmConfigureShowButton = new MyButton(Tools.getString("HostInfo.crmShellShowButton")); crmConfigureShowButton.miniButton(); crmConfigureCommitButton.setEnabled(false); final ExecCallback execCallback = new ExecCallback() { @Override public void done(final String ans) { ta.setText(ans); SwingUtilities.invokeLater( new Runnable() { public void run() { crmConfigureShowButton.setEnabled(true); hostInfoButton.setEnabled(true); crmShowInProgress = false; } }); } @Override public void doneError(final String ans, final int exitCode) { ta.setText(ans); Tools.sshError(host, "", ans, "", exitCode); SwingUtilities.invokeLater( new Runnable() { public void run() { crmConfigureCommitButton.setEnabled(false); } }); } }; hostInfoButton.addActionListener( new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { registerComponentEditAccessMode(ta, new AccessMode(ConfigData.AccessType.GOD, false)); crmInfo = true; hostInfoButton.setEnabled(false); crmConfigureCommitButton.setEnabled(false); String command = "HostBrowser.getHostInfo"; if (!host.isCsInit()) { command = "HostBrowser.getHostInfoHeartbeat"; } host.execCommand( command, execCallback, null, /* ConvertCmdCallback */ false, /* outputVisible */ SSH.DEFAULT_COMMAND_TIMEOUT); } }); host.registerEnableOnConnect(hostInfoButton); crmConfigureShowButton.addActionListener( new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { registerComponentEditAccessMode(ta, new AccessMode(ConfigData.AccessType.ADMIN, false)); updateAdvancedPanels(); crmShowInProgress = true; crmInfo = false; crmConfigureShowButton.setEnabled(false); crmConfigureCommitButton.setEnabled(false); host.execCommand( "HostBrowser.getCrmConfigureShow", execCallback, null, /* ConvertCmdCallback */ false, /* outputVisible */ SSH.DEFAULT_COMMAND_TIMEOUT); } }); final CRMGraph crmg = getBrowser().getClusterBrowser().getCRMGraph(); final Document taDocument = ta.getDocument(); taDocument.addDocumentListener( new DocumentListener() { private void update() { if (!crmShowInProgress && !crmInfo) { crmConfigureCommitButton.setEnabled(true); } } public void changedUpdate(final DocumentEvent documentEvent) { update(); } public void insertUpdate(final DocumentEvent documentEvent) { update(); } public void removeUpdate(final DocumentEvent documentEvent) { update(); } }); final ButtonCallback buttonCallback = new ButtonCallback() { private volatile boolean mouseStillOver = false; /** Whether the whole thing should be enabled. */ @Override public boolean isEnabled() { if (Tools.versionBeforePacemaker(host)) { return false; } return true; } @Override public void mouseOut() { if (!isEnabled()) { return; } mouseStillOver = false; crmg.stopTestAnimation(crmConfigureCommitButton); crmConfigureCommitButton.setToolTipText(null); } @Override public void mouseOver() { if (!isEnabled()) { return; } mouseStillOver = true; crmConfigureCommitButton.setToolTipText(ClusterBrowser.STARTING_PTEST_TOOLTIP); crmConfigureCommitButton.setToolTipBackground( Tools.getDefaultColor("ClusterBrowser.Test.Tooltip.Background")); Tools.sleep(250); if (!mouseStillOver) { return; } mouseStillOver = false; final CountDownLatch startTestLatch = new CountDownLatch(1); crmg.startTestAnimation(crmConfigureCommitButton, startTestLatch); final Host dcHost = getBrowser().getClusterBrowser().getDCHost(); getBrowser().getClusterBrowser().ptestLockAcquire(); final ClusterStatus clStatus = getBrowser().getClusterBrowser().getClusterStatus(); clStatus.setPtestData(null); CRM.crmConfigureCommit(host, ta.getText(), true); final PtestData ptestData = new PtestData(CRM.getPtest(dcHost)); crmConfigureCommitButton.setToolTipText(ptestData.getToolTip()); clStatus.setPtestData(ptestData); getBrowser().getClusterBrowser().ptestLockRelease(); startTestLatch.countDown(); } }; addMouseOverListener(crmConfigureCommitButton, buttonCallback); crmConfigureCommitButton.addActionListener( new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { crmConfigureCommitButton.setEnabled(false); final Thread thread = new Thread( new Runnable() { @Override public void run() { getBrowser().getClusterBrowser().clStatusLock(); final String ret = CRM.crmConfigureCommit(host, ta.getText(), false); getBrowser().getClusterBrowser().clStatusUnlock(); } }); thread.start(); } }); final JPanel mainPanel = new JPanel(); mainPanel.setBackground(HostBrowser.PANEL_BACKGROUND); mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); final JPanel buttonPanel = new JPanel(new BorderLayout()); buttonPanel.setBackground(HostBrowser.BUTTON_PANEL_BACKGROUND); buttonPanel.setMinimumSize(new Dimension(0, 50)); buttonPanel.setPreferredSize(new Dimension(0, 50)); buttonPanel.setMaximumSize(new Dimension(Short.MAX_VALUE, 50)); mainPanel.add(buttonPanel); /* Actions */ buttonPanel.add(getActionsButton(), BorderLayout.EAST); final JPanel p = new JPanel(new SpringLayout()); p.setBackground(HostBrowser.BUTTON_PANEL_BACKGROUND); p.add(hostInfoButton); p.add(crmConfigureShowButton); p.add(crmConfigureCommitButton); p.add(new JLabel("")); SpringUtilities.makeCompactGrid( p, 1, 3, // rows, cols 1, 1, // initX, initY 1, 1); // xPad, yPad mainPanel.setMinimumSize( new Dimension( Tools.getDefaultSize("HostBrowser.ResourceInfoArea.Width"), Tools.getDefaultSize("HostBrowser.ResourceInfoArea.Height"))); mainPanel.setPreferredSize( new Dimension( Tools.getDefaultSize("HostBrowser.ResourceInfoArea.Width"), Tools.getDefaultSize("HostBrowser.ResourceInfoArea.Height"))); buttonPanel.add(p); mainPanel.add(new JLabel(Tools.getString("HostInfo.crmShellInfo"))); mainPanel.add(new JScrollPane(ta)); String command = "HostBrowser.getHostInfo"; if (!host.isCsInit()) { command = "HostBrowser.getHostInfoHeartbeat"; } host.execCommand( command, execCallback, null, /* ConvertCmdCallback */ false, /* outputVisible */ SSH.DEFAULT_COMMAND_TIMEOUT); return mainPanel; } /** Gets host. */ public Host getHost() { return host; } /** * Compares this host info name with specified hostinfo's name. * * @param otherHI other host info * @return true if they are equal */ boolean equals(final HostInfo otherHI) { if (otherHI == null) { return false; } return otherHI.toString().equals(host.getName()); } /** Returns string representation of the host. It's same as name. */ @Override public String toString() { return host.getName(); } /** Returns name of the host. */ @Override public String getName() { return host.getName(); } /** Creates the popup for the host. */ @Override public List<UpdatableItem> createPopup() { final List<UpdatableItem> items = new ArrayList<UpdatableItem>(); final boolean testOnly = false; /* host wizard */ final MyMenuItem hostWizardItem = new MyMenuItem( Tools.getString("HostBrowser.HostWizard"), HostBrowser.HOST_ICON_LARGE, "", new AccessMode(ConfigData.AccessType.RO, false), new AccessMode(ConfigData.AccessType.RO, false)) { private static final long serialVersionUID = 1L; @Override public String enablePredicate() { return null; } @Override public void action() { final EditHostDialog dialog = new EditHostDialog(host); dialog.showDialogs(); } }; items.add(hostWizardItem); Tools.getGUIData().registerAddHostButton(hostWizardItem); /* cluster manager standby on/off */ final HostInfo thisClass = this; final MyMenuItem standbyItem = new MyMenuItem( Tools.getString("HostBrowser.CRM.StandByOn"), HOST_STANDBY_ICON, ClusterBrowser.STARTING_PTEST_TOOLTIP, Tools.getString("HostBrowser.CRM.StandByOff"), HOST_STANDBY_OFF_ICON, ClusterBrowser.STARTING_PTEST_TOOLTIP, new AccessMode(ConfigData.AccessType.OP, false), new AccessMode(ConfigData.AccessType.OP, false)) { private static final long serialVersionUID = 1L; @Override public boolean predicate() { return !isStandby(testOnly); } @Override public String enablePredicate() { if (!getHost().isClStatus()) { return NO_PCMK_STATUS_STRING; } return null; } @Override public void action() { final Host dcHost = getBrowser().getClusterBrowser().getDCHost(); if (isStandby(testOnly)) { CRM.standByOff(dcHost, host, testOnly); } else { CRM.standByOn(dcHost, host, testOnly); } } }; final ClusterBrowser cb = getBrowser().getClusterBrowser(); if (cb != null) { final ClusterBrowser.ClMenuItemCallback standbyItemCallback = cb.new ClMenuItemCallback(standbyItem, host) { @Override public void action(final Host dcHost) { if (isStandby(false)) { CRM.standByOff(dcHost, host, true); } else { CRM.standByOn(dcHost, host, true); } } }; addMouseOverListener(standbyItem, standbyItemCallback); } items.add(standbyItem); /* Migrate all services from this host. */ final MyMenuItem allMigrateFromItem = new MyMenuItem( Tools.getString("HostInfo.CRM.AllMigrateFrom"), HOST_STANDBY_ICON, ClusterBrowser.STARTING_PTEST_TOOLTIP, new AccessMode(ConfigData.AccessType.OP, false), new AccessMode(ConfigData.AccessType.OP, false)) { private static final long serialVersionUID = 1L; @Override public boolean predicate() { return true; } @Override public String enablePredicate() { if (!getHost().isClStatus()) { return NO_PCMK_STATUS_STRING; } if (getBrowser().getClusterBrowser().getExistingServiceList(null).isEmpty()) { return "there are no services to migrate"; } return null; } @Override public void action() { for (final ServiceInfo si : cb.getExistingServiceList(null)) { if (!si.isConstraintPH() && si.getGroupInfo() == null && si.getCloneInfo() == null) { final List<String> runningOnNodes = si.getRunningOnNodes(false); if (runningOnNodes != null && runningOnNodes.contains(getHost().getName())) { final Host dcHost = getHost(); si.migrateFromResource(dcHost, getHost().getName(), false); } } } } }; if (cb != null) { final ClusterBrowser.ClMenuItemCallback allMigrateFromItemCallback = cb.new ClMenuItemCallback(allMigrateFromItem, host) { @Override public void action(final Host dcHost) { for (final ServiceInfo si : cb.getExistingServiceList(null)) { if (!si.isConstraintPH() && si.getGroupInfo() == null) { final List<String> runningOnNodes = si.getRunningOnNodes(false); if (runningOnNodes != null && runningOnNodes.contains(host.getName())) { si.migrateFromResource(dcHost, host.getName(), true); } } } } }; addMouseOverListener(allMigrateFromItem, allMigrateFromItemCallback); } items.add(allMigrateFromItem); /* Stop corosync/openais. */ final MyMenuItem stopCorosyncItem = new MyMenuItem( Tools.getString("HostInfo.StopCorosync"), HOST_STOP_COMM_LAYER_ICON, ClusterBrowser.STARTING_PTEST_TOOLTIP, Tools.getString("HostInfo.StopOpenais"), HOST_STOP_COMM_LAYER_ICON, ClusterBrowser.STARTING_PTEST_TOOLTIP, new AccessMode(ConfigData.AccessType.ADMIN, true), new AccessMode(ConfigData.AccessType.ADMIN, false)) { private static final long serialVersionUID = 1L; @Override public boolean predicate() { /* when both are running it's openais. */ return getHost().isCsRunning() && !getHost().isAisRunning(); } @Override public boolean visiblePredicate() { return getHost().isCsRunning() || getHost().isAisRunning(); } @Override public void action() { if (Tools.confirmDialog( Tools.getString("HostInfo.confirmCorosyncStop.Title"), Tools.getString("HostInfo.confirmCorosyncStop.Desc"), Tools.getString("HostInfo.confirmCorosyncStop.Yes"), Tools.getString("HostInfo.confirmCorosyncStop.No"))) { final Host host = getHost(); host.setCommLayerStopping(true); if (!host.isPcmkStartedByCorosync() && host.isPcmkInit() && host.isPcmkRunning()) { Corosync.stopCorosyncWithPcmk(host); } else { Corosync.stopCorosync(host); } getBrowser().getClusterBrowser().updateHWInfo(host); } } }; if (cb != null) { final ClusterBrowser.ClMenuItemCallback stopCorosyncItemCallback = cb.new ClMenuItemCallback(stopCorosyncItem, host) { @Override public void action(final Host dcHost) { if (!isStandby(false)) { CRM.standByOn(dcHost, host, true); } } }; addMouseOverListener(stopCorosyncItem, stopCorosyncItemCallback); } items.add(stopCorosyncItem); /* Stop heartbeat. */ final MyMenuItem stopHeartbeatItem = new MyMenuItem( Tools.getString("HostInfo.StopHeartbeat"), HOST_STOP_COMM_LAYER_ICON, ClusterBrowser.STARTING_PTEST_TOOLTIP, new AccessMode(ConfigData.AccessType.ADMIN, true), new AccessMode(ConfigData.AccessType.ADMIN, false)) { private static final long serialVersionUID = 1L; @Override public boolean visiblePredicate() { return getHost().isHeartbeatRunning(); } @Override public void action() { if (Tools.confirmDialog( Tools.getString("HostInfo.confirmHeartbeatStop.Title"), Tools.getString("HostInfo.confirmHeartbeatStop.Desc"), Tools.getString("HostInfo.confirmHeartbeatStop.Yes"), Tools.getString("HostInfo.confirmHeartbeatStop.No"))) { getHost().setCommLayerStopping(true); Heartbeat.stopHeartbeat(getHost()); getBrowser().getClusterBrowser().updateHWInfo(host); } } }; if (cb != null) { final ClusterBrowser.ClMenuItemCallback stopHeartbeatItemCallback = cb.new ClMenuItemCallback(stopHeartbeatItem, host) { @Override public void action(final Host dcHost) { if (!isStandby(false)) { CRM.standByOn(dcHost, host, true); } } }; addMouseOverListener(stopHeartbeatItem, stopHeartbeatItemCallback); } items.add(stopHeartbeatItem); /* Start corosync. */ final MyMenuItem startCorosyncItem = new MyMenuItem( Tools.getString("HostInfo.StartCorosync"), HOST_START_COMM_LAYER_ICON, ClusterBrowser.STARTING_PTEST_TOOLTIP, new AccessMode(ConfigData.AccessType.ADMIN, false), new AccessMode(ConfigData.AccessType.ADMIN, false)) { private static final long serialVersionUID = 1L; @Override public boolean visiblePredicate() { final Host h = getHost(); return h.isCorosync() && h.isCsInit() && h.isCsAisConf() && !h.isCsRunning() && !h.isAisRunning() && !h.isHeartbeatRunning() && !h.isHeartbeatRc(); } @Override public String enablePredicate() { final Host h = getHost(); if (h.isAisRc() && !h.isCsRc()) { return "Openais is in rc.d"; } return null; } @Override public void action() { getHost().setCommLayerStarting(true); if (getHost().isPcmkRc()) { Corosync.startCorosyncWithPcmk(getHost()); } else { Corosync.startCorosync(getHost()); } getBrowser().getClusterBrowser().updateHWInfo(host); } }; if (cb != null) { final ClusterBrowser.ClMenuItemCallback startCorosyncItemCallback = cb.new ClMenuItemCallback(startCorosyncItem, host) { @Override public void action(final Host host) { // TODO } }; addMouseOverListener(startCorosyncItem, startCorosyncItemCallback); } items.add(startCorosyncItem); /* Start openais. */ final MyMenuItem startOpenaisItem = new MyMenuItem( Tools.getString("HostInfo.StartOpenais"), HOST_START_COMM_LAYER_ICON, ClusterBrowser.STARTING_PTEST_TOOLTIP, new AccessMode(ConfigData.AccessType.ADMIN, false), new AccessMode(ConfigData.AccessType.ADMIN, false)) { private static final long serialVersionUID = 1L; @Override public boolean visiblePredicate() { final Host h = getHost(); return h.isAisInit() && h.isCsAisConf() && !h.isCsRunning() && !h.isAisRunning() && !h.isHeartbeatRunning() && !h.isHeartbeatRc(); } @Override public String enablePredicate() { final Host h = getHost(); if (h.isCsRc() && !h.isAisRc()) { return "Corosync is in rc.d"; } return null; } @Override public void action() { getHost().setCommLayerStarting(true); Openais.startOpenais(getHost()); getBrowser().getClusterBrowser().updateHWInfo(host); } }; if (cb != null) { final ClusterBrowser.ClMenuItemCallback startOpenaisItemCallback = cb.new ClMenuItemCallback(startOpenaisItem, host) { @Override public void action(final Host host) { // TODO } }; addMouseOverListener(startOpenaisItem, startOpenaisItemCallback); } items.add(startOpenaisItem); /* Start heartbeat. */ final MyMenuItem startHeartbeatItem = new MyMenuItem( Tools.getString("HostInfo.StartHeartbeat"), HOST_START_COMM_LAYER_ICON, ClusterBrowser.STARTING_PTEST_TOOLTIP, new AccessMode(ConfigData.AccessType.ADMIN, false), new AccessMode(ConfigData.AccessType.ADMIN, false)) { private static final long serialVersionUID = 1L; @Override public boolean visiblePredicate() { final Host h = getHost(); return h.isHeartbeatInit() && h.isHeartbeatConf() && !h.isCsRunning() && !h.isAisRunning() && !h.isHeartbeatRunning(); // && !h.isAisRc() // && !h.isCsRc(); TODO should check /etc/defaults/ } @Override public void action() { getHost().setCommLayerStarting(true); Heartbeat.startHeartbeat(getHost()); getBrowser().getClusterBrowser().updateHWInfo(host); } }; if (cb != null) { final ClusterBrowser.ClMenuItemCallback startHeartbeatItemCallback = cb.new ClMenuItemCallback(startHeartbeatItem, host) { @Override public void action(final Host host) { // TODO } }; addMouseOverListener(startHeartbeatItem, startHeartbeatItemCallback); } items.add(startHeartbeatItem); /* Start pacemaker. */ final MyMenuItem startPcmkItem = new MyMenuItem( Tools.getString("HostInfo.StartPacemaker"), HOST_START_COMM_LAYER_ICON, ClusterBrowser.STARTING_PTEST_TOOLTIP, new AccessMode(ConfigData.AccessType.ADMIN, false), new AccessMode(ConfigData.AccessType.ADMIN, false)) { private static final long serialVersionUID = 1L; @Override public boolean visiblePredicate() { final Host h = getHost(); return !h.isPcmkStartedByCorosync() && !h.isPcmkRunning() && (h.isCsRunning() || h.isAisRunning()) && !h.isHeartbeatRunning(); } @Override public String enablePredicate() { return null; } @Override public void action() { host.setPcmkStarting(true); Corosync.startPacemaker(host); getBrowser().getClusterBrowser().updateHWInfo(host); } }; if (cb != null) { final ClusterBrowser.ClMenuItemCallback startPcmkItemCallback = cb.new ClMenuItemCallback(startPcmkItem, host) { @Override public void action(final Host host) { // TODO } }; addMouseOverListener(startPcmkItem, startPcmkItemCallback); } items.add(startPcmkItem); /* change host color */ final MyMenuItem changeHostColorItem = new MyMenuItem( Tools.getString("HostBrowser.Drbd.ChangeHostColor"), null, "", new AccessMode(ConfigData.AccessType.RO, false), new AccessMode(ConfigData.AccessType.RO, false)) { private static final long serialVersionUID = 1L; @Override public String enablePredicate() { return null; } @Override public void action() { final Color newColor = JColorChooser.showDialog( Tools.getGUIData().getMainFrame(), "Choose " + host.getName() + " color", host.getPmColors()[0]); if (newColor != null) { host.setSavedColor(newColor); } } }; items.add(changeHostColorItem); /* view logs */ final MyMenuItem viewLogsItem = new MyMenuItem( Tools.getString("HostBrowser.Drbd.ViewLogs"), LOGFILE_ICON, "", new AccessMode(ConfigData.AccessType.RO, false), new AccessMode(ConfigData.AccessType.RO, false)) { private static final long serialVersionUID = 1L; @Override public String enablePredicate() { if (!getHost().isConnected()) { return Host.NOT_CONNECTED_STRING; } return null; } @Override public void action() { HostLogs l = new HostLogs(host); l.showDialog(); } }; items.add(viewLogsItem); /* advacend options */ final MyMenu hostAdvancedSubmenu = new MyMenu( Tools.getString("HostBrowser.AdvancedSubmenu"), new AccessMode(ConfigData.AccessType.OP, false), new AccessMode(ConfigData.AccessType.OP, false)) { private static final long serialVersionUID = 1L; @Override public String enablePredicate() { if (!host.isConnected()) { return Host.NOT_CONNECTED_STRING; } return null; } @Override public void update() { super.update(); getBrowser().addAdvancedMenu(this); } }; items.add(hostAdvancedSubmenu); /* remove host from gui */ final MyMenuItem removeHostItem = new MyMenuItem( Tools.getString("HostBrowser.RemoveHost"), HostBrowser.HOST_REMOVE_ICON, Tools.getString("HostBrowser.RemoveHost"), new AccessMode(ConfigData.AccessType.RO, false), new AccessMode(ConfigData.AccessType.RO, false)) { private static final long serialVersionUID = 1L; @Override public String enablePredicate() { if (getHost().getCluster() != null) { return "it is a member of a cluster"; } return null; } @Override public void action() { getHost().disconnect(); Tools.getConfigData().removeHostFromHosts(getHost()); Tools.getGUIData().allHostsUpdate(); } }; items.add(removeHostItem); return items; } /** Returns grahical view if there is any. */ @Override public JPanel getGraphicalView() { final ClusterBrowser b = getBrowser().getClusterBrowser(); if (b == null) { return null; } return b.getServicesInfo().getGraphicalView(); } /** Returns how much of this is used. */ public int getUsed() { // TODO: maybe the load? return -1; } /** Returns subtexts that appears in the host vertex in the cluster graph. */ public Subtext[] getSubtextsForGraph(final boolean testOnly) { final List<Subtext> texts = new ArrayList<Subtext>(); if (getHost().isConnected()) { if (!getHost().isClStatus()) { texts.add(new Subtext("waiting for Pacemaker...", null, Color.BLACK)); } } else { texts.add(new Subtext("connecting...", null, Color.BLACK)); } return texts.toArray(new Subtext[texts.size()]); } /** Returns text that appears above the icon in the graph. */ public String getIconTextForGraph(final boolean testOnly) { if (!getHost().isConnected()) { return Tools.getString("HostBrowser.Hb.NoInfoAvailable"); } return null; } /** Returns whether this host is in stand by. */ public boolean isStandby(final boolean testOnly) { final ClusterBrowser b = getBrowser().getClusterBrowser(); if (b == null) { return false; } return b.isStandby(host, testOnly); } /** Returns cluster status. */ ClusterStatus getClusterStatus() { final ClusterBrowser b = getBrowser().getClusterBrowser(); if (b == null) { return null; } return b.getClusterStatus(); } /** Returns text that appears in the corner of the graph. */ public Subtext getRightCornerTextForGraph(final boolean testOnly) { if (getHost().isCommLayerStopping()) { return STOPPING_SUBTEXT; } else if (getHost().isCommLayerStarting()) { return STARTING_SUBTEXT; } else if (getHost().isPcmkStarting()) { return STARTING_SUBTEXT; } final ClusterStatus cs = getClusterStatus(); if (cs != null && cs.isFencedNode(host.getName())) { return FENCED_SUBTEXT; } else if (getHost().isClStatus()) { if (isStandby(testOnly)) { return STANDBY_SUBTEXT; } else { return ONLINE_SUBTEXT; } } else if (getHost().isConnected()) { final Boolean running = getHost().getCorosyncHeartbeatRunning(); if (running == null) { return UNKNOWN_SUBTEXT; } else if (!running) { return CORO_STOPPED_SUBTEXT; } if (cs != null && cs.isPendingNode(host.getName())) { return PENDING_SUBTEXT; } else if (!getHost().isPcmkRunning()) { return PCMK_STOPPED_SUBTEXT; } else if (cs != null && "no".equals(cs.isOnlineNode(host.getName()))) { return OFFLINE_SUBTEXT; } else { return UNKNOWN_SUBTEXT; } } return null; } /** Selects the node in the menu and reloads everything underneath. */ @Override public void selectMyself() { super.selectMyself(); getBrowser().nodeChanged(getNode()); } }
/** This class holds info about Virtual Hardware. */ public abstract class VMSHardwareInfo extends EditableInfo { /** Cache for the info panel. */ private JComponent infoPanel = null; /** VMS virtual domain info object. */ private final VMSVirtualDomainInfo vmsVirtualDomainInfo; /** Back to overview icon. */ private static final ImageIcon BACK_ICON = Tools.createImageIcon(Tools.getDefault("BackIcon")); /** Default units. */ private static final Map<String, String> DEFAULT_UNIT = new HashMap<String, String>(); /** If it has units. */ private static final Map<String, Boolean> HAS_UNIT = new HashMap<String, Boolean>(); /** Cache for files. */ private final Map<String, LinuxFile> linuxFileCache = new HashMap<String, LinuxFile>(); /** Pattern that parses stat output. */ private static final Pattern STAT_PATTERN = Pattern.compile("(.).{9}\\s+(\\d+)\\s+" + "(\\d+)\\s+" + "(\\d+) (.*)$"); /** Whether file chooser needs file or dir. */ protected static final boolean FILECHOOSER_DIR_ONLY = true; protected static final boolean FILECHOOSER_FILE_ONLY = !FILECHOOSER_DIR_ONLY; /** Creates the VMSHardwareInfo object. */ VMSHardwareInfo( final String name, final Browser browser, final VMSVirtualDomainInfo vmsVirtualDomainInfo) { super(name, browser); setResource(new Resource(name)); this.vmsVirtualDomainInfo = vmsVirtualDomainInfo; } /** Returns browser object of this info. */ @Override protected final ClusterBrowser getBrowser() { return (ClusterBrowser) super.getBrowser(); } /** Returns info panel. */ @Override public final JComponent getInfoPanel() { if (infoPanel != null) { return infoPanel; } final boolean abExisted = getApplyButton() != null; /* main, button and options panels */ final JPanel mainPanel = new JPanel(); mainPanel.setBackground(ClusterBrowser.PANEL_BACKGROUND); mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); final JTable headerTable = getTable(VMSVirtualDomainInfo.HEADER_TABLE); if (headerTable != null) { mainPanel.add(headerTable.getTableHeader()); mainPanel.add(headerTable); } addHardwareTable(mainPanel); final JPanel buttonPanel = new JPanel(new BorderLayout()); buttonPanel.setBackground(ClusterBrowser.BUTTON_PANEL_BACKGROUND); buttonPanel.setMinimumSize(new Dimension(0, 50)); buttonPanel.setPreferredSize(new Dimension(0, 50)); buttonPanel.setMaximumSize(new Dimension(Short.MAX_VALUE, 50)); final JPanel optionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 20)); optionsPanel.setBackground(ClusterBrowser.PANEL_BACKGROUND); final String[] params = getParametersFromXML(); initApplyButton(null); /* add item listeners to the apply button. */ if (!abExisted) { getApplyButton() .addActionListener( new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { final Thread thread = new Thread( new Runnable() { @Override public void run() { getBrowser().clStatusLock(); apply(false); getBrowser().clStatusUnlock(); } }); thread.start(); } }); getRevertButton() .addActionListener( new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { final Thread thread = new Thread( new Runnable() { @Override public void run() { getBrowser().clStatusLock(); revert(); getBrowser().clStatusUnlock(); } }); thread.start(); } }); } final JPanel extraButtonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 3, 0)); extraButtonPanel.setBackground(Browser.BUTTON_PANEL_BACKGROUND); buttonPanel.add(extraButtonPanel); addApplyButton(buttonPanel); addRevertButton(extraButtonPanel); final MyButton overviewButton = new MyButton("VM Host Overview", BACK_ICON); overviewButton.miniButton(); overviewButton.setPreferredSize(new Dimension(130, 50)); // overviewButton.setPreferredSize(new Dimension(200, 50)); overviewButton.addActionListener( new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { vmsVirtualDomainInfo.selectMyself(); } }); extraButtonPanel.add(overviewButton); addParams( optionsPanel, params, ClusterBrowser.SERVICE_LABEL_WIDTH, ClusterBrowser.SERVICE_FIELD_WIDTH * 2, null); /* Actions */ buttonPanel.add(getActionsButton(), BorderLayout.EAST); mainPanel.add(optionsPanel); final JPanel newPanel = new JPanel(); newPanel.setBackground(ClusterBrowser.PANEL_BACKGROUND); newPanel.setLayout(new BoxLayout(newPanel, BoxLayout.Y_AXIS)); newPanel.add(buttonPanel); newPanel.add( getMoreOptionsPanel( ClusterBrowser.SERVICE_LABEL_WIDTH + ClusterBrowser.SERVICE_FIELD_WIDTH + 4)); newPanel.add(new JScrollPane(mainPanel)); SwingUtilities.invokeLater( new Runnable() { @Override public void run() { getApplyButton().setVisible(!getVMSVirtualDomainInfo().getResource().isNew()); setApplyButtons(null, params); } }); infoPanel = newPanel; infoPanelDone(); return infoPanel; } /** Returns whether this parameter has a unit prefix. */ @Override protected final boolean hasUnitPrefix(final String param) { return HAS_UNIT.containsKey(param) && HAS_UNIT.get(param); } /** Returns units. */ @Override protected final Unit[] getUnits() { return new Unit[] { // new Unit("", "", "KiByte", "KiBytes"), /* default unit */ new Unit("K", "K", "KiByte", "KiBytes"), new Unit("M", "M", "MiByte", "MiBytes"), new Unit("G", "G", "GiByte", "GiBytes"), new Unit("T", "T", "TiByte", "TiBytes") }; } /** Returns the default unit for the parameter. */ protected final String getDefaultUnit(final String param) { return DEFAULT_UNIT.get(param); } /** Returns columns for the table. */ @Override protected final String[] getColumnNames(final String tableName) { return vmsVirtualDomainInfo.getColumnNames(tableName); } /** Execute when row in the table was clicked. */ @Override protected final void rowClicked(final String tableName, final String key, final int column) { final Thread thread = new Thread( new Runnable() { @Override public void run() { if (isControlButton(tableName, column)) { vmsVirtualDomainInfo.rowClicked(tableName, key, column); } else { vmsVirtualDomainInfo.selectMyself(); } } }); thread.start(); } /** Retrurns color for some rows. */ @Override protected final Color getTableRowColor(final String tableName, final String key) { if (VMSVirtualDomainInfo.HEADER_TABLE.equals(tableName)) { return vmsVirtualDomainInfo.getTableRowColor(tableName, key); } return Browser.PANEL_BACKGROUND; } /** Alignment for the specified column. */ @Override protected final int getTableColumnAlignment(final String tableName, final int column) { if (VMSVirtualDomainInfo.HEADER_TABLE.equals(tableName)) { return vmsVirtualDomainInfo.getTableColumnAlignment(tableName, column); } return SwingConstants.LEFT; } /** Returns info object for this row. */ @Override protected final Info getTableInfo(final String tableName, final String key) { if (VMSVirtualDomainInfo.HEADER_TABLE.equals(tableName)) { return vmsVirtualDomainInfo; } return null; } /** Return info object of the whole domain. */ protected final VMSVirtualDomainInfo getVMSVirtualDomainInfo() { return vmsVirtualDomainInfo; } /** Get first host that has this vm and is connected. */ protected final Host getFirstConnectedHost() { for (final Host h : getBrowser().getClusterHosts()) { final VMSXML vmsxml = getBrowser().getVMSXML(h); if (vmsxml != null && h.isConnected()) { return h; } } return null; } /** Returns whether this item is removeable (null), or string why it isn't. */ protected abstract String isRemoveable(); /** Updates parameters. */ abstract void updateParameters(); /** Returns list of menu items. */ @Override public final List<UpdatableItem> createPopup() { final List<UpdatableItem> items = new ArrayList<UpdatableItem>(); final boolean testOnly = false; /* remove service */ final MyMenuItem removeMenuItem = new MyMenuItem( Tools.getString("VMSHardwareInfo.Menu.Remove"), ClusterBrowser.REMOVE_ICON, ClusterBrowser.STARTING_PTEST_TOOLTIP, Tools.getString("VMSHardwareInfo.Menu.Cancel"), ClusterBrowser.REMOVE_ICON, ClusterBrowser.STARTING_PTEST_TOOLTIP, new AccessMode(ConfigData.AccessType.ADMIN, false), new AccessMode(ConfigData.AccessType.OP, false)) { private static final long serialVersionUID = 1L; @Override public boolean predicate() { return !getResource().isNew(); } @Override public String enablePredicate() { if (getResource().isNew()) { return null; } return isRemoveable(); } @Override public void action() { hidePopup(); removeMyself(false); } }; addMouseOverListener(removeMenuItem, null); items.add((UpdatableItem) removeMenuItem); return items; } /** Removes this hardware from the libvirt with confirmation dialog. */ @Override public final void removeMyself(final boolean testOnly) { if (getResource().isNew()) { super.removeMyself(testOnly); getResource().setNew(false); removeNode(); return; } String desc = Tools.getString("VMSHardwareInfo.confirmRemove.Description"); desc = desc.replaceAll("@HW@", Matcher.quoteReplacement(toString())); if (Tools.confirmDialog( Tools.getString("VMSHardwareInfo.confirmRemove.Title"), desc, Tools.getString("VMSHardwareInfo.confirmRemove.Yes"), Tools.getString("VMSHardwareInfo.confirmRemove.No"))) { removeMyselfNoConfirm(testOnly); getResource().setNew(false); } } /** Removes this disk without confirmation dialog. */ protected abstract void removeMyselfNoConfirm(final boolean testOnly); /** Applies the changes. */ abstract void apply(final boolean testOnly); /** Adds disk table with only this disk to the main panel. */ protected abstract void addHardwareTable(final JPanel mainPanel); /** Modify device xml. */ protected abstract void modifyXML( final VMSXML vmsxml, final Node node, final String domainName, final Map<String, String> params); /** Returns whether the column is a button, 0 column is always a button. */ @Override protected final Map<Integer, Integer> getDefaultWidths(final String tableName) { return vmsVirtualDomainInfo.getDefaultWidths(tableName); } /** Returns device parameters. */ protected Map<String, String> getHWParameters(final boolean allParams) { Tools.invokeAndWait( new Runnable() { public void run() { getInfoPanel(); } }); final String[] params = getParametersFromXML(); final Map<String, String> parameters = new HashMap<String, String>(); for (final String param : getParametersFromXML()) { final String value = getComboBoxValue(param); if (allParams || !Tools.areEqual(getParamSaved(param), value)) { if (Tools.areEqual(getParamDefault(param), value)) { parameters.put(param, null); } else { parameters.put(param, value); } } } return parameters; } /** Returns default widths for columns. Null for computed width. */ @Override protected final boolean isControlButton(final String tableName, final int column) { return vmsVirtualDomainInfo.isControlButton(tableName, column); } /** Returns tool tip text in the table. */ @Override protected String getTableToolTip( final String tableName, final String key, final Object object, final int raw, final int column) { return vmsVirtualDomainInfo.getTableToolTip(tableName, key, object, raw, column); } /** Returns cached file object. */ public final LinuxFile getLinuxDir(final String dir, final Host host) { LinuxFile ret = linuxFileCache.get(dir); if (ret == null) { ret = new LinuxFile(this, host, dir, "d", 0, 0); linuxFileCache.put(dir, ret); } return ret; } /** Returns file system view that allows remote browsing. */ private FileSystemView getFileSystemView(final Host host, final String directory) { final VMSHardwareInfo thisClass = this; return new FileSystemView() { @Override public final File[] getRoots() { return new LinuxFile[] {getLinuxDir("/", host)}; } @Override public final boolean isRoot(final File f) { final String path = Tools.getUnixPath(f.toString()); if ("/".equals(path)) { return true; } return false; } @Override public final File createNewFolder(final File containingDir) { return null; } @Override public final File getHomeDirectory() { return getLinuxDir(directory, host); } @Override public final Boolean isTraversable(final File f) { final LinuxFile lf = linuxFileCache.get(f.toString()); if (lf != null) { return lf.isDirectory(); } return true; } @Override public final File getParentDirectory(final File dir) { return getLinuxDir(dir.getParent(), host); } @Override public final File[] getFiles(final File dir, final boolean useFileHiding) { final StringBuilder dirSB = new StringBuilder(dir.toString()); if ("/".equals(dir.toString())) { dirSB.append('*'); } else { dirSB.append("/*"); } final SSH.SSHOutput out = Tools.execCommandProgressIndicator( host, "stat -c \"%A %a %Y %s %n\" " + dirSB.toString() + " 2>/dev/null", null, false, "executing...", SSH.DEFAULT_COMMAND_TIMEOUT); final List<LinuxFile> files = new ArrayList<LinuxFile>(); if (out.getExitCode() == 0) { for (final String line : out.getOutput().split("\r\n")) { if ("".equals(line.trim())) { continue; } final Matcher m = STAT_PATTERN.matcher(line); if (m.matches()) { final String type = m.group(1); final long lastModified = Long.parseLong(m.group(3)) * 1000; final long size = Long.parseLong(m.group(4)); final String filename = m.group(5); LinuxFile lf = linuxFileCache.get(filename); if (lf == null) { lf = new LinuxFile(thisClass, host, filename, type, lastModified, size); linuxFileCache.put(filename, lf); } else { lf.update(type, lastModified, size); } files.add(lf); } else { Tools.appWarning("could not match: " + line); } } } return files.toArray(new LinuxFile[files.size()]); } }; } /** * Starts file chooser. * * @param dir whether it needs dir or file */ protected void startFileChooser( final Widget paramWi, final String directory, final boolean dirOnly) { final Host host = getFirstConnectedHost(); if (host == null) { Tools.appError("Connection to host lost."); return; } final VMSHardwareInfo thisClass = this; final JFileChooser fc = new JFileChooser(getLinuxDir(directory, host), getFileSystemView(host, directory)) { /** Serial version UID. */ private static final long serialVersionUID = 1L; @Override public final void setCurrentDirectory(final File dir) { super.setCurrentDirectory(new LinuxFile(thisClass, host, dir.toString(), "d", 0, 0)); } }; fc.setBackground(ClusterBrowser.STATUS_BACKGROUND); fc.setDialogType(JFileChooser.CUSTOM_DIALOG); if (dirOnly) { fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); } fc.setDialogTitle(Tools.getString("VMSDiskInfo.FileChooserTitle") + host.getName()); // fc.setApproveButtonText(Tools.getString("VMSDiskInfo.Approve")); fc.setApproveButtonToolTipText(Tools.getString("VMSDiskInfo.Approve.ToolTip")); fc.putClientProperty("FileChooser.useShellFolder", Boolean.FALSE); final int ret = fc.showDialog(Tools.getGUIData().getMainFrame(), Tools.getString("VMSDiskInfo.Approve")); linuxFileCache.clear(); if (ret == JFileChooser.APPROVE_OPTION && fc.getSelectedFile() != null) { final String name = fc.getSelectedFile().getAbsolutePath(); paramWi.setValue(name); } } /** * Returns whether the specified parameter or any of the parameters have changed. Don't check the * invisible for the type parameters. */ @Override public boolean checkResourceFieldsChanged(final String param, final String[] params) { return checkResourceFieldsChanged(param, params, false); } /** * Returns whether the specified parameter or any of the parameters have changed. Don't check the * invisible for the type parameters. */ boolean checkResourceFieldsChanged( final String param, final String[] params, final boolean fromDomain) { final VMSVirtualDomainInfo vdi = vmsVirtualDomainInfo; if (!fromDomain && vdi != null && params.length != 1) { vdi.setApplyButtons(null, vdi.getParametersFromXML()); } String[] parameters; if (params == null || params.length == 1) { /* just one param */ parameters = params; } else { parameters = getRealParametersFromXML(); } return super.checkResourceFieldsChanged(param, parameters); } /** Returns whether all the parameters are correct. */ @Override public boolean checkResourceFieldsCorrect(final String param, final String[] params) { return checkResourceFieldsCorrect(param, params, false); } /** Returns whether all the parameters are correct. */ boolean checkResourceFieldsCorrect( final String param, final String[] params, final boolean fromDomain) { final VMSVirtualDomainInfo vdi = vmsVirtualDomainInfo; if (!fromDomain && vdi != null && params.length != 1) { vdi.setApplyButtons(null, vdi.getParametersFromXML()); } String[] parameters; if (params == null || params.length == 1) { /* just one param */ parameters = params; } else { parameters = getRealParametersFromXML(); } return super.checkResourceFieldsCorrect(param, parameters); } /** Checks one parameter. */ @Override protected final void checkOneParam(final String param) { checkResourceFieldsCorrect(param, new String[] {param}, true); } /** Returns parameters. */ String[] getRealParametersFromXML() { return getParametersFromXML(); } /** Saves all preferred values. */ public final void savePreferredValues() { for (final String param : getParametersFromXML()) { final String pv = getParamPreferred(param); if (pv != null) { getResource().setValue(param, pv); } } } }
/** * An implementation of a wizard dialog with next, back, finish and cancel buttons. The dialogs that * are in a row of dialog steps should extend this class and overwrite at least * body() and * nextDialog() methods. * * @author Rasto Levrinc * @version $Id$ */ public abstract class WizardDialog extends ConfigDialog { /** Serial Version UID. */ private static final long serialVersionUID = 1L; /** Previous dialog object. A dialog that will be displayed after clicking on the back button */ private WizardDialog previousDialog; /** Cancel icon. */ private static final ImageIcon CANCEL_ICON = Tools.createImageIcon(Tools.getDefault("Dialog.Dialog.CancelIcon")); /** Finish icon. */ private static final ImageIcon FINISH_ICON = Tools.createImageIcon(Tools.getDefault("Dialog.Dialog.FinishIcon")); /** Next icon. */ private static final ImageIcon NEXT_ICON = Tools.createImageIcon(Tools.getDefault("Dialog.Dialog.NextIcon")); /** Back icon. */ private static final ImageIcon BACK_ICON = Tools.createImageIcon(Tools.getDefault("Dialog.Dialog.BackIcon")); /** Progress bar. */ private ProgressBar progressBar = null; /** Prepares a new <code>WizardDialog</code> object. */ protected WizardDialog(final WizardDialog previousDialog) { super(); this.previousDialog = previousDialog; } /** * Returns previous dialog. It is used to get with the back button to the dialog before this one. */ public WizardDialog getPreviousDialog() { return previousDialog; } /** * Returns previous dialog. It is used to get with the back button to the dialog before this one. */ protected final void setPreviousDialog(final WizardDialog previousDialog) { this.previousDialog = previousDialog; } /// ** // * TextResource files contain texts in different languages. Text for every // * button has to be defined there. If Next button is used, resource file // * has to contain Dialog.Next item. // */ // protected final String buttonString(final String b) { // return Tools.getString("Dialog.Dialog." + b); // } /** Returns localized string of Next button. */ public String nextButton() { return buttonString("Next"); } /** Returns localized string of Back button. */ public final String backButton() { return buttonString("Back"); } /** Returns localized string of Finish button. */ public String finishButton() { return buttonString("Finish"); } /** Returns localized string of Retry button. */ final String retryButton() { return buttonString("Retry"); } /** Returns true if Cancel button was pressed. */ public final boolean isPressedCancelButton() { return isPressedButton(cancelButton()); } /** Returns true if Retry button was pressed. */ final boolean isPressedRetryButton() { return isPressedButton(retryButton()); } /** Returns true if Finish button was pressed. */ public final boolean isPressedFinishButton() { return isPressedButton(finishButton()); } /** * Array of buttons that are used in the dialog. Wrapper function like nextButton() should be used * instead of simple "Next", so it can be localized. In TextResources.java file it can be than * redifined with Dialog.Dialog.Next. */ @Override protected final String[] buttons() { final String[] btns = { retryButton(), // this one is hidden. backButton(), nextButton(), finishButton(), cancelButton() }; return btns; } /** Returns the listener for the skip button, that enables "next" button if it is checked. */ @Override protected final ItemListener skipButtonListener() { return new ItemListener() { @Override public void itemStateChanged(final ItemEvent e) { buttonClass(nextButton()).setEnabled(true); skipButtonSetEnabled(false); } }; } /** Enable next button, with skip button logic. */ protected final void nextButtonSetEnabled(final boolean enable) { if (skipButtonIsSelected()) { return; } else { if (enable) { skipButtonSetEnabled(false); } else { skipButtonSetEnabled(true); } SwingUtilities.invokeLater( new Runnable() { @Override public void run() { buttonClass(nextButton()).setEnabled(enable); if (enable) { makeDefaultAndRequestFocus(buttonClass(nextButton())); } } }); } } /** Returns icons for the buttons. */ @Override protected final ImageIcon[] getIcons() { final ImageIcon[] icons = {null, BACK_ICON, NEXT_ICON, FINISH_ICON, CANCEL_ICON}; return icons; } /** Returns default button, none by default. */ @Override protected final String defaultButton() { return null; } /** After next or finish buttons are pressed, this function is called. */ protected final boolean checkAfterNextFinish() { return true; } /** After next or finish buttons are pressed, this function is called. */ protected void finishDialog() { /* no action */ } /** Returns next dialog, that follows after pressing next button. */ public abstract WizardDialog nextDialog(); /** Enables components except the ones that are passed as the argument. */ @Override protected final void enableComponents(final JComponent[] componentsToDisable) { super.enableComponents(componentsToDisable); SwingUtilities.invokeLater( new Runnable() { @Override public void run() { if (buttonClass(retryButton()) != null && buttonClass(retryButton()).isVisible() && buttonClass(retryButton()).isEnabled()) { makeDefaultAndRequestFocus(buttonClass(retryButton())); } else if (buttonClass(nextButton()) != null && buttonClass(nextButton()).isEnabled()) { makeDefaultAndRequestFocus(buttonClass(nextButton())); } else if (buttonClass(finishButton()) != null && buttonClass(finishButton()).isEnabled()) { makeDefaultAndRequestFocus(buttonClass(finishButton())); } } }); } /** Requests focus. */ protected final void makeDefaultAndRequestFocus(final JComponent b) { if (b instanceof JButton) { getDialogPanel().getRootPane().setDefaultButton((JButton) b); } b.requestFocus(); } /** Requests focus in the swing thread. */ protected final void makeDefaultAndRequestFocusLater(final JComponent b) { SwingUtilities.invokeLater( new Runnable() { public void run() { makeDefaultAndRequestFocus(b); } }); } /** Sets as default button. */ protected final void makeDefaultButton(final JButton b) { getDialogPanel().getRootPane().setDefaultButton(b); } /** Enables components. */ @Override protected final void enableComponents() { enableComponents(new JComponent[] {}); } /** Inits the dialog. */ @Override protected void initDialog() { /* align buttons to the right */ final FlowLayout layout = new FlowLayout(); layout.setAlignment(FlowLayout.RIGHT); if (buttonClass(cancelButton()) != null) { buttonClass(cancelButton()).getParent().setLayout(layout); } /* disable back button if there is no previous dialog */ if (previousDialog == null && buttonClass(backButton()) != null) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { buttonClass(backButton()).setEnabled(false); } }); } /* disable next and finish buttons */ if (buttonClass(nextButton()) != null) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { buttonClass(nextButton()).setEnabled(false); } }); } if (buttonClass(finishButton()) != null) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { buttonClass(finishButton()).setEnabled(false); } }); } if (buttonClass(retryButton()) != null) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { buttonClass(retryButton()).setVisible(false); buttonClass(retryButton()).setBackgroundColor(Color.RED); } }); } disableComponents(); } /** if retry button was pressed this method will be executed. */ protected final void retryWasPressed() { /* no action */ } /** if back button was pressed this method will be executed. */ protected final void backButtonWasPressed() { /* no action */ } /** * Check which button was pressed. Return previous dialog if back button was pressed. Call * checkAfterNextFinish() if next or back button were pressed. If checkAfterNextFinish() returns * true return next dialog, if next button was pressed. */ @Override protected final ConfigDialog checkAnswer() { if (isPressedButton(backButton())) { backButtonWasPressed(); return getPreviousDialog(); } if (isPressedButton(nextButton()) || isPressedButton(finishButton()) || isPressedButton(retryButton())) { if (checkAfterNextFinish()) { finishDialog(); if (isPressedButton(nextButton())) { return nextDialog(); } else if (isPressedButton(retryButton())) { retryWasPressed(); setDialogPanel(null); return this; } else { return null; } } else { return this; } } return null; } /** prints error text in the answer pane, reenables buttons and adds retry button. */ public void printErrorAndRetry(final String text) { printErrorAndRetry(text, null, 0); } /** prints error text in the answer pane, reenables buttons and adds retry button. */ public final void printErrorAndRetry(String text, final String ans, final int exitCode) { if (ans != null) { text += "\n" + Tools.getString("Dialog.Dialog.PrintErrorAndRetry") + exitCode + "\n" + ans; } answerPaneSetTextError(text); addRetryButton(); if (buttonClass(retryButton()) != null) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { buttonClass(retryButton()).requestFocus(); } }); } if (buttonClass(nextButton()) != null) { enableComponents(new JComponent[] {buttonClass(nextButton())}); SwingUtilities.invokeLater( new Runnable() { @Override public void run() { buttonClass(nextButton()).setEnabled(false); } }); } } /** Reenables buttons and adds retry button. */ public final void retry() { addRetryButton(); if (buttonClass(retryButton()) != null) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { buttonClass(retryButton()).requestFocus(); } }); if (buttonClass(nextButton()) != null) { enableComponents(new JComponent[] {buttonClass(nextButton())}); SwingUtilities.invokeLater( new Runnable() { @Override public void run() { buttonClass(nextButton()).setEnabled(false); } }); } } } /** Adds the retry button. */ final void addRetryButton() { if (buttonClass(retryButton()) != null) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { getOptionPane().setInitialValue(buttonClass(retryButton())); } }); } // setInitialValue destroys layout, so once // again... final FlowLayout layout = new FlowLayout(); layout.setAlignment(FlowLayout.RIGHT); if (buttonClass(cancelButton()) != null) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { final Container parent = buttonClass(cancelButton()).getParent(); if (parent != null) { buttonClass(cancelButton()).getParent().setLayout(layout); } } }); } if (buttonClass(retryButton()) != null) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { buttonClass(retryButton()).setVisible(true); buttonClass(retryButton()).setEnabled(true); } }); } } /** Hides the retry button if it is there. */ public final void hideRetryButton() { final MyButton rb = buttonClass(retryButton()); if (rb != null && rb.isVisible()) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { rb.setVisible(false); } }); } } /** Presses the retry button. */ final void pressRetryButton() { final MyButton rb = buttonClass(retryButton()); if (rb != null && rb.isVisible() && rb.isEnabled()) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { rb.pressButton(); } }); } } /** Presses the next button. */ public final void pressNextButton() { final MyButton nb = buttonClass(nextButton()); if (nb != null) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { if (nb.isVisible() && nb.isEnabled()) { nb.pressButton(); } } }); } } /** * Creates progress bar that can be used during connecting to the host and returns pane, where the * progress bar is displayed. */ public JPanel getProgressBarPane(final CancelCallback cancelCallback) { progressBar = new ProgressBar(cancelCallback); final JPanel p = progressBar.getProgressBarPane(); p.setBackground(Tools.getDefaultColor("ConfigDialog.Background.Dark")); return p; } /** Is called after failed connection. */ public final void progressBarDoneError() { progressBar.doneError(); } /** Is called after successful connection. */ public final void progressBarDone() { progressBar.done(); } /** Returns progressBar object. */ public final ProgressBar getProgressBar() { return progressBar; } /** * Creates progress bar that can be used during connecting to the host and returns pane, where the * progress bar is displayed. */ public final JPanel getProgressBarPane(final String title, final CancelCallback cancelCallback) { progressBar = new ProgressBar(title, cancelCallback); final JPanel p = progressBar.getProgressBarPane(); p.setBackground(Tools.getDefaultColor("ConfigDialog.Background.Dark")); return p; } }
/** * An implementation of an empty tab panel with new cluster and host button. * * @author Rasto Levrinc * @version $Id$ */ final class EmptyViewPanel extends ViewPanel implements AllHostsUpdatable { /** Serial version UID. */ private static final long serialVersionUID = 1L; /** Browser. */ private final EmptyBrowser browser; /** Background color of the status panel. */ private static final Color STATUS_BACKGROUND = Tools.getDefaultColor("ViewPanel.Status.Background"); /** Add cluster icon. */ private static final ImageIcon CLUSTER_ICON = Tools.createImageIcon(Tools.getDefault("ClusterTab.ClusterIcon")); /** Add host icon. */ private static final ImageIcon HOST_ICON = Tools.createImageIcon(Tools.getDefault("HostTab.HostIcon")); /** Dimension of the big buttons. */ private static final Dimension BIG_BUTTON_DIMENSION = new Dimension(300, 100); /** Logo panel for card layout. */ private static final String LOGO_PANEL_STRING = "LOGO-STRING"; /** Prepares a new <code>ClusterViewPanel</code> object. */ EmptyViewPanel() { super(); browser = new EmptyBrowser(); Tools.getGUIData().setEmptyBrowser(browser); browser.setEmptyViewPanel(this); browser.initHosts(); final JPanel buttonPanel = new JPanel(new FlowLayout()); buttonPanel.setMinimumSize(new Dimension(0, 110)); buttonPanel.setPreferredSize(new Dimension(0, 110)); buttonPanel.setMaximumSize(new Dimension(Short.MAX_VALUE, 110)); buttonPanel.setBackground(STATUS_BACKGROUND); add(buttonPanel, BorderLayout.NORTH); final JPanel logoPanel = new JPanel(new CardLayout()); logoPanel.setBackground(java.awt.Color.WHITE); final ImageIcon logoImage = Tools.createImageIcon("startpage_head.jpg"); final JLabel logo = new JLabel(logoImage); final JPanel lPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); lPanel.setBackground(java.awt.Color.WHITE); lPanel.add(logo); logoPanel.add(lPanel, LOGO_PANEL_STRING); final JPanel smallButtonPanel = new JPanel(); smallButtonPanel.setBackground(STATUS_BACKGROUND); smallButtonPanel.setLayout(new BoxLayout(smallButtonPanel, BoxLayout.Y_AXIS)); buttonPanel.add(smallButtonPanel); /* check for upgrade field. */ smallButtonPanel.add(Tools.getGUIData().getClustersPanel().registerUpgradeTextField()); /* add new host button */ final MyButton addHostButton = new MyButton(Tools.getString("ClusterTab.AddNewHost"), HOST_ICON); addHostButton.setBackgroundColor(Browser.STATUS_BACKGROUND); addHostButton.setPreferredSize(BIG_BUTTON_DIMENSION); addHostButton.addActionListener( new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { final Thread thread = new Thread( new Runnable() { @Override public void run() { final AddHostDialog ahd = new AddHostDialog(); ahd.showDialogs(); } }); thread.start(); } }); Tools.getGUIData().registerAddHostButton(addHostButton); buttonPanel.add(addHostButton); createEmptyView(); add(logoPanel, BorderLayout.SOUTH); Tools.getGUIData().registerAllHostsUpdate(this); Tools.getGUIData().allHostsUpdate(); /* add new cluster button */ final MyButton addClusterButton = new MyButton(Tools.getString("ClusterTab.AddNewCluster"), CLUSTER_ICON); addClusterButton.setBackgroundColor(Browser.STATUS_BACKGROUND); addClusterButton.setPreferredSize(BIG_BUTTON_DIMENSION); addClusterButton.setMinimumSize(BIG_BUTTON_DIMENSION); addClusterButton.addActionListener( new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { final Thread thread = new Thread( new Runnable() { @Override public void run() { AddClusterDialog acd = new AddClusterDialog(); acd.showDialogs(); } }); thread.start(); } }); Tools.getGUIData().registerAddClusterButton(addClusterButton); Tools.getGUIData().checkAddClusterButtons(); buttonPanel.add(addClusterButton); if (!Tools.getConfigData().getAutoHosts().isEmpty()) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { addHostButton.pressButton(); } }); } } /** creates cluster view and updates the tree. */ private void createEmptyView() { getTree(browser); browser.updateHosts(); } /** Updates the all hosts menu item. */ @Override public void allHostsUpdate() { browser.updateHosts(); } }