/*
* (C) Copyright IBM Corp. 2009
*
* LICENSE: Eclipse Public License v1.0
* http://www.eclipse.org/legal/epl-v10.html
*/
package com.ibm.gaiandb.apps.dashboard;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.Map.Entry;
import java.util.logging.Logger;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.Border;
public class StatsTab extends UpdatingTab {
// Use PROPRIETARY notice if class contains a main() method, otherwise use COPYRIGHT notice.
public static final String COPYRIGHT_NOTICE = "(c) Copyright IBM Corp. 2009";
private static final long serialVersionUID = 3463679662252114164L;
private static final Logger LOGGER = Logger.getLogger(StatsTab.class.getName());
private static final int INTERVAL = 1000;
private static final int CHART_HEIGHT = 80;
private static final int CHART_INSET_SIZE = 5;
private static final int CHART_DURATION = 60;
private static final int NODE_SELECTION_PANEL_WIDTH = 120;
private static final Color UNSELECTED_NODE_COLOR = Color.BLACK;
Map<String, StatsChart> charts;
private MetricValueProcessor valueProcessor;
private Set<String> liveNodes;
private Map<String, Color> selectedNodes;
private ColorAllocator<String> nodeColorAllocator;
private JPanel nodeSelectionPanel, nodeSelectionContainer;
private JPanel chartPanel;
private JScrollPane chartPanelScroller;
private final ItemListener nodeCheckBoxSelected = new ItemListener() {
public void itemStateChanged(ItemEvent e) {
JCheckBox checkBox = (JCheckBox)e.getSource();
String node = checkBox.getText();
boolean checked = e.getStateChange() == ItemEvent.SELECTED;
if (checked) {
Color color = nodeColorAllocator.get(node);
selectedNodes.put(node, color);
checkBox.setForeground(color);
}
else {
selectedNodes.remove(node);
checkBox.setForeground(UNSELECTED_NODE_COLOR);
nodeColorAllocator.deallocate(node);
}
}
};
public StatsTab(Dashboard container) {
super(container);
}
protected void create() {
Border rightBorder = BorderFactory.createEmptyBorder(
0, 0, 0, Dashboard.BORDER_SIZE);
nodeSelectionContainer = new JPanel();
nodeSelectionContainer.setLayout(new BoxLayout(nodeSelectionContainer, BoxLayout.PAGE_AXIS));
JLabel nodeSelectionLabel = new JLabel("Nodes:");
nodeSelectionPanel = new JPanel();
nodeSelectionPanel.setLayout(new BoxLayout(nodeSelectionPanel, BoxLayout.PAGE_AXIS));
nodeSelectionPanel.setBackground(Color.WHITE);
nodeSelectionContainer.add(nodeSelectionLabel);
nodeSelectionContainer.add(createScroller(nodeSelectionPanel, NODE_SELECTION_PANEL_WIDTH, -1));
chartPanel = new JPanel();
chartPanel.setLayout(new BoxLayout(chartPanel, BoxLayout.PAGE_AXIS));
chartPanel.setBorder(rightBorder);
charts = new LinkedHashMap<String, StatsChart>();
selectedNodes = new HashMap<String, Color>();
nodeColorAllocator = new ColorAllocator<String>();
for (MonitorInfo monitor : MetricValueProcessor.MONITORS) {
if ( monitor.isInternalMetric() ) continue;
StatsChart chart = new StatsChart(CHART_DURATION, selectedNodes);
chart.setInsets(CHART_INSET_SIZE);
chart.setTitle(monitor.name + " (" + monitor.unit + ")");
if (monitor.hardBounds) {
chart.setValueRange(monitor.minBound, monitor.maxBound);
}
charts.put(monitor.name, chart);
}
boolean first = true;
for (StatsChart chart : charts.values()) {
chart.setBackground(Color.WHITE);
chart.setBorder(BorderFactory.createEtchedBorder());
chart.setPreferredSize(new Dimension(-1, CHART_HEIGHT));
JLabel label = new JLabel(chart.getTitle() + ":");
if (first) {
first = false;
}
else {
label.setBorder(BorderFactory.createEmptyBorder(
Dashboard.BORDER_SIZE, 0, 0, 0));
}
chartPanel.add(label);
chartPanel.add(chart);
}
chartPanelScroller = createScroller(chartPanel, BorderFactory.createEmptyBorder(), -1, -1);
try {
valueProcessor = new MetricValueProcessor(conn) {
public void processHistoricalMetrics(int maxAge) throws SQLException {
liveNodes = new TreeSet<String>();
super.processHistoricalMetrics(maxAge);
}
protected void add(String node, int timestamp, Map<MonitorInfo, Integer> values) {
liveNodes.add(node);
for (Entry<MonitorInfo, Integer> current : values.entrySet()) {
MonitorInfo monitor = current.getKey();
if ( monitor.isInternalMetric() ) continue;
Integer value = current.getValue();
if (null != value) {
charts.get(monitor.name).addStat(node, timestamp, value);
}
}
}
};
valueProcessor.setAllMonitors();
// valueProcessor.setTopologyGraph(TopologyGraph.getSingleton());
}
catch (SQLException e) {
if (container.checkConnection()) {
LOGGER.severe(unravelMessages(e));
destroy();
showError("Could not query the database.");
}
return;
}
addUpdater(new Updater("StatsTab.updateCharts", INTERVAL) {
protected boolean update() {
return updateCharts();
}
});
hideMessage();
add(nodeSelectionContainer, BorderLayout.LINE_START);
add(chartPanelScroller);
}
protected boolean updateCharts() {
try {
synchronized (nodeSelectionPanel) {
valueProcessor.processHistoricalMetrics(CHART_DURATION);
Component[] components = nodeSelectionPanel.getComponents();
for (Component component : components) {
String node = ((JCheckBox)component).getText();
if (!liveNodes.contains(node)) {
selectedNodes.remove(node);
nodeColorAllocator.deallocate(node);
nodeSelectionPanel.remove(component);
}
}
int count = nodeSelectionPanel.getComponentCount();
for (String node : liveNodes) {
int position = 0;
int comparison = -1;
while (position < count && (comparison = node.compareTo(((JCheckBox)nodeSelectionPanel.getComponent(position)).getText())) > 0) {
position++;
}
if (comparison != 0) {
JCheckBox checkBox = new JCheckBox(node);
checkBox.setContentAreaFilled(false);
checkBox.addItemListener(nodeCheckBoxSelected);
nodeSelectionPanel.add(checkBox, position);
count++;
if (node.equals(container.getLocalNodeID())) {
Color color = nodeColorAllocator.get(node);
selectedNodes.put(node, color);
checkBox.setForeground(color);
checkBox.setSelected(true);
}
else {
checkBox.setForeground(UNSELECTED_NODE_COLOR);
checkBox.setSelected(false);
}
}
}
}
validate();
repaint();
}
catch (SQLException e) {
if (container.checkConnection()) {
LOGGER.severe(unravelMessages(e));
destroy();
showError("Could not query the database.");
}
return false;
}
return true;
}
protected void destroy() {
if (null != nodeSelectionPanel) {
synchronized (nodeSelectionPanel) {
remove(nodeSelectionContainer);
nodeSelectionContainer = null;
nodeSelectionPanel = null;
liveNodes = null;
}
}
if (null != chartPanel) {
remove(chartPanelScroller);
chartPanelScroller = null;
chartPanel = null;
charts = null;
}
}
}