package xgenerator.ui.swing.model;
import java.util.List;
import java.util.Vector;
import javax.swing.JComboBox;
import javax.swing.table.DefaultTableModel;
import xgenerator.model.FieldMetadata;
import xgenerator.model.ModelMetadata;
import xgenerator.service.MetadataService;
import xgenerator.service.impl.MetadataServiceImpl;
/**
* <p>
* Title:MetadataTableModel
* </p>
* <p>
* Description:
* </p>
* <p>
* Copyright: Copyright (c) 2012
* </p>
* <p>
* Company: liss
* </p>
* @author <a href="mailto:shushanlee@msn.com">liss</a>
* @version 1.0
* @see
* @since 1.0
*/
public class MetadataTableModel extends DefaultTableModel {
/**
* Serializable
*/
private static final long serialVersionUID = 1L;
/**
* 列名列索引=0
*/
public static final int COLUMN_NAME_INDEX = 0;
/**
* 属性名列索引=1
*/
public static final int PROPERTY_NAME_INDEX = 1;
/**
* 显示名称列索引=2
*/
public static final int DISPLAY_NAME_INDEX = 2;
/**
* 注释列索引=3
*/
public static final int COMMENTS_INDEX = 3;
/**
* 数据类型列索引=4
*/
public static final int SQL_DATA_TYPE_INDEX = 4;
/**
* 列长度列索引=5
*/
public static final int DATA_LENGTH_INDEX = 5;
/**
* 精度列索引=6
*/
public static final int DATA_PRECISION_INDEX = 6;
/**
* 刻度——小数点后位数,列索引=7
*/
public static final int DATA_SCALE_INDEX = 7;
/**
* 属性类型列索引=8
*/
public static final int PROPERTY_TYPE_INDEX = 8;
/**
* 可否为空列索引=9
*/
public static final int NULLABLE_INDEX = 9;
/**
* 默认值列索引=10
*/
public static final int DATA_DEFAULT_INDEX = 10;
/**
* 是否为键列索引=11
*/
public static final int IS_KEY_FIELD_INDEX = 11;
/**
* 约束类型列索引=12
*/
public static final int CONSTRAINT_TYPE_INDEX = 12;
/**
* 参照表列索引=13
*/
public static final int REFERENCING_TABLE_INDEX = 13;
/**
* 参照列列索引=14
*/
public static final int REFERENCING_COLUMN_INDEX = 14;
/**
* 删除规则索引=15
*/
public static final int DELETE_RULE_INDEX = 15;
/**
* 是否作为查询字段=16
*/
public static final int IS_QUERY_FIELD_INDEX = 16;
/**
* 查询模式=17
*/
public static final int QUERY_MODE_INDEX = 17;
/**
* 组件类型=18
*/
public static final int COMPONENT_TYPE_INDEX = 18;
/**
* 表列头
*/
public static final Object[] COLUMN_NAMES = {"列名", "属性名", "显示名", "注释", "SQL数据类型", "长度", "精度", "刻度", "属性类型", "可为空", "默认值", "键", "约束类型", "参照表", "参照列", "参照完整性约束", "可查询", "查询类型", "组件类型" };
/**
* 列数据类型
*/
public static final Class[] COLUMN_CLASS = { String.class, // 列名
String.class, // 属性名
String.class, // 中文名称
String.class, // 注释
JComboBox.class, // 数据类型
Integer.class, // 长度
Integer.class, // 精度
Integer.class, // 刻度
JComboBox.class, // 属性类型
Boolean.class, // 可为空
String.class, // 默认值/表达式
Boolean.class, // 键
JComboBox.class, // 约束类型
JComboBox.class, // 参照表
JComboBox.class, // 参照列
JComboBox.class, // 参照完整性约束
Boolean.class, // 查询设置
JComboBox.class, // 查询类型
JComboBox.class // 组件类型
};
/**
* service
*/
private MetadataService metadataService;
/**
* 单元格可否编辑矩阵
*/
private Vector<Vector<Boolean>> cellEditableVector;
/**
* 新建数据模型,并初始化数据
* @param datasourceName
* @param tableName
*/
public MetadataTableModel(String datasourceName, String tableName) {
this.metadataService = new MetadataServiceImpl();
this.updateDataVector(datasourceName, tableName);
}
/**
* 新建数据模型,并用空行初始化
*/
public MetadataTableModel() {
this(null, null);
}
/**
* <p>
* Title:cellEditableVector getter
* </p>
* @author <a href="mailto:shushanlee@msn.com">liss</a>
* @return
*/
public Vector<Vector<Boolean>> getCellEditableVector() {
return this.cellEditableVector;
}
/**
* <p>
* Title:cellEditableVector setter
* </p>
* @author <a href="mailto:shushanlee@msn.com">liss</a>
* @param cellEditableVector
*/
public void setCellEditableVector(Vector<Vector<Boolean>> cellEditableVector) {
this.cellEditableVector = cellEditableVector;
}
/**
* <p>
* Title:设置指定单元格可否编辑
* </p>
* @author <a href="mailto:shushanlee@msn.com">liss</a>
* @param editable
* @param row
* @param column
*/
public void setCellEditableAt(boolean editable, int row, int column) {
// this.editableVector.get(row).setElementAt(editable, column);
Vector rowVector = (Vector)this.cellEditableVector.elementAt(row);
rowVector.setElementAt(editable, column);
fireTableCellUpdated(row, column);
}
/**
* <p>
* Title:构造一行的所有单元格可否编辑Vector
* </p>
* @author <a href="mailto:shushanlee@msn.com">liss</a>
* @return
*/
private Vector<Boolean> mapRowEditableVector(FieldMetadata fieldMetadata) {
int columnCount = COLUMN_NAMES.length;
Vector<Boolean> oneRowCellEditable = new Vector<Boolean>(columnCount);
for(int j=0; j<columnCount; j++) {
if(j == CONSTRAINT_TYPE_INDEX) {
if(fieldMetadata.isKeyField()) {
oneRowCellEditable.add(new Boolean(true));
} else {
oneRowCellEditable.add(new Boolean(false));
}
} else if(j == REFERENCING_TABLE_INDEX || j == REFERENCING_COLUMN_INDEX || j == DELETE_RULE_INDEX) {
if(fieldMetadata.isKeyField() && ConstraintTypeComboBoxModel.FK_TYPE.equals(fieldMetadata.getConstraintType())) {
oneRowCellEditable.add(new Boolean(true));
} else {
oneRowCellEditable.add(new Boolean(false));
}
} else if(j == QUERY_MODE_INDEX) {
if(fieldMetadata.isQueryField()) {
oneRowCellEditable.add(new Boolean(true));
} else {
oneRowCellEditable.add(new Boolean(false));
}
} else {
oneRowCellEditable.add(new Boolean(true));
}
}
return oneRowCellEditable;
}
/**
* <p>
* Title:构造表格单元格可否编辑矩阵
* </p>
* @author <a href="mailto:shushanlee@msn.com">liss</a>
* @param rowCount
*/
private Vector<Vector<Boolean>> mapCellEditableVector(List<FieldMetadata> fieldMetadatas) {
int rowCount = fieldMetadatas.size();
Vector<Vector<Boolean>> tableCellEditableMatrix = new Vector<Vector<Boolean>>(rowCount);
for(int i=0; i<rowCount; i++) {
tableCellEditableMatrix.add(mapRowEditableVector(fieldMetadatas.get(i)));
}
return tableCellEditableMatrix;
}
/**
* <p>
* Title:添加TableModel行时,同时添加单元格可否编辑的矩阵的一行
* </p>
* @author <a href="mailto:shushanlee@msn.com">liss</a>
* @param rowIndex
*/
private void insertRowEditable(int rowIndex) {
FieldMetadata fieldMetadata = buildNewRowData();
this.cellEditableVector.insertElementAt(mapRowEditableVector(fieldMetadata), rowIndex);
}
/**
* <p>
* Title:删除TableModel行时,同时删除单元格可否编辑的矩阵的一行
* </p>
* @author <a href="mailto:shushanlee@msn.com">liss</a>
* @param rowIndex
*/
private void removeRowEditable(int rowIndex) {
this.cellEditableVector.remove(rowIndex);
}
/**
* <p>
* Title:构造一个数据TableColumnMetadataBean
* </p>
* @author <a href="mailto:shushanlee@msn.com">liss</a>
* @return
*/
private FieldMetadata buildNewRowData() {
FieldMetadata fieldMetadata = new FieldMetadata();
fieldMetadata.setNullable(true);
fieldMetadata.setKeyField(false);
return fieldMetadata;
}
/**
* <p>
* Title:插入新行
* </p>
* @author <a href="mailto:shushanlee@msn.com">liss</a>
* @param rowIndex
*/
public void insertNewRow(int rowIndex) {
Object[] rowData = this.mapRowData(this.buildNewRowData());
this.insertRow(rowIndex, rowData);
this.insertRowEditable(rowIndex);
}
/**
* <p>
* Title:重写删除行方法,删除一行,并删除对应的行单元格可否编辑状态
* </p>
* @param row
* @see javax.swing.table.DefaultTableModel#removeRow(int)
*/
@Override
public void removeRow(int row) {
super.removeRow(row);
this.removeRowEditable(row);
}
/**
* <p>
* Title:将TableColumnMetadataBean映射为一个数据表格行
* </p>
* @author <a href="mailto:shushanlee@msn.com">liss</a>
* @param oneFieldMetadata
* @return
*/
private Object[] mapRowData(FieldMetadata oneFieldMetadata) {
int columnCount = MetadataTableModel.COLUMN_NAMES.length;
Object[] oneRowData = new Object[columnCount];
oneRowData[COLUMN_NAME_INDEX] = oneFieldMetadata.getColumnName();
oneRowData[PROPERTY_NAME_INDEX] = oneFieldMetadata.getPropertyName();
oneRowData[DISPLAY_NAME_INDEX] = oneFieldMetadata.getDisplayName();
oneRowData[COMMENTS_INDEX] = oneFieldMetadata.getComments();
oneRowData[SQL_DATA_TYPE_INDEX] = oneFieldMetadata.getSqlDataType();
oneRowData[DATA_LENGTH_INDEX] = oneFieldMetadata.getDataLength();
oneRowData[DATA_PRECISION_INDEX] = oneFieldMetadata.getDataPrecision();
oneRowData[DATA_SCALE_INDEX] = oneFieldMetadata.getDataScale();
oneRowData[PROPERTY_TYPE_INDEX] = oneFieldMetadata.getPropertyType();
oneRowData[NULLABLE_INDEX] = oneFieldMetadata.isNullable();
oneRowData[DATA_DEFAULT_INDEX] = oneFieldMetadata.getDataDefault();
oneRowData[IS_KEY_FIELD_INDEX] = oneFieldMetadata.isKeyField();
oneRowData[CONSTRAINT_TYPE_INDEX] = oneFieldMetadata.getConstraintType();
oneRowData[REFERENCING_TABLE_INDEX] = oneFieldMetadata.getReferencingTable();
oneRowData[REFERENCING_COLUMN_INDEX] = oneFieldMetadata.getReferencingColumn();
oneRowData[DELETE_RULE_INDEX] = oneFieldMetadata.getDeleteRule();
return oneRowData;
}
/**
* <p>
* Title:构造TableModel的DataVector
* </p>
* @author <a href="mailto:shushanlee@msn.com">liss</a>
* @param fieldMetadatas
* @return
*/
private Object[][] mapDataVector(List<FieldMetadata> fieldMetadatas) {
int rowCount = fieldMetadatas.size();
int columnCount = COLUMN_NAMES.length;
Object[][] rowDataArray = new Object[rowCount][columnCount];
for (int i = 0; i < rowDataArray.length; i++) {
rowDataArray[i] = mapRowData(fieldMetadatas.get(i));
}
return rowDataArray;
}
/**
* <p>
* Title:更新TableModel的DataVector数据
* </p>
* @author <a href="mailto:shushanlee@msn.com">liss</a>
* @param datasourceName
* @param tableName
*/
public ModelMetadata updateDataVector(String datasourceName, String tableName) {
ModelMetadata modelMetadata = this.metadataService.getModelMetadata(datasourceName, tableName);
List<FieldMetadata> fieldMetadatas = modelMetadata.getFieldMetadatas();
/*
* editableVector的初始化一定要在setDataVector之前
*/
this.setCellEditableVector(mapCellEditableVector(fieldMetadatas));
this.setDataVector(mapDataVector(fieldMetadatas), COLUMN_NAMES);
return modelMetadata;
}
/**
* <p>
* Title:使表格能识别不同的数据类型
* </p>
* @author <a href="mailto:shushanlee@msn.com">liss</a>
* @param columnIndex
* @return
* @see javax.swing.table.AbstractTableModel#getColumnClass(int)
*/
@Override
public Class getColumnClass(int columnIndex) {
// Object cellObj = getValueAt(0, columnIndex);
// if(null != cellObj) {
// return cellObj.getClass();
// } else {
// return super.getColumnClass(columnIndex);
// }
return COLUMN_CLASS[columnIndex];
}
/**
* <p>
* Title:
* </p>
* @author <a href="mailto:shushanlee@msn.com">liss</a>
* @param row
* @param column
* @return
* @see javax.swing.table.DefaultTableModel#isCellEditable(int, int)
*/
@Override
public boolean isCellEditable(int row, int column) {
// return super.isCellEditable(row, column);
// return this.editableVector.get(row).get(column);
Vector<Boolean> rowVector = (Vector<Boolean>) this.cellEditableVector.elementAt(row);
return rowVector.elementAt(column);
}
}