package com.ibm.nmon.gui.analysis;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import java.util.BitSet;
import com.ibm.nmon.analysis.AnalysisSet;
import com.ibm.nmon.analysis.Statistic;
import com.ibm.nmon.data.DataSet;
import com.ibm.nmon.gui.main.NMONVisualizerGui;
/**
* Table model that displays min, max, average and standard deviation for each measurement in an
* AnalysisSet. Data for all data sets is displayed, one row per file / measurement combination.
*/
public final class ByStatisticTableModel extends AnalysisSetTableModel implements PropertyChangeListener {
private static final long serialVersionUID = 2863125593272808676L;
// last null is for GRANULARITY_MAXIMUM which will have a custom name
private static final String[] COLUMN_NAMES = new String[] { "Hostname", "Data Type", "Metric",
Statistic.MINIMUM.toString(), Statistic.AVERAGE.toString(), Statistic.MAXIMUM.toString(),
Statistic.STD_DEV.toString(), Statistic.MEDIAN.toString(), Statistic.SUM.toString(),
Statistic.COUNT.toString(), null };
private static final boolean[] DEFAULT_COLUMNS = new boolean[] { true, true, true, true, true, true, true, false,
false, false, false };
static {
if (COLUMN_NAMES.length != DEFAULT_COLUMNS.length) {
throw new IllegalArgumentException("default values array size not equal to column names size "
+ COLUMN_NAMES.length + " != " + DEFAULT_COLUMNS.length);
}
}
public ByStatisticTableModel(NMONVisualizerGui gui, AnalysisSet analysisSet) {
super(gui, analysisSet);
COLUMN_NAMES[COLUMN_NAMES.length - 1] = Statistic.GRANULARITY_MAXIMUM.getName(gui.getGranularity());
buildColumnNameMap();
enabledColumns = new BitSet(COLUMN_NAMES.length);
for (int i = 0; i < DEFAULT_COLUMNS.length; i++) {
enabledColumns.set(i, DEFAULT_COLUMNS[i]);
}
// alert the owning table that it has columns so it can be sized in the column model
fireTableStructureChanged();
}
@Override
public String getKey(int index) {
int keyIndex = index / gui.getDataSetCount();
return keys.get(keyIndex);
}
@Override
public int getRowCount() {
// each file displays a measurement for every key
return keys.size() * gui.getDataSetCount();
}
@Override
public String[] getAllColumns() {
return COLUMN_NAMES;
}
@Override
public boolean getDefaultColumnState(int column) {
return DEFAULT_COLUMNS[column];
}
@Override
public boolean canDisableColumn(int column) {
if (column < 3) {
return false;
}
else {
return true;
}
}
@Override
protected Class<?> getEnabledColumnClass(int columnIndex) {
if (columnIndex < 3) {
return String.class;
}
else if (columnIndex == 9) {
return Integer.class;
}
else {
return Double.class;
}
}
@Override
protected String getEnabledColumnName(int column) {
return COLUMN_NAMES[column];
}
@Override
protected Object getEnabledValueAt(int rowIndex, int columnIndex) {
// display table as
// file 1, key 1
// file 2, key 1
// ...
// file 1, key 1
// file 2, key 2
// ...
// file n, key n
// need to map key rows from base model to actual rows
int fileIndex = rowIndex % gui.getDataSetCount();
DataSet data = null;
int n = 0;
for (DataSet toSearch : gui.getDataSets()) {
if (n++ == fileIndex) {
data = toSearch;
break;
}
}
if (data == null) {
throw new ArrayIndexOutOfBoundsException(rowIndex);
}
int keyIndex = rowIndex / gui.getDataSetCount();
String key = keys.get(keyIndex);
switch (columnIndex) {
case 0:
return data.toString();
case 1:
return analysisSet.getType(key);
case 2:
return analysisSet.getField(key);
case 3:
return gui.getAnalysis(data).getMinimum(analysisSet.getType(key), analysisSet.getField(key));
case 4:
return gui.getAnalysis(data).getAverage(analysisSet.getType(key), analysisSet.getField(key));
case 5:
return gui.getAnalysis(data).getMaximum(analysisSet.getType(key), analysisSet.getField(key));
case 6:
return gui.getAnalysis(data).getStandardDeviation(analysisSet.getType(key), analysisSet.getField(key));
case 7:
return gui.getAnalysis(data).getMedian(analysisSet.getType(key), analysisSet.getField(key));
case 8:
return gui.getAnalysis(data).getSum(analysisSet.getType(key), analysisSet.getField(key));
case 9:
return gui.getAnalysis(data).getCount(analysisSet.getType(key), analysisSet.getField(key));
case 10:
return gui.getAnalysis(data).getGranularityMaximum(analysisSet.getType(key), analysisSet.getField(key));
default:
return new ArrayIndexOutOfBoundsException(columnIndex);
}
}
// base table model fires updates on key changes
// this model needs to update a row for each file
@Override
public void fireTableRowsInserted(int firstRow, int lastRow) {
for (int i = firstRow; i <= lastRow; i++) {
for (int j = 0; j < gui.getDataSetCount(); j++) {
int actualRow = i * gui.getDataSetCount() + j;
super.fireTableRowsInserted(actualRow, actualRow);
}
}
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("granularity".equals(evt.getPropertyName())) {
updateGranularityMax();
}
}
void updateGranularityMax() {
COLUMN_NAMES[COLUMN_NAMES.length - 1] = Statistic.GRANULARITY_MAXIMUM.getName(gui.getGranularity());
buildColumnNameMap();
if (enabledColumns.get(COLUMN_NAMES.length - 1)) {
// update granularity max column name
fireTableStructureChanged();
}
}
}