package cn.org.rapid_framework.generator.provider.db.table.model;
import java.util.List;
import cn.org.rapid_framework.generator.GeneratorProperties;
import cn.org.rapid_framework.generator.provider.db.table.TableFactory;
import cn.org.rapid_framework.generator.provider.db.table.model.ForeignKey.ReferenceKey;
import cn.org.rapid_framework.generator.provider.db.table.model.util.ColumnHelper;
import cn.org.rapid_framework.generator.util.GLogger;
import cn.org.rapid_framework.generator.util.StringHelper;
import cn.org.rapid_framework.generator.util.TestDataGenerator;
import cn.org.rapid_framework.generator.util.typemapping.ActionScriptDataTypesUtils;
import cn.org.rapid_framework.generator.util.typemapping.DatabaseDataTypesUtils;
import cn.org.rapid_framework.generator.util.typemapping.JavaPrimitiveTypeMapping;
import cn.org.rapid_framework.generator.util.typemapping.JdbcType;
/**
* 用于生成代码的Columb对象.对应数据库表column
* @author badqiu
* @email badqiu(a)gmail.com
*/
public class Column {
/**
* Reference to the containing table
*/
private Table _table;
/**
* The java.sql.Types type
*/
private int _sqlType;
/**
* The sql typename. provided by JDBC driver
*/
private String _sqlTypeName;
/**
* The name of the column
*/
private String _sqlName;
/**
* True if the column is a primary key
*/
private boolean _isPk;
/**
* True if the column is a foreign key
*/
private boolean _isFk;
/**
* @todo-javadoc Describe the column
*/
private int _size;
/**
* @todo-javadoc Describe the column
*/
private int _decimalDigits;
/**
* True if the column is nullable
*/
private boolean _isNullable;
/**
* True if the column is indexed
*/
private boolean _isIndexed;
/**
* True if the column is unique
*/
private boolean _isUnique;
/**
* Null if the DB reports no default value
*/
private String _defaultValue;
/**
* The comments of column
*/
private String _remarks;
/**
* @param table
* @param sqlType
* @param sqlTypeName
* @param sqlName
* @param size
* @param decimalDigits
* @param isPk
* @param isNullable
* @param isIndexed
* @param isUnique
* @param defaultValue
* @param remarks
*/
public Column(Table table, int sqlType, String sqlTypeName,
String sqlName, int size, int decimalDigits, boolean isPk,
boolean isNullable, boolean isIndexed, boolean isUnique,
String defaultValue,String remarks) {
_table = table;
_sqlType = sqlType;
_sqlName = sqlName;
_sqlTypeName = sqlTypeName;
_size = size;
_decimalDigits = decimalDigits;
_isPk = isPk;
_isNullable = isNullable;
_isIndexed = isIndexed;
_isUnique = isUnique;
_defaultValue = defaultValue;
_remarks = remarks;
GLogger.trace(sqlName + " isPk -> " + _isPk);
initOtherProperties();
}
public Column(Column c) {
this(c.getTable(),
c.getSqlType(),
c.getSqlTypeName(),
c.getColumnName(),
c.getSize(),
c.getDecimalDigits(),
c.isPk(),
c.isNullable(),
c.isIndexed(),
c.isUnique(),
c.getDefaultValue(),
c.getRemarks());
}
public Column() {
}
/**
* Gets the SqlType attribute of the Column object
*
* @return The SqlType value
*/
public int getSqlType() {
return _sqlType;
}
/**
* Gets the Table attribute of the DbColumn object
*
* @return The Table value
*/
public Table getTable() {
return _table;
}
public String getMybatisFlagBegin(){
return "#{";
}
public String getMybatisFlagEnd(){
return "}";
}
/**
* Gets the Size attribute of the DbColumn object
*
* @return The Size value
*/
public int getSize() {
return _size;
}
/**
* Gets the DecimalDigits attribute of the DbColumn object
*
* @return The DecimalDigits value
*/
public int getDecimalDigits() {
return _decimalDigits;
}
/**
* Gets the SqlTypeName attribute of the Column object
*
* @return The SqlTypeName value
*/
public String getSqlTypeName() {
return _sqlTypeName;
}
public String getJdbcTypeName(){
if(_sqlTypeName.equals("NUMBER") || _sqlTypeName.equals("INTEGER")){
return "NUMERIC";
}else if(_sqlTypeName.equals("VARCHAR2")){
return "VARCHAR";
}else if(_sqlTypeName.equals("TIMESTAMP(6)")){
return "TIMESTAMP";
}else{
return _sqlTypeName;
}
}
/**
* Gets the SqlName attribute of the Column object
*
* @return The SqlName value
*/
public String getSqlName() {
return _sqlName;
}
public String getSqlNameLower(){
return _sqlName.toLowerCase();
}
/**
* Gets the Pk attribute of the Column object
*
* @return The Pk value
*/
public boolean isPk() {
return _isPk;
}
/**
* Gets the Fk attribute of the Column object
*
* @return The Fk value
*/
public boolean isFk() {
return _isFk;
}
/**
* Gets the Nullable attribute of the Column object
*
* @return The Nullable value
*/
public boolean isNullable() {
return _isNullable;
}
/**
* Gets the Indexed attribute of the DbColumn object
*
* @return The Indexed value
*/
public boolean isIndexed() {
return _isIndexed;
}
/**
* Gets the Unique attribute of the DbColumn object
*
* @return The Unique value
*/
public boolean isUnique() {
return _isUnique;
}
/**
* Gets the DefaultValue attribute of the DbColumn object
*
* @return The DefaultValue value
*/
public String getDefaultValue() {
return _defaultValue;
}
/**
* 列的数据库备注
* @return
*/
public String getRemarks() {
return _remarks;
}
public void setUpdatable(boolean updatable) {
this.updatable = updatable;
}
public void setInsertable(boolean insertable) {
this.insertable = insertable;
}
public void setNullable(boolean v) {
this._isNullable = v;
}
public void setForQuery(boolean forQuery) {
this.forQuery = forQuery;
}
public void setForList(boolean forList) {
this.forList = forList;
}
public void setUnique(boolean unique) {
_isUnique = unique;
}
public void setPk(boolean v) {
this._isPk = v;
}
/**
* Describe what the method does
*
* @return Describe the return value
* @todo-javadoc Write javadocs for method
* @todo-javadoc Write javadocs for return value
*/
public int hashCode() {
if(getTable() != null) {
return (getTable().getSqlName() + "#" + getSqlName()).hashCode();
}else {
return (getSqlName()).hashCode();
}
}
/**
* Describe what the method does
*
* @param o
* Describe what the parameter does
* @return Describe the return value
* @todo-javadoc Write javadocs for method
* @todo-javadoc Write javadocs for method parameter
* @todo-javadoc Write javadocs for return value
*/
public boolean equals(Object o) {
if(this == o) return true;
if(o instanceof Column) {
Column other = (Column)o;
if(getSqlName().equals(other.getSqlName())) {
return true;
}
}
return false;
}
/**
* Describe what the method does
*
* @return Describe the return value
* @todo-javadoc Write javadocs for method
* @todo-javadoc Write javadocs for return value
*/
public String toString() {
return getSqlName();
}
/**
* Describe what the method does
*
* @return Describe the return value
* @todo-javadoc Write javadocs for method
* @todo-javadoc Write javadocs for return value
*/
protected String prefsPrefix() {
return "tables/" + getTable().getSqlName() + "/columns/" + getSqlName();
}
/**
* Sets the Pk attribute of the DbColumn object
*
* @param flag
* The new Pk value
*/
void setFk(boolean flag) {
_isFk = flag;
}
public String getUnderscoreName() {
return getSqlName().toLowerCase();
}
/**
* 根据列名,根据sqlName计算得出,示例值: BirthDate
**/
public String getColumnName() {
if(columnName.equalsIgnoreCase("RowId")){
return "Row_Id";
}else
return columnName;
}
/**
* 第一个字母小写的columName,等价于: StringHelper.uncapitalize(getColumnName()),示例值: birthDate
**/
public String getColumnNameFirstLower() {
if(getColumnName().equalsIgnoreCase("ROW_ID") || getColumnName().equalsIgnoreCase("ROWID")){
return "row_Id";
}else
return StringHelper.uncapitalize(getColumnName());
}
/**
* 全部小写的columName,等价于: getColumnName().toLowerCase(),示例值: birthdate
**/
public String getColumnNameLowerCase() {
return getColumnName().toLowerCase();
}
/**
* 使用 getColumnNameFirstLower()替换
* @deprecated use getColumnNameFirstLower() instead
*/
public String getColumnNameLower() {
return getColumnNameFirstLower();
}
/**
* 使用 jdbcSqlType类型名称,示例值:VARCHAR,DECIMAL, 现Ibatis3使用该属性
*/
public String getJdbcSqlTypeName() {
String result = JdbcType.getJdbcSqlTypeName(getSqlType());
//if(result == null) throw new RuntimeException("jdbcSqlTypeName is null column:"+getSqlName()+" sqlType:"+getSqlType());
return result;
}
/**
* 列的别名,等价于:getRemarks().isEmpty() ? getColumnNameFirstLower() : getRemarks()
*
* <br />
* 示例值: birthDate
*/
public String getColumnAlias() {
return columnAlias;
}
/**
* 列的常量名称
*
* <br />
* 示例值: BIRTH_DATE
*/
public String getConstantName() {
return StringHelper.toUnderscoreName(getColumnName()).toUpperCase();
}
/**
*
* @deprecated
*/
public boolean getIsNotIdOrVersionField() {
return !isPk();
}
/**得到 rapid-validation的验证表达式: required min-value-800 */
public String getValidateString() {
return isNullable() ? getNoRequiredValidateString() : "required " + getNoRequiredValidateString();
}
/**得到 rapid-validation的验证表达式: min-value-800 */
public String getNoRequiredValidateString() {
return ColumnHelper.getRapidValidation(this);
}
/** 得到JSR303 bean validation(Hibernate Validator)的验证表达式: @NotNull @Min(100) @Max(800) */
public String[] getHibernateValidatorConstraintNames() {
return ColumnHelper.removeHibernateValidatorSpecialTags(getHibernateValidatorExprssion());
}
/** 得到JSR303 bean validation(Hibernate Validator)的验证表达式: @NotNull @Min(100) @Max(800) */
public String getHibernateValidatorExprssion() {
return hibernateValidatorExprssion;
}
public void setHibernateValidatorExprssion(String v) {
hibernateValidatorExprssion = v;
}
/** 列是否是String类型 */
public boolean getIsStringColumn() {
return DatabaseDataTypesUtils.isString(getJavaType());
}
/** 列是否是日期类型 */
public boolean getIsDateTimeColumn() {
return DatabaseDataTypesUtils.isDate(getJavaType());
}
/** 列是否是Number类型 */
public boolean getIsNumberColumn() {
return DatabaseDataTypesUtils.isFloatNumber(getJavaType())
|| DatabaseDataTypesUtils.isIntegerNumber(getJavaType());
}
/** 检查是否包含某些关键字,关键字以逗号分隔 */
public boolean contains(String keywords) {
if(keywords == null) throw new IllegalArgumentException("'keywords' must be not null");
return StringHelper.contains(getSqlName(), keywords.split(","));
}
public boolean isHtmlHidden() {
return isPk() && _table.isSingleId();
}
/**
* 得到对应的javaType,如java.lang.String,
* @return
*/
public String getJavaType() {
return javaType;
}
/**
* 得到简短的java.lang.javaType,如java.lang.String将返回String,而非java.lang包的,将直接返回getJavaType()
* @return
*/
public String getSimpleJavaType() {
return StringHelper.removePrefix(getJavaType(), "java.lang.");
}
/**
* 得到原生类型的javaType,如java.lang.Integer将返回int,而非原生类型,将直接返回getSimpleJavaType()
* @return
*/
public String getPrimitiveJavaType() {
return JavaPrimitiveTypeMapping.getPrimitiveType(getSimpleJavaType());
}
/** 得到ActionScript的映射类型,用于Flex代码的生成 */
public String getAsType() {
return asType;
}
/** 得到列的测试数据 */
public String getTestData() {
return new TestDataGenerator().getDBUnitTestData(getColumnName(),getJavaType(),getSize());
}
/** 列是否可以更新 */
public boolean isUpdatable() {
return updatable;
}
/** 列是否可以插入 */
public boolean isInsertable() {
return insertable;
}
/** 列是否可以查询 */
public boolean isForQuery() {
return forQuery;
}
/** 列是否可以显示 */
public boolean isForList() {
return forList;
}
/** 得到枚举(enum)的类名称,示例值:SexEnum */
public String getEnumClassName() {
return enumClassName;
}
/** 枚举值,以分号分隔,示例值:M(1,男);F(0,女) 或者是:M(男);F(女) */
public void setEnumString(String str) {
this.enumString = str;
}
/** 枚举值,以分号分隔,示例值:M(1,男);F(0,女) 或者是:M(男);F(女) */
public String getEnumString() {
return enumString;
}
/** 解析getEnumString()字符串转换为List<EnumMetaDada>对象 */
public List<EnumMetaDada> getEnumList() {
return StringHelper.string2EnumMetaData(getEnumString());
}
/** 是否是枚举列,等价于:return getEnumList() != null && !getEnumList().isEmpty() */
public boolean isEnumColumn() {
return getEnumList() != null && !getEnumList().isEmpty();
}
public void setJavaType(String javaType) {
this.javaType = javaType;
}
public void setColumnAlias(String columnAlias) {
this.columnAlias = columnAlias;
}
public void setColumnName(String columnName) {
this.columnName = columnName;
}
public void setAsType(String asType) {
this.asType = asType;
}
public void setEnumClassName(String enumClassName) {
this.enumClassName = enumClassName;
}
// public void setBelongsTo(String foreignKey) {
// ReferenceKey ref = ReferenceKey.fromString(foreignKey);
// if(ref != null && _table != null) {
// _table.getImportedKeys().addForeignKey(ref.tableName, ref.columnSqlName, getSqlName(), ref.columnSqlName.hashCode());
// }
// }
//
// public void setHasAndBelongsToMany(String foreignKey) {
// }
private ReferenceKey hasOne;
public String getHasOne() {
return ReferenceKey.toString(hasOne);
}
/**
* 设置many-to-one,foreignKey格式: fk_table_name(fk_column) 或者 schema_name.fk_table_name(fk_column)
* @param foreignKey
* @return
*/
public void setHasOne(String foreignKey) {
hasOne = ReferenceKey.fromString(foreignKey);
if(hasOne != null && _table != null) {
// Table refTable = TableFactory.getInstance().getTable(hasOne.tableName);
// _table.getImportedKeys().addForeignKey(refTable.getSqlName(), hasOne.columnSqlName, getSqlName(), hasOne.columnSqlName.toLowerCase().hashCode());
_table.getImportedKeys().addForeignKey(hasOne.tableName, hasOne.columnSqlName, getSqlName(), hasOne.columnSqlName.toLowerCase().hashCode());
}
}
private ReferenceKey hasMany = null;
public String getHasMany() {
return ReferenceKey.toString(hasMany);
}
/**
* 设置one-to-many,foreignKey格式: fk_table_name(fk_column) 或者 schema_name.fk_table_name(fk_column)
* @param foreignKey
* @return
*/
public void setHasMany(String foreignKey) {
hasMany = ReferenceKey.fromString(foreignKey);
if(hasMany != null && _table != null) {
// Table refTable = TableFactory.getInstance().getTable(hasMany.tableName);
// _table.getExportedKeys().addForeignKey(refTable.getSqlName(), hasMany.columnSqlName, getSqlName(), hasMany.columnSqlName.toLowerCase().hashCode());
_table.getExportedKeys().addForeignKey(hasMany.tableName, hasMany.columnSqlName, getSqlName(), hasMany.columnSqlName.toLowerCase().hashCode());
}
}
private void initOtherProperties() {
String normalJdbcJavaType = DatabaseDataTypesUtils.getPreferredJavaType(getSqlType(), getSize(), getDecimalDigits());
javaType = GeneratorProperties.getProperty("java_typemapping."+normalJdbcJavaType,normalJdbcJavaType).trim();
columnName = StringHelper.makeAllWordFirstLetterUpperCase(StringHelper.toUnderscoreName(getSqlName()));
enumClassName = getColumnName()+"Enum";
asType = ActionScriptDataTypesUtils.getPreferredAsType(getJavaType());
columnAlias = StringHelper.defaultIfEmpty(getRemarks(), getColumnNameFirstLower());
columnAlias = StringHelper.removeCrlf(columnAlias);
setHibernateValidatorExprssion(ColumnHelper.getHibernateValidatorExpression(this));
}
private String enumString = "";
private String javaType;
private String columnAlias;
private String columnName;
private String asType;
private String enumClassName;
private boolean updatable = true;
private boolean insertable = true;
private boolean forQuery = true;
private boolean forList = true;
private String hibernateValidatorExprssion;
// private String rapidValidation;
/**
* public enum ${enumClassName} {
* ${enumAlias}(${enumKey},${enumDesc});
* private String key;
* private String value;
* }
* @author badqiu
*/
public static class EnumMetaDada {
private String enumAlias;
private String enumKey;
private String enumDesc;
public EnumMetaDada(String enumAlias, String enumKey, String enumDesc) {
super();
this.enumAlias = enumAlias;
this.enumKey = enumKey;
this.enumDesc = enumDesc;
}
public String getEnumAlias() {
return enumAlias;
}
public String getEnumKey() {
return enumKey;
}
public String getEnumDesc() {
return enumDesc;
}
}
}