package com.vistatec.ocelot.lqi.gui;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.table.AbstractTableModel;
import com.vistatec.ocelot.lqi.model.LQIErrorCategory;
import com.vistatec.ocelot.lqi.model.LQIGrid;
import com.vistatec.ocelot.lqi.model.LQISeverity;
import com.vistatec.ocelot.lqi.model.LQIShortCut;
/**
* Table model for the LQI grid.
*/
public class LQIGridTableModel extends AbstractTableModel {
/** Serial version UID. */
private static final long serialVersionUID = -1813995821444213075L;
/** Error category column index. */
private static final int ERROR_CAT_COLUMN = 0;
/** The error category weight column index. */
private static final int ERROR_CAT_WEIGHT_COLUMN = 1;
/** Comment column index. */
private static final int COMMENT_COLUMN = 2;
/** List if severity columns. */
private List<LQIGridColumn> severityColumns;
/** List of fixed columns. */
private List<LQIGridColumn> fixedColumns = new ArrayList<LQIGridColumn>(
Arrays.asList(new LQIGridColumn[] {
new LQIGridColumn("Error Category"),
new LQIGridColumn("Weight"), new LQIGridColumn("Comment") }));
/** The list of table columns. */
private List<LQIGridColumn> tableColumns;
/** A map stating which columns are enabled. */
private Map<LQIGridColumn, Boolean> enabledColumns;
/** The LQI grid object. */
private LQIGrid lqiGridObj;
/** The current mode (Issue creation/configuration) */
private int mode;
/**
* A boolean stating if the model has been changed when in configuration
* mode.
*/
private boolean changed;
/** List of cell listeners. */
private List<TableCellListener> cellListeners;
/**
* Constructor.
*
* @param lqiGridObj
* the lQI grid object.
* @param mode
* the current LQI grid mode.
*/
public LQIGridTableModel(final LQIGrid lqiGridObj, final int mode) {
this.lqiGridObj = lqiGridObj;
this.mode = mode;
initColumns();
}
/**
* Changes the mode.
*/
private void changedMode() {
enabledColumns.put(fixedColumns.get(ERROR_CAT_WEIGHT_COLUMN),
mode == LQIGridDialog.CONFIG_MODE);
fireTableStructureChanged();
}
/**
* Initializes the columns.
*/
private void initColumns() {
enabledColumns = new HashMap<LQIGridColumn, Boolean>();
for (LQIGridColumn col : fixedColumns) {
enabledColumns.put(col, true);
}
if (lqiGridObj != null && lqiGridObj.getSeverities() != null) {
severityColumns = new ArrayList<LQIGridColumn>();
LQIGridColumn sevColumn = null;
for (LQISeverity sev : lqiGridObj.getSeverities()) {
sevColumn = new LQIGridColumn(sev.getName());
severityColumns.add(sevColumn);
enabledColumns.put(sevColumn, true);
}
}
tableColumns = new ArrayList<LQIGridColumn>();
tableColumns.add(fixedColumns.get(ERROR_CAT_COLUMN));
tableColumns.add(fixedColumns.get(ERROR_CAT_WEIGHT_COLUMN));
tableColumns.addAll(severityColumns);
tableColumns.add(fixedColumns.get(COMMENT_COLUMN));
changedMode();
}
/*
* (non-Javadoc)
*
* @see javax.swing.table.TableModel#getRowCount()
*/
@Override
public int getRowCount() {
int count = 0;
if (lqiGridObj != null && lqiGridObj.getErrorCategories() != null) {
count = lqiGridObj.getErrorCategories().size();
}
return count;
}
/*
* (non-Javadoc)
*
* @see javax.swing.table.TableModel#getColumnCount()
*/
@Override
public int getColumnCount() {
int count = 0;
for (LQIGridColumn col : fixedColumns) {
if (enabledColumns.get(col)) {
count++;
}
}
for (LQIGridColumn col : severityColumns) {
if (enabledColumns.get(col)) {
count++;
}
}
return count;
}
/**
* Gets the severity columns count.
*
* @return the severity columns count.
*/
public int getSeverityColumnsCount() {
int count = 0;
if (severityColumns != null) {
count = severityColumns.size();
}
return count;
}
/**
* Gets the severity columns start index.
*
* @return the severity columns start index.
*/
public int getSeverityColsStartIndex() {
int index = -1;
if (severityColumns != null && !severityColumns.isEmpty()) {
index = getColumnIndex(severityColumns.get(0));
}
return index;
}
/**
* Gets the column corresponding to the given index.
*
* @param colIndex
* the column index.
* @return the column corresponding to the given index.
*/
private LQIGridColumn getColumn(int colIndex) {
LQIGridColumn column = null;
int count = 0;
for (LQIGridColumn col : tableColumns) {
if (enabledColumns.get(col)) {
if (count == colIndex) {
column = col;
break;
}
count++;
}
}
return column;
}
/**
* Gets the column index for a specific column.
*
* @param column
* the column.
* @return the column index.
*/
private int getColumnIndex(LQIGridColumn column) {
int colIndex = -1;
if (enabledColumns.get(column)) {
for (LQIGridColumn col : tableColumns) {
if (enabledColumns.get(col)) {
colIndex++;
}
if (col.equals(column)) {
break;
}
}
}
return colIndex;
}
/*
* (non-Javadoc)
*
* @see javax.swing.table.AbstractTableModel#getColumnName(int)
*/
@Override
public String getColumnName(int colIndex) {
String colName = null;
if (colIndex < tableColumns.size()) {
LQIGridColumn column = getColumn(colIndex);
colName = column.getName();
if (severityColumns.contains(column)) {
colName += " (" + lqiGridObj.getSeverityScore(colName) + ")";
}
}
return colName;
}
/*
* (non-Javadoc)
*
* @see javax.swing.table.TableModel#getValueAt(int, int)
*/
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Object retValue = null;
if (lqiGridObj != null && lqiGridObj.getErrorCategories() != null
&& rowIndex < lqiGridObj.getErrorCategories().size()) {
LQIErrorCategory errorCat = lqiGridObj.getErrorCategories().get(
rowIndex);
LQIGridColumn col = getColumn(columnIndex);
if (fixedColumns.contains(col)) {
if (col.equals(fixedColumns.get(ERROR_CAT_COLUMN))) {
retValue = errorCat.getName();
} else if (col
.equals(fixedColumns.get(ERROR_CAT_WEIGHT_COLUMN))
&& errorCat.getWeight() > 0) {
retValue = errorCat.getWeight();
} else if (col.equals(fixedColumns.get(COMMENT_COLUMN))) {
errorCat.getComment();
}
} else if (severityColumns.contains(col)) {
retValue = errorCat.getShortcut(col.getName());
}
}
return retValue;
}
/*
* (non-Javadoc)
*
* @see javax.swing.table.AbstractTableModel#setValueAt(java.lang.Object,
* int, int)
*/
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (lqiGridObj != null && lqiGridObj.getErrorCategories() != null
&& !lqiGridObj.getErrorCategories().isEmpty()) {
LQIErrorCategory errorCat = lqiGridObj.getErrorCategories().get(
rowIndex);
LQIGridColumn col = getColumn(columnIndex);
if (col != null) {
if (col.equals(fixedColumns.get(ERROR_CAT_COLUMN))) {
if (aValue != null && !((String) aValue).isEmpty()
&& !errorCat.getName().equals((String) aValue)) {
TableCellEvent event = new TableCellEvent(
errorCat.getName(), aValue, rowIndex,
columnIndex);
errorCat.setName((String) aValue);
if (cellListeners != null) {
for (TableCellListener listener : cellListeners) {
listener.cellValueChanged(event);
}
}
changed = true;
}
} else if (col.equals(fixedColumns.get(COMMENT_COLUMN))) {
errorCat.setComment((String) aValue);
} else if (col
.equals(fixedColumns.get(ERROR_CAT_WEIGHT_COLUMN))) {
String weigthString = (String) aValue;
errorCat.setWeight(Float.parseFloat(weigthString));
changed = true;
}
}
}
}
/*
* (non-Javadoc)
*
* @see javax.swing.table.AbstractTableModel#isCellEditable(int, int)
*/
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
LQIGridColumn col = getColumn(columnIndex);
return col != null
&& (mode == LQIGridDialog.ISSUES_ANNOTS_MODE && !col
.equals(fixedColumns.get(ERROR_CAT_COLUMN)))
|| (mode == LQIGridDialog.CONFIG_MODE && !col
.equals(fixedColumns.get(COMMENT_COLUMN)));
}
/**
* Gets the error category object at a specific row.
*
* @param row
* the row
* @return the error category at that row.
*/
public LQIErrorCategory getErrorCategoryAtRow(int row) {
LQIErrorCategory errorCat = null;
if (lqiGridObj != null && lqiGridObj.getErrorCategories() != null
&& row < lqiGridObj.getErrorCategories().size()) {
errorCat = lqiGridObj.getErrorCategories().get(row);
}
return errorCat;
}
/**
* Gets the error category column index.
*
* @return the error category column index.
*/
public int getErrorCategoryColumn() {
return getColumnIndex(fixedColumns.get(ERROR_CAT_COLUMN));
}
/**
* Gets the comment column index.
*
* @return the comment column index.
*/
public int getCommentColumn() {
return getColumnIndex(fixedColumns.get(COMMENT_COLUMN));
}
/**
* Gets the error category weight column index.
*
* @return the error category weight column index.
*/
public int getErrorCatWeightColumn() {
return getColumnIndex(fixedColumns.get(ERROR_CAT_WEIGHT_COLUMN));
}
/**
* Gets the severity score for a specific severity column.
*
* @param column
* the column index
* @return the severity score
*/
public double getScoreForColumn(int column) {
double score = 0;
LQIGridColumn col = getColumn(column);
if (col != null && severityColumns.contains(col)) {
score = lqiGridObj.getSeverityScore(col.getName());
}
return score;
}
/**
* Sets the score value for a specific severity column.
*
* @param score
* the score value
* @param column
* the severity column index.
*/
public void setScoreForColumn(double score, int column) {
LQIGridColumn col = getColumn(column);
if (col != null && severityColumns.contains(col)) {
lqiGridObj.setSeverityScore(col.getName(), score);
changed = true;
}
}
/**
* Gets the severity name for a specific column.
*
* @param severityColumn
* the severity column index
* @return the severity name.
*/
public String getSeverityNameForColumn(int severityColumn) {
String severityName = "";
LQIGridColumn col = getColumn(severityColumn);
if (severityColumns.contains(col)) {
severityName = col.getName();
}
return severityName;
}
/**
* Gets the column index for a specific severity.
*
* @param severityName
* the severity name.
* @return the column index.
*/
public int getSeverityColIndex(String severityName) {
int index = -1;
LQIGridColumn sevColumn = null;
if (severityColumns != null) {
for (LQIGridColumn sevCol : severityColumns) {
if (sevCol.getName().equals(severityName)) {
sevColumn = sevCol;
break;
}
}
}
if (sevColumn != null) {
index = getColumnIndex(sevColumn);
}
return index;
}
/**
* Sets a new shortcut for a cell at specific row and column.
*
* @param row
* the row
* @param column
* the column
* @param keyCode
* the shortcut key code
* @param modifiers
* the shortcut modifiers
*/
public void setShortCut(int row, int column, int keyCode, int[] modifiers) {
if (lqiGridObj != null && lqiGridObj.getErrorCategories() != null
&& row < lqiGridObj.getErrorCategories().size()) {
LQIErrorCategory errorCat = lqiGridObj.getErrorCategories()
.get(row);
LQIGridColumn col = getColumn(column);
if (col != null && severityColumns.contains(col)) {
LQIShortCut newShortCut = new LQIShortCut(
lqiGridObj.getSeverity(col.getName()), keyCode,
modifiers);
errorCat.setShortcut(newShortCut);
changed = true;
}
fireTableCellUpdated(row, column);
}
}
/**
* Sets the mode.
*
* @param mode
* the mode.
*/
public void setMode(int mode) {
this.mode = mode;
changedMode();
}
/**
* Gets the mode.
*
* @return the mode.
*/
public int getMode() {
return mode;
}
/**
* Set the changed value.
*
* @param changed
* a boolean value for the changed field.
*/
public void setChanged(boolean changed) {
this.changed = changed;
}
/**
* Checks if the model has changed.
*
* @return <code>true</code> if the model has changed; <code>false</code>
* otherwise
*/
public boolean isChanged() {
return changed;
}
/**
* Gets the LQI grid object.
*
* @return the LQI grid object.
*/
public LQIGrid getLQIGrid() {
return lqiGridObj;
}
/**
* Sets the LQI grid.
*
* @param lqiGrid
* the LQI grid.
*/
public void setLQIGrid(LQIGrid lqiGrid) {
this.lqiGridObj = lqiGrid;
initColumns();
fireTableDataChanged();
}
/**
* Adds a new row to the model.
*
* @return the error category related to the added row.
*/
public LQIErrorCategory addRow() {
LQIErrorCategory newErrorCat = null;
if (lqiGridObj != null) {
newErrorCat = new LQIErrorCategory("");
if (lqiGridObj.getErrorCategories() == null) {
lqiGridObj
.setErrorCategories(new ArrayList<LQIErrorCategory>());
}
lqiGridObj.getErrorCategories().add(newErrorCat);
changed = true;
fireTableRowsInserted(lqiGridObj.getErrorCategories().size() - 1,
lqiGridObj.getErrorCategories().size() - 1);
}
return newErrorCat;
}
/**
* Deletes a specific row.
*
* @param rowIndex
* the row index.
* @return the deleted error category object.
*/
public LQIErrorCategory deleteRow(int rowIndex) {
LQIErrorCategory deletedErrorCat = null;
if (lqiGridObj != null && lqiGridObj.getErrorCategories() != null
&& rowIndex < lqiGridObj.getErrorCategories().size()) {
deletedErrorCat = lqiGridObj.getErrorCategories().remove(rowIndex);
changed = true;
fireTableRowsDeleted(rowIndex, rowIndex);
}
return deletedErrorCat;
}
/**
* Adds a table cell listener.
*
* @param listener
* the table cell listener.
*/
public void addTableCellListener(TableCellListener listener) {
if (cellListeners == null) {
cellListeners = new ArrayList<TableCellListener>();
}
cellListeners.add(listener);
}
/**
* Removes a specific table cell listener.
*
* @param listener
* table cell listener to remove.
*/
public void removeTableCellListener(TableCellListener listener) {
if (cellListeners != null) {
cellListeners.remove(listener);
}
}
/**
* Gets all LQI categories currently in use in the LQI grid.
*
* @return
*/
public List<String> getUsedCategoryName() {
List<String> usedNames = new ArrayList<String>();
if (lqiGridObj != null && lqiGridObj.getErrorCategories() != null) {
for (LQIErrorCategory errCat : lqiGridObj.getErrorCategories()) {
usedNames.add(errCat.getName());
}
}
return usedNames;
}
/**
* Moves a row up.
*
* @param row
* the row index.
* @return <code>true</code> if the row has been moved; <code>false</code>
* otherwise.
*/
public boolean moveRowUp(int row) {
boolean moved = false;
if (lqiGridObj != null && lqiGridObj.getErrorCategories() != null
&& lqiGridObj.getErrorCategories().size() > 1 && row > 0) {
LQIErrorCategory catToMove = lqiGridObj.getErrorCategories().get(
row);
lqiGridObj.getErrorCategories().set(row,
lqiGridObj.getErrorCategories().get(row - 1));
lqiGridObj.getErrorCategories().set(row - 1, catToMove);
moved = true;
changed = true;
fireTableRowsUpdated(row - 1, row);
}
return moved;
}
/**
* Moves a row down.
*
* @param row
* the row index.
* @return <code>true</code> if the row has been moved.
*/
public boolean moveRowDown(int row) {
boolean moved = false;
if (lqiGridObj != null && lqiGridObj.getErrorCategories() != null
&& lqiGridObj.getErrorCategories().size() > 1
&& row < lqiGridObj.getErrorCategories().size() - 1) {
LQIErrorCategory catToMove = lqiGridObj.getErrorCategories().get(
row);
lqiGridObj.getErrorCategories().set(row,
lqiGridObj.getErrorCategories().get(row + 1));
lqiGridObj.getErrorCategories().set(row + 1, catToMove);
moved = true;
changed = true;
fireTableRowsUpdated(row, row + 1);
}
return moved;
}
/**
* Gets the comment for a specific category.
*
* @param categoryName
* the category name.
* @return the comment.
*/
public String getCommentByCategory(String categoryName) {
String comment = null;
if (lqiGridObj != null && lqiGridObj.getErrorCategories() != null) {
for (int i = 0; i < lqiGridObj.getErrorCategories().size(); i++) {
if (lqiGridObj.getErrorCategories().get(i).getName()
.equals(categoryName)) {
comment = lqiGridObj.getErrorCategories().get(i)
.getComment();
break;
}
}
}
return comment;
}
/**
* Clears the comment cell for a specific category.
*
* @param category
* the category name.
*/
public void clearCommentForCategory(String category) {
for (int i = 0; i < lqiGridObj.getErrorCategories().size(); i++) {
if (lqiGridObj.getErrorCategories().get(i).getName()
.equals(category)) {
lqiGridObj.getErrorCategories().get(i).setComment("");
fireTableCellUpdated(i,
getColumnIndex(fixedColumns.get(COMMENT_COLUMN)));
break;
}
}
}
/**
* Removes the column related to a specific severity.
*
* @param severity
* the severity.
*/
public void removeSeverityColumn(LQISeverity severity) {
if (lqiGridObj.getSeverities() != null) {
lqiGridObj.getSeverities().remove(severity);
}
for (LQIErrorCategory cat : lqiGridObj.getErrorCategories()) {
cat.removeShortcut(severity.getName());
}
initColumns();
changed = true;
fireTableStructureChanged();
}
/**
* Adds a column for a specific severity.
*
* @param newSeverity
* the severity.
*/
public void addSeverityColumn(LQISeverity newSeverity) {
if (lqiGridObj.getSeverities() == null) {
lqiGridObj.setSeverities(new ArrayList<LQISeverity>());
}
lqiGridObj.getSeverities().add(newSeverity);
Collections.sort(lqiGridObj.getSeverities(),
new LQISeverityComparator());
initColumns();
changed = true;
fireTableStructureChanged();
}
/**
* Sets the name for a severity column.
*
* @param name
* the name
* @param columnIndex
* the column index.
*/
public void setNameForSeverityColumn(String name, int columnIndex) {
LQIGridColumn column = getColumn(columnIndex);
if (lqiGridObj.getSeverities() != null) {
for (LQISeverity sev : lqiGridObj.getSeverities()) {
if (sev.getName().equals(column.getName())) {
sev.setName(name);
break;
}
}
}
if (severityColumns.contains(column)) {
column.setName(name);
}
changed = true;
}
/**
* Gets the severity related to a column with a specific index.
*
* @param colIndex
* the column index
* @return the severity if it exists; <code>null</code> otherwise
*/
public LQISeverity getSeverityByColumn(int colIndex) {
LQISeverity severity = null;
LQIGridColumn column = getColumn(colIndex);
if (severityColumns.contains(column)
&& lqiGridObj.getSeverities() != null) {
for (LQISeverity sev : lqiGridObj.getSeverities()) {
if (sev.getName().equals(column.getName())) {
severity = sev;
break;
}
}
}
return severity;
}
/**
* Sorts severity columns by severity score.
*/
public void sortSeverityColumns() {
Collections.sort(lqiGridObj.getSeverities(),
new LQISeverityComparator());
initColumns();
changed = true;
fireTableStructureChanged();
}
}
/**
* Severity comparator.
*/
class LQISeverityComparator implements Comparator<LQISeverity> {
/*
* (non-Javadoc)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@Override
public int compare(LQISeverity sev1, LQISeverity sev2) {
return Double.compare(sev1.getScore(), sev2.getScore());
}
}