All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gu.sql2java.generator.Column Maven / Gradle / Ivy

There is a newer version: 4.4.0
Show newest version
package gu.sql2java.generator;

import java.nio.ByteBuffer;
import java.sql.DatabaseMetaData;
import java.sql.Types;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
import gu.sql2java.excel.annotations.ExcelColumn;
import static net.gdface.utils.MiscellaneousUtils.elementsOf;
import static com.google.common.base.MoreObjects.firstNonNull;

public class Column implements Cloneable, Comparable,MappedType {
	private String catalog;
	private String schema;
	private String tableName;
	private String name;
	private SqlComment remarks;
	private String defaultValue;
	private int size;
	private int decDigits;
	private int radix;
	private int nullable;
	private int ordinal;
	private short type;
	private boolean isPrimaryKey;
	private String strCheckingType = "";
	private String autoincrement;
	private Database db;
	private List foreignKeys = new Vector();
	private List importedKeys = new Vector();
	private String typeName = "";
	private volatile String invalidValueAnn;
	private volatile Boolean preAlloc;
	private static Random rand = new Random();
	private static boolean jsonJacksonRawValue;
	private static boolean byteBufferAsString;
	private static boolean jacksonBeanSupport;
	private static String geometrySerialType;
	@Override
	public String toString() {
		return new ToStringBuilder(this)
				.append("catalog",catalog)
				.append("schema",schema)
				.append("tableName",tableName)
				.append("name",name)
				.append("remarks",remarks)
				.append("defaultValue",defaultValue)
				.append("size",size)
				.append("decDigits",decDigits)
				.append("radix",radix)
				.append("nullable",nullable)
				.append("ordinal",ordinal)
				.append("type",type)
				.append("isPrimaryKey",isPrimaryKey)
				.append("autoincrement",autoincrement)
				.append("typeName",typeName)
				.toString();
	}

	@Override
	public boolean equals(Object obj) {
		if(super.equals(obj))return true;
		if(!(obj instanceof Column))return false;
		Column other = (Column)obj;
		return new EqualsBuilder()
				.append(catalog,other.catalog)
				.append(schema,other.schema)
				.append(tableName,other.tableName)
				.append(name,other.name)
				.append(remarks,other.remarks)
				.append(defaultValue,other.defaultValue)
				.append(size,other.size)
				.append(decDigits,other.decDigits)
				.append(radix,other.radix)
				.append(nullable,other.nullable)
				.append(ordinal,other.ordinal)
				.append(type,other.type)
				.append(isPrimaryKey,other.isPrimaryKey)
				.append(autoincrement,other.autoincrement)
				.append(typeName,other.typeName)
				.isEquals();
	}

	public void setCheckingType(String strValue) {
		this.strCheckingType = strValue;
	}

	public String getCheckingType() {
		return this.strCheckingType;
	}

	public void setDatabase(Database db) {
		this.db = db;
	}

	public void setCatalog(String catalog) {
		this.catalog = catalog;
	}

	public void setSchema(String schema) {
		this.schema = schema;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public void setName(String name) {
		this.name = null == name ? "" : name.replaceAll("\\W", "");
	}

	public void setType(short type) {
		this.type = type;
	}

	public void setSize(int size) {
		this.size = size;
	}

	public void setDecimalDigits(int decDigits) {
		this.decDigits = decDigits;
	}

	public void setRadix(int radix) {
		this.radix = radix;
	}

	public void setNullable(int nullable) {
		this.nullable = nullable;
	}

	public void setRemarks(String remarks) {
		this.remarks = new SqlComment(remarks);
	}

	public void setDefaultValue(String defaultValue) {
		this.defaultValue = defaultValue;
	}

	public void setOrdinalPosition(int ordinal) {
		this.ordinal = ordinal;
	}

	public void isPrimaryKey(boolean isKey) {
		this.isPrimaryKey = isKey;
	}

	public String getCatalog() {
		return this.catalog;
	}

	public String getSchema() {
		return this.schema;
	}

	public String getTableName() {
		return this.tableName;
	}

	public String getName() {
		return this.name;
	}

	public short getType() {
		return this.type;
	}

	public int getSize() {
		return this.size;
	}

	public int getDecimalDigits() {
		return this.decDigits;
	}

	public int getRadix() {
		return this.radix;
	}

	public int getNullable() {
		return this.nullable;
	}

	public String getNullableAsString() {
		return this.getNullable() != 0 ? "nullable" : "null not allowed";
	}

	public int getOrdinalPosition() {
		return this.ordinal;
	}

	public boolean isPrimaryKey() {
		return this.isPrimaryKey;
	}

	public String getFullName() {
		return this.tableName + "." + this.getName();
	}

	public String getConstName() {
		return this.getName().toUpperCase();
	}

	public String getIDConstName() {
		return (this.tableName + "_ID_" + this.getName()).toUpperCase();
	}
	public String getIDMaskConstName() {
		return (this.tableName + "_ID_" + this.getName()).toUpperCase() + "_MASK";
	}
	public String getNameConstName() {
	    return (this.tableName + "_COLUMN_" + this.getName()).toUpperCase();
	}
	/**
	 * @see gu.sql2java.generator.SqlComment#getDescName()
	 */
	public String getDescName(){
		return remarks.getDescName();
	}

	/**
	 * @see gu.sql2java.generator.SqlComment#getNamesTagMap()
	 */
	public Map getNamesTagMap() {
		return remarks.getNamesTagMap();
	}

    public String getExcelColumn(){
		return remarks.getExcelAnnotation(ExcelColumn.class, 
				buffer->{buffer.append("sort=").append(ordinal);return 1;});
	}
	
	/**
	 * 返回当前字段是否被定义为JSON字段
	 */
	public boolean isJsonField(){
		return isString() && remarks.hasJsonTag();
	}
	/**
	 * 如果字段注释中定义了字段类型返回{@code true},否则返回{@code false}
	 * @since 3.21.0
	 */
	public boolean isDefinedFieldType() {
		return !Strings.isNullOrEmpty(remarks.getFieldType());
	}
	/**
	 * 如果字段被定义为M_BOOLEAN类型则返回 {@code true}, 
	 * 否则返回{@code false}
	 */
	private boolean isBoolean() {
		return M_BOOLEAN == getMappedType();
	}
	/**
	 * 返回当前字段是否为空间数据类型(Spatial Data)
	 * @since 3.18.0
	 */
	public boolean isGeometry() {
	    return null != getGeometryType(); 
	}
	public boolean isJsonJacksonRawValue(){
		return jacksonBeanSupport && jsonJacksonRawValue && isJsonField();
	}
	public boolean isByteBufferAsString(){
		return byteBufferAsString && ByteBuffer.class.equals(getJavaClass());
	}
	/**
	 * 如果字段注释中有JSON tag,则解析JSON tag,返回JSON的类型定义(fastjson) 
	 * 如果不是JSON字段则返回{@code null}
	 * @see SqlComment#getJsonType()
	 */
	private String getJsonType(){
		if(isJsonField()){
			return remarks.getJsonType();
		}
		return null;
	}
	/**
	 * 如果字段注释中有ANNOT tag,则解析ANNOT tag,返回ANNOT的注解定义列表
	 * 如果不是ANNOT字段则返回空
	 * @since 3.21.0
	 */
	public List getAnnotations(){
		return remarks.getAnnotations();
	}
	/**
	 * 如果字段为空间数据类型(Spatial Data)则返回对应的JTS Java类否则 返回{@code null}
	 * @since 3.18.0
	 */
	public Class getGeometryType(){
        return SPATIAL_TARGET_TYPES.get(this.getTypeName().toUpperCase());
	}
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

	private void tuoe() {
		throw new UnsupportedOperationException("Not supported yet: " + this.getTableName() + "." + this.getName() + " "
				+ this.getJavaTypeAsTypeName());
	}

	private void tiae() {
		throw new IllegalArgumentException("No primary type associated: " + this.getTableName() + "." + this.getName());
	}

	public int getMappedType() {
		switch (this.getType()) {
			case Types.ARRAY : {
				return M_ARRAY;
			}
			case Types.BIGINT : {
				return M_LONG;
			}
			case Types.BINARY : {
				return M_BYTES;
			}
			case Types.BIT : {
				return M_BOOLEAN;
			}
			case Types.BLOB : {
				return M_BLOB;
			}
			case Types.BOOLEAN : {
				return M_BOOLEAN;
			}
			case Types.CHAR : {
				return M_STRING;
			}
			case Types.CLOB : {
				return M_CLOB;
			}
			case Types.DATALINK : {
				return M_URL;
			}
			case Types.DATE : {
				if ("java.util.Date".equals(CodeWriter.dateClassName)) {
					return M_UTILDATE;
				}
				if ("java.sql.Date".equals(CodeWriter.dateClassName)) {
					return M_SQLDATE;
				}
				if ("java.util.Calendar".equals(CodeWriter.dateClassName)) {
					return M_CALENDAR;
				}
				this.tuoe();
			}
			case Types.DECIMAL : {
				return this.getDecimalDigits() > 0 ? M_BIGDECIMAL : M_LONG;
			}
			case Types.DISTINCT : {
				return M_OBJECT;
			}
			case Types.DOUBLE : {
				return M_DOUBLE;
			}
			case Types.FLOAT : {
				return M_DOUBLE;
			}
			case Types.INTEGER : {
				return this.getTypeName().equalsIgnoreCase("INT UNSIGNED") ? M_LONG : M_INTEGER;
			}
			case Types.JAVA_OBJECT : {
				return M_OBJECT;
			}
			case Types.LONGVARBINARY : {
				return M_BYTES;
			}
			case Types.LONGVARCHAR : {
				return M_STRING;
			}
			case Types.NUMERIC : {
				return this.getDecimalDigits() > 0 ? M_BIGDECIMAL : M_LONG;
			}
			case Types.OTHER : {
				return M_OBJECT;
			}
			case Types.REAL : {
				return M_FLOAT;
			}
			case Types.REF : {
				return M_REF;
			}
			case Types.SMALLINT : {
				return M_SHORT;
			}
			case Types.STRUCT : {
				return M_OBJECT;
			}
			case Types.TIME : {
				if ("java.util.Date".equals(CodeWriter.timeClassName)) {
					return M_UTILDATE;
				}
				if ("java.sql.Time".equals(CodeWriter.timeClassName)) {
					return M_TIME;
				}
				if ("java.util.Calendar".equals(CodeWriter.timeClassName)) {
					return M_CALENDAR;
				}
				this.tuoe();
			}
			case Types.TIMESTAMP : {
				if ("java.util.Date".equals(CodeWriter.timestampClassName)) {
					return M_UTILDATE;
				}
				if ("java.sql.Timestamp".equals(CodeWriter.timestampClassName)) {
					return M_TIMESTAMP;
				}
				if ("java.util.Calendar".equals(CodeWriter.timestampClassName)) {
					return M_CALENDAR;
				}
				this.tuoe();
			}
			case Types.TINYINT : {
				/** 如果字段注释中有NUM tag,则解析NUM tag,且为Boolean返回 M_BOOLEAN */
				if(Boolean.class.equals(remarks.getPrimitiveType())) {
					return M_BOOLEAN;
				}
				return M_BYTE;
			}
			case Types.VARBINARY : {
				return M_BYTES;
			}
			case Types.VARCHAR : {
				return M_STRING;
			}
		}
		this.tuoe();
		return -1;
	}

	public String getQuerySetMethod() {
		switch (this.getType()) {
			case Types.ARRAY : {
				return "setArray";
			}
			case Types.BIGINT : {
				return "setBigDecimal";
			}
			case Types.BINARY : {
				return "setBytes";
			}
			case Types.BIT : {
				return "setBoolean";
			}
			case Types.BLOB : {
				return "setBlob";
			}
			case Types.BOOLEAN : {
				return "setBoolean";
			}
			case Types.CHAR : {
				return "setString";
			}
			case Types.CLOB : {
				return "setClob";
			}
			case Types.DATALINK : {
				return "setURL";
			}
			case Types.DATE : {
				return "setDate";
			}
			case Types.DECIMAL : {
				return this.getDecimalDigits() > 0 ? "setBigDecimal" : "setLong";
			}
			case Types.DISTINCT : {
				return "setObject";
			}
			case Types.DOUBLE : {
				return "setDouble";
			}
			case Types.FLOAT : {
				return "setDouble";
			}
			case Types.INTEGER : {
				return this.getTypeName().equalsIgnoreCase("INT UNSIGNED") ? "setLong" : "setInt";
			}
			case Types.JAVA_OBJECT : {
				return "setObject";
			}
			case Types.LONGVARBINARY : {
				return "setBytes";
			}
			case Types.LONGVARCHAR : {
				return "setString";
			}
			case Types.NUMERIC : {
				return this.getDecimalDigits() > 0 ? "setBigDecimal" : "setLong";
			}
			case Types.OTHER : {
				return "setObject";
			}
			case Types.REAL : {
				return "setFloat";
			}
			case Types.REF : {
				return "setRef";
			}
			case Types.SMALLINT : {
				return "setInt";
			}
			case Types.STRUCT : {
				return "setObject";
			}
			case Types.TIME : {
				if ("java.util.Date".equals(CodeWriter.timeClassName)) {
					return "setDate";
				}
				if ("java.sql.Time".equals(CodeWriter.timeClassName)) {
					return "setTime";
				}
				this.tuoe();
			}
			case Types.TIMESTAMP : {
				if ("java.util.Date".equals(CodeWriter.timestampClassName)) {
					return "setDate";
				}
				if ("java.sql.Timestamp".equals(CodeWriter.timestampClassName)) {
					return "setTimestamp";
				}
				this.tuoe();
			}
			case Types.TINYINT : {
				return "setInt";
			}
			case Types.VARBINARY : {
				return "setBytes";
			}
			case Types.VARCHAR : {
				return "setString";
			}
		}
		this.tuoe();
		return "setObject";
	}
	/**
	 * @return 返回对应的Java类型
	 */
	public Class getJavaClass() {
		switch (this.getMappedType()) {
			case M_ARRAY : {
				return java.sql.Array.class;
			}
			case M_BIGDECIMAL : {
				return java.math.BigDecimal.class;
			}
			case M_BOOLEAN : {
				return Boolean.class;
			}
			case M_BYTES : {
				try {
					if(CodeWriter.DEFAULT_BINARY_TYPE.equals(CodeWriter.binaryClassName)){
						return byte[].class;
					}
					return Class.forName(CodeWriter.binaryClassName);
				} catch (ClassNotFoundException e) {
					throw new RuntimeException(e);
				}
			}
			case M_CLOB : {
				// map Clob to java.lang.String
				return String.class;
			}
			case M_SQLDATE : {
				return java.sql.Date.class;
			}
			case M_UTILDATE : {
				return java.util.Date.class;
			}
			case M_DOUBLE : {
				return Double.class;
			}
			case M_FLOAT : {
				return Float.class;
			}
			case M_BLOB : {
				try {
					return Class.forName(CodeWriter.binaryClassName);
				} catch (ClassNotFoundException e) {
					throw new RuntimeException(e);
				}
			}
			case M_BYTE : {
				return Byte.class;
			}
			case M_SHORT : {
				return Short.class;
			}
			case M_INTEGER : {
				return Integer.class;
			}
			case M_LONG : {
				return Long.class;
			}
			case M_REF : {
				return java.sql.Ref.class;
			}
			case M_STRING : {
				return String.class;
			}
			case M_TIME : {
				return java.sql.Time.class;
			}
			case M_TIMESTAMP : {
				return java.sql.Timestamp.class;
			}
			case M_URL : {
				return java.net.URL.class;
			}
			case M_OBJECT : {
				return firstNonNull(OBJECT_TARGET_TYPES.get(this.getTypeName().toUpperCase()), Object.class);
			}
			case M_CALENDAR : {
				return java.util.Calendar.class;
			}
		}
		this.tiae();
		return null;
	}
    /**
     * SQL 空间数据类型对应的JTS Java类
     */
    private static final ImmutableMap> SPATIAL_TARGET_TYPES = 
            ImmutableMap.>builder()
            .put("GEOMETRY",com.vividsolutions.jts.geom.Geometry.class)
            .put("POINT",com.vividsolutions.jts.geom.Point.class)
            .put("LINESTRING",com.vividsolutions.jts.geom.LineString.class)
            .put("POLYGON",com.vividsolutions.jts.geom.Polygon.class)
            .put("MULTIPOINT",com.vividsolutions.jts.geom.GeometryCollection.class)
            .put("MULTILINESTRING",com.vividsolutions.jts.geom.GeometryCollection.class)
            .put("MULTIPOLYGON",com.vividsolutions.jts.geom.GeometryCollection.class)
            .put("GEOMETRYCOLLECTION",com.vividsolutions.jts.geom.GeometryCollection.class)
            .build();
    /**
     * SQL Object类型对应的Java类型
     */
    private static final ImmutableMap> OBJECT_TARGET_TYPES = 
            ImmutableMap.copyOf(SPATIAL_TARGET_TYPES);
    
	private String getJavaType(Class type) {
		if(type.isArray()){
			return getJavaType(type.getComponentType()) + "[]";
		}
		if(type.isPrimitive()){
			return type.getSimpleName();
		}
		if(type.getPackage().getName().equals("java.lang")){
			return type.getSimpleName();
		}
		return type.getName();
	}
	/**
	 * 返回对应的Java类型,除java语言内置类型(java.lang)外,其他类型返回全名
	 */
	String getJavaType0() {
		if(isGeometry() && "STRING".equalsIgnoreCase(geometrySerialType)) {
			return "String";
		}
		return getJavaType(getJavaClass());
	}
	/**
	 * 返回对应的Java类型,除java语言内置类型(java.lang)外,其他类型返回全名,
	 * 如果SQL注释中定义了字段的Java类型则优先返回注释中定义的类型
	 */
	public String getJavaType() {
		if(isDefinedFieldType()) {
			return remarks.getFieldType();
		}
		return getJavaType0();
	}
	/**
	 * 返回字段的Java类型,除java语言内置类型(java.lang)外,其他类型返回全名
	 */
	String getFieldJavaType0() {
		if(isDefinedFieldType()) {
			return remarks.getFieldType();
		}
		Class javaClass = getJavaClass();
		if(isByteBufferAsString()){
			return "String";
		}
		if(jacksonBeanSupport && jsonJacksonRawValue){
			String jsonType=getJsonType();
			if(null != jsonType) {
				return jsonType;
			}
		}
		return getJavaType(javaClass);
	}
	/**
	 * 返回字段的Java类型,除java语言内置类型(java.lang)外,其他类型返回全名,
	 * 如果SQL注释中定义了字段的Java类型则优先返回注释中定义的类型
	 */
	public String getFieldJavaType() {
		if(isDefinedFieldType()) {
			return remarks.getFieldType();
		}
		return getFieldJavaType0();
	}
	/**
	 * 返回字段 read/write方法的Java类型
	 * @since 3.21.0
	 */
	public String getRwType() {
		if(isDefinedFieldType()) {
			return getJavaType0();
		}else {
			return getFieldJavaType0();
		}
	}
	
	public boolean hasPrimaryType() {
		return this.getJavaPrimaryType() != null;
	}

	public String getJavaPrimaryType() throws IllegalArgumentException {
		int decimalDigits = this.getDecimalDigits();
		if ((this.type == Types.DECIMAL || this.type == Types.NUMERIC) && decimalDigits == 0) {
			if (this.size == 1) {
				return "boolean";
			}
			if (this.size < 3) {
				return "byte";
			}
			if (this.size < 5) {
				return "short";
			}
			if (this.size < 10) {
				return "int";
			}
			if (this.size < 19) {
				return "long";
			}
		}
		switch (this.getMappedType()) {
			case M_BOOLEAN : {
				return "boolean";
			}
			case M_SQLDATE : {
				return "long";
			}
			case M_UTILDATE : {
				return "long";
			}
			case M_DOUBLE : {
				return "double";
			}
			case M_FLOAT : {
				return "float";
			}
			case M_INTEGER : {
				return "int";
			}
			case M_LONG : {
				return "long";
			}
			case M_TIME : {
				return "long";
			}
			case M_TIMESTAMP : {
				return "long";
			}
		}
		return null;
	}
	
	public String getJavaTypeAsTypeName() {
		switch (this.getType()) {
			case Types.ARRAY : {
				return "Types.ARRAY";
			}
			case Types.BIGINT : {
				return "Types.BIGINT";
			}
			case Types.BINARY : {
				return "Types.BINARY";
			}
			case Types.BIT : {
				return "Types.BIT";
			}
			case Types.BLOB : {
				return "Types.BLOB";
			}
			case Types.BOOLEAN : {
				return "Types.BOOLEAN";
			}
			case Types.CHAR : {
				return "Types.CHAR";
			}
			case Types.CLOB : {
				return "Types.CLOB";
			}
			case Types.DATALINK : {
				return "Types.DATALINK";
			}
			case Types.DATE : {
				return "Types.DATE";
			}
			case Types.DECIMAL : {
				return "Types.DECIMAL";
			}
			case Types.DISTINCT : {
				return "Types.DISTINCT";
			}
			case Types.DOUBLE : {
				return "Types.DOUBLE";
			}
			case Types.FLOAT : {
				return "Types.FLOAT";
			}
			case Types.INTEGER : {
				return "Types.INTEGER";
			}
			case Types.JAVA_OBJECT : {
				return "Types.JAVA_OBJECT";
			}
			case Types.LONGVARBINARY : {
				return "Types.LONGVARBINARY";
			}
			case Types.LONGVARCHAR : {
				return "Types.LONGVARCHAR";
			}
			case Types.NULL : {
				return "Types.NULL";
			}
			case Types.NUMERIC : {
				return "Types.NUMERIC";
			}
			case Types.OTHER : {
				return "Types.OTHER";
			}
			case Types.REAL : {
				return "Types.REAL";
			}
			case Types.REF : {
				return "Types.REF";
			}
			case Types.SMALLINT : {
				return "Types.SMALLINT";
			}
			case Types.STRUCT : {
				return "Types.STRUCT";
			}
			case Types.TIME : {
				return "Types.TIME";
			}
			case Types.TIMESTAMP : {
				return "Types.TIMESTAMP";
			}
			case Types.TINYINT : {
				return "Types.TINYINT";
			}
			case Types.VARBINARY : {
				return "Types.VARBINARY";
			}
			case Types.VARCHAR : {
				return "Types.VARCHAR";
			}
		}
		return "unkown SQL type " + this.getType();
	}

	/**
	 * @return 字段类型是否有长度限制
	 */
	public boolean isSizeLimit(){
		switch (this.getMappedType()) {
		case M_ARRAY : 
		case M_BYTES : 
		case M_CLOB : 
		case M_BLOB : 
		case M_STRING :
			return true;
		default:
			return false;
		}
	}
	/**
	 * @return 字段类型是否有最大长度限制
	 */
	public boolean isMaxSize(){
		switch (this.getType()) {
		case Types.BLOB : 
		case Types.CLOB :
		case Types.NCLOB :
		case Types.LONGVARBINARY : 
		case Types.LONGVARCHAR : 
		case Types.VARBINARY : 
		case Types.VARCHAR :
		case Types.NVARCHAR :
			return true;
		default:
			return false;
		}
	}
	/**
	 * @return 字段类型是否有固定长度限制
	 */
	public boolean isFixSize(){
		switch (this.getType()) {
		case Types.ARRAY :
		case Types.BINARY :
		case Types.CHAR :
		case Types.NCHAR:
			return true;
		default:
			return false;
		}
	}

	public boolean isCrossableDefaultvalue(){
		return defaultValue != null && !defaultValue.equals("CURRENT_TIMESTAMP");
	}
	public boolean isColumnNumeric() {
		switch (this.getMappedType()) {
			case M_BIGDECIMAL :
			case M_DOUBLE :
			case M_FLOAT :
			case M_BYTE :
			case M_SHORT :
			case M_INTEGER :
			case M_LONG : {
				return true;
			}
		}
		return false;
	}

	public boolean isString() {
		return M_STRING == this.getMappedType();
	}
	public boolean isFloat() {
		return M_FLOAT == this.getMappedType();
	}
	public boolean isDate() {
		switch (this.getMappedType()) {
		case M_SQLDATE: 
		case M_UTILDATE :
		case M_TIME :
		case M_TIMESTAMP : 
			return true;
		}
		return false;
	}
	public boolean isBinary() {
		switch (this.getMappedType()) {
		case M_BYTES: 
		case M_BLOB:
			return true;
		}
		return false;
	}
	public boolean isCalendar() {
		return this.getMappedType() == M_CALENDAR;
	}

	public boolean hasCompareTo() throws Exception {
		switch (this.getMappedType()) {
			case M_ARRAY : {
				return false;
			}
			case M_BIGDECIMAL : {
				return true;
			}
			case M_BOOLEAN : {
				return true;
			}
			case M_BYTES : {
				return CodeWriter.binaryIsByteBuffer();
			}
			case M_CLOB : {
				// Clob map to java.lang.String that has compareTo
				return true;
			}
			case M_SQLDATE : {
				return true;
			}
			case M_UTILDATE : {
				return true;
			}
			case M_DOUBLE : {
				return true;
			}
			case M_FLOAT : {
				return true;
			}
			case M_BLOB : {
				return CodeWriter.binaryIsByteBuffer();
			}
			case M_INTEGER : {
				return true;
			}
			case M_LONG : {
				return true;
			}
			case M_REF : {
				return false;
			}
			case M_STRING : {
				return true;
			}
			case M_TIME : {
				return true;
			}
			case M_TIMESTAMP : {
				return true;
			}
			case M_URL : {
				return false;
			}
			case M_OBJECT : {
				return false;
			}
			case M_CALENDAR : {
				return true;
			}
		}
		return false;
	}

	public boolean useEqualsInSetter() throws Exception {
		// 优先使用equals方法
		if(hasCompareTo())return true;
		switch (this.getMappedType()) {
			case M_BOOLEAN : {
				return true;
			}
			case M_URL : {
				return true;
			}
		}
		return false;
	}

	public String getResultSetMethodObject(String pos) {
		return this.getResultSetMethodObject("rs", pos);
	}

	public String getResultSetMethodObject(String resultSet, String pos) {
		switch (this.getMappedType()) {
			case M_ARRAY : {
				return resultSet + ".getArray(" + pos + ")";
			}
			case M_LONG : {
				return CodeWriter.MGR_CLASS + ".getLong(" + resultSet + ", " + pos + ")";
			}
			case M_BYTES : {
				return CodeWriter.MGR_CLASS + ".getBytes(" + resultSet + ", " + pos + ")";
			}
			case M_BLOB : {
				return CodeWriter.MGR_CLASS + ".getBlob(" + resultSet + ", " + pos + ")";
			}
			case M_BOOLEAN : {
				return CodeWriter.MGR_CLASS + ".getBoolean(" + resultSet + ", " + pos + ")";
			}
			case M_STRING : {
				return resultSet + ".getString(" + pos + ")";
			}
			case M_CLOB : {
				return CodeWriter.MGR_CLASS + ".getClob(" + resultSet + ", " + pos + ")";
			}
			case M_URL : {
				return resultSet + ".getURL(" + pos + ")";
			}
			case M_BIGDECIMAL : {
				return resultSet + ".getBigDecimal(" + pos + ")";
			}
			case M_DOUBLE : {
				return CodeWriter.MGR_CLASS + ".getDouble(" + resultSet + ", " + pos + ")";
			}
			case M_FLOAT : {
				return CodeWriter.MGR_CLASS + ".getFloat(" + resultSet + ", " + pos + ")";
			}
			case M_INTEGER : {
				return CodeWriter.MGR_CLASS + ".getInteger(" + resultSet + ", " + pos + ")";
			}
			case M_OBJECT : {
				return resultSet + ".getObject(" + pos + ")";
			}
			case M_REF : {
				return resultSet + ".getRef(" + pos + ")";
			}
			case M_SQLDATE : {
				return resultSet + ".getDate(" + pos + ")";
			}
			case M_TIME : {
				return resultSet + ".getTime(" + pos + ")";
			}
			case M_TIMESTAMP : {
				return resultSet + ".getTimestamp(" + pos + ")";
			}
			case M_UTILDATE : {
				switch (this.getType()) {
					case Types.TIME : {
						return resultSet + ".getTime(" + pos + ")";
					}
					case Types.TIMESTAMP : {
						return resultSet + ".getTimestamp(" + pos + ")";
					}
					case Types.DATE : {
						return resultSet + ".getDate(" + pos + ")";
					}
				}
				this.tuoe();
			}
			case M_CALENDAR : {
				return CodeWriter.MGR_CLASS + ".getCalendar(" + resultSet + ", " + pos + ")";
			}
		}
		this.tuoe();
		return null;
	}

	public String getPreparedStatementMethod(String var, int pos) {
		return this.getPreparedStatementMethod(var, String.valueOf(pos));
	}

	public String getPreparedStatementMethod(String var, String pos) {
		StringBuffer sb = new StringBuffer();
		StringBuffer end = new StringBuffer();
		end.append(pos).append(", ").append(var).append(");");
		String fillNullStart = Boolean.TRUE == CodeWriter.getFillNull() ? "" : "if(fillNull){";
		String fillNullEnd = Boolean.TRUE == CodeWriter.getFillNull() ? "" : "}";
        Pattern p = Pattern.compile("^((?:SQL_LIKE_WILDCARD\\s*\\+)*)([\\w\\. \\(\\)-]*)((?:\\+\\s*SQL_LIKE_WILDCARD)*)$");
        
        Matcher m = p.matcher(var);
        if(!m.matches()){
        	throw new IllegalArgumentException(String.format("Not match found %s", var));
        }
		String v = m.group(2);
		sb.append("if (").append(v).append(" == null) {"+fillNullStart+" ps.setNull(").append(pos).append(", ")
				.append(this.getJavaTypeAsTypeName()).append(");").append(fillNullEnd).append(" } else { ");
		end.append(" }");
		switch (this.getMappedType()) {
			case M_ARRAY : {
				return sb.append("ps.setArray(").append(end).toString();
			}
			case M_LONG : {
				return sb.append(CodeWriter.MGR_CLASS).append(".setLong(ps, ").append(end).toString();
			}
			case M_BYTES : {
				return sb.append(CodeWriter.MGR_CLASS).append(".setBytes("+this.getJavaTypeAsTypeName()+",ps, ").append(end).toString();
			}
			case M_BLOB : {
				return sb.append(CodeWriter.MGR_CLASS).append(".setBlob(ps, ").append(end).toString();
			}
			case M_BOOLEAN : {
				return sb.append(CodeWriter.MGR_CLASS).append(".setBoolean(ps, ").append(end).toString();
			}
			case M_STRING : {
				return sb.append("ps.setString(").append(end).toString();
			}
			case M_CLOB : {
				return sb.append(CodeWriter.MGR_CLASS).append(".setClob(ps, ").append(end).toString();
			}
			case M_URL : {
				return sb.append("ps.setURL(").append(end).toString();
			}
			case M_BIGDECIMAL : {
				return sb.append("ps.setBigDecimal(").append(end).toString();
			}
			case M_DOUBLE : {
				return sb.append(CodeWriter.MGR_CLASS).append(".setDouble(ps, ").append(end).toString();
			}
			case M_INTEGER : {
				return sb.append(CodeWriter.MGR_CLASS).append(".setInteger(ps, ").append(end).toString();
			}
			case M_OBJECT : {
				return sb.append("ps.setObject(").append(end).toString();
			}
			case M_FLOAT : {
				return sb.append(CodeWriter.MGR_CLASS).append(".setFloat(ps, ").append(end).toString();
			}
			case M_SQLDATE : {
				return sb.append("ps.setDate(").append(end).toString();
			}
			case M_TIME : {
				return sb.append("ps.setTime(").append(end).toString();
			}
			case M_TIMESTAMP : {
				return sb.append("ps.setTimestamp(").append(end).toString();
			}
			case M_UTILDATE : {
				switch (this.getType()) {
					case Types.TIMESTAMP : {
						return sb.append("ps.setTimestamp(").append(pos).append(", new java.sql.Timestamp(").append(var)
								.append(".getTime())); }").toString();
					}
					case Types.DATE : {
						return sb.append("ps.setDate(").append(pos).append(", new java.sql.Date(").append(var)
								.append(".getTime())); }").toString();
					}
					case Types.TIME : {
						return sb.append("ps.setTime(").append(pos).append(", new java.sql.Time(").append(var)
								.append(".getTime())); }").toString();
					}
				}
				return null;
			}
			case M_CALENDAR : {
				return sb.append(CodeWriter.MGR_CLASS).append(".setCalendar(ps, ").append(end).toString();
			}
			case M_REF : {
				sb.setLength(0);
				sb.append("ps.setRef(").append(end);
				sb.setLength(sb.length() - 2);
				return sb.toString();
			}
		}
		sb.setLength(0);
		sb.append("ps.setObject(").append(end);
		sb.setLength(sb.length() - 2);
		return sb.toString();
	}

	public String getStringConvertionMethod() {
		switch (this.getMappedType()) {
			case M_BIGDECIMAL : {
				return "new java.math.BigDecimal";
			}
			case M_BOOLEAN : {
				return "new Boolean";
			}
			case M_SQLDATE : {
				return "new java.sql.Date";
			}
			case M_DOUBLE : {
				return "new Double";
			}
			case M_FLOAT : {
				return "new Float";
			}
			case M_INTEGER : {
				return "new Integer";
			}
			case M_LONG : {
				return "new Long";
			}
			case M_STRING : {
				return "";
			}
			case M_UTILDATE :
			case M_TIME :
			case M_TIMESTAMP : {
				if ("java.util.GregorianCalendar".equals(CodeWriter.dateClassName)) {
					return "GregorianDate";
				}
				return CodeWriter.MGR_CLASS + ".getDateFromString";
			}
		}
		System.err.println(
				" unknown mapped type " + this.getMappedType() + " (" + this.getType() + ") for " + this.getFullName());
		return "";
	}

	public String getDefaultWidget() {
		if (this.isForeignKey()) {
			return "SelectWidget";
		}
		if (this.isString() && (this.getSize() > 200 || this.getSize() == -1)) {
			return "TextAreaWidget";
		}
		switch (this.getMappedType()) {
			case M_BOOLEAN : {
				return "BooleanWidget";
			}
			case M_SQLDATE :
			case M_UTILDATE :
			case M_TIME :
			case M_TIMESTAMP : {
				return "DateWidget";
			}
			case M_BIGDECIMAL :
			case M_DOUBLE :
			case M_FLOAT :
			case M_INTEGER :
			case M_LONG : {
				return "NumericWidget";
			}
			case M_ARRAY :
			case M_BYTES :
			case M_CLOB :
			case M_REF :
			case M_STRING :
			case M_URL :
			case M_OBJECT : {
				return "InputWidget";
			}
		}
		System.err.println("type unknown for " + this.getFullName());
		return "";
	}

	public boolean isVersion() {
		if (!CodeWriter.optimisticLockType.equalsIgnoreCase("timestamp")) {
			return false;
		}
		if (!this.getName().equalsIgnoreCase(CodeWriter.optimisticLockColumn)) {
			return false;
		}
		if (this.getMappedType() == M_LONG || this.getMappedType() == M_STRING) {
			return true;
		}
		return false;
	}

	public Table getTable() {
		return this.db.getTable(this.getTableName());
	}

	public void addForeignKey(Column col, 
			String fkName, 
			short keySeq,
			Table.ForeignKeyRule updateRule,
			Table.ForeignKeyRule deleteRule) {
		this.foreignKeys.add(col);
		this.getTable().addForeignKey(this, fkName,keySeq, updateRule, deleteRule);
	}

	public List getForeignKeys() {
		return this.foreignKeys;
	}

	public void addImportedKey(Column col) {
		this.importedKeys.add(col);
		this.getTable().addImportedKey(col);
	}

	public List getImportedKeys() {
		return this.importedKeys;
	}

	public int countImportedKeys() {
		return this.importedKeys.size();
	}

	public boolean isImportedKey() {
		if (this.countImportedKeys() > 0) {
			return true;
		}
		return false;
	}

	public Column getForeignColumn() {
		return (Column) this.foreignKeys.get(0);
	}

	public int countForeignKeys() {
		return this.foreignKeys.size();
	}

	public boolean isForeignKey() {
		if (this.countForeignKeys() > 0) {
			return true;
		}
		return false;
	}

	public String getPropertyTag() {
		return (this.getTableName() + "." + this.getName()).toLowerCase();
	}

	public String getDefaultRules() {
		String rule = "";
		rule = this.getNullable() == 0 && !this.isPrimaryKey() ? rule + " nullnotallowed" : rule + " nullallowed";
		if (this.getType() == 91 || this.getType() == 93) {
			rule = rule + " dateformat";
		}
		return rule;
	}

	public boolean getDefaultIncludeFor(String webElement) {
		return true;
	}
	
	private static final String EMPTY_STRING = "";
	/**
	 * 生成缺省值字符串
	 * @param nullInstead 指示{@link #defaultValue}为 {@code null}时是否用字符串'null'代替
	 * @return 缺省值字符串
	 */
	public String getDefaultValue(boolean nullInstead) {
		String empty = nullInstead?"null":EMPTY_STRING;
		if(!CodeWriter.getPropertyBoolean("codewriter.generate.defaultvalue")){
			return empty;
		}
		if (null != this.defaultValue) {
			if (this.isColumnNumeric()) {
				try {
					double value = Double.parseDouble(this.defaultValue);
					switch (this.getMappedType()) {
						case M_BIGDECIMAL :
						case M_SHORT :
						case M_INTEGER :
						case M_LONG : {
							return this.generateNewNumeric(this.getFieldJavaType(), this.defaultValue);
						}
						case M_DOUBLE :
						case M_FLOAT : {
							return this.generateNewNumeric(this.getFieldJavaType(), String.valueOf(value));
						}
						case M_BYTE :{
							return this.defaultValueForByte(this.defaultValue);
						}
					}
					return empty;
				} catch (NumberFormatException nfe) {
					return empty;
				}
			}
			if (this.isDate()) {
				try {
					return generateDateDefaultValue(this.getFieldJavaType(),this.defaultValue);
				} catch (IllegalArgumentException pe) {
					return empty;
				}
			}
			if (this.isString()) {
				return "\"" + this.defaultValue + '\"';
			}
			if (isBoolean()) {
				return "1".equals(this.defaultValue) ? "true" : "false";
			}
		}
		return this.defaultValue == null ? empty : this.defaultValue;
	}
	/** 兼容之前版本 */
	public String getDefaultValue() {
		return getDefaultValue(false);
	}
	/** 返回{@link #defaultValue}原始值 */
	public String getOriginalDefaultValue(){
		return this.defaultValue;
	}
	/** SQL 类型日期字符串转为java 日期对象 */
	private static Date parseSqlDate(String source){
		if(null == source)
			throw new IllegalArgumentException();
		try{
			return java.sql.Date.valueOf(source);
		}catch(IllegalArgumentException e){
			try{
				return java.sql.Time.valueOf(source);
			}catch(IllegalArgumentException e2){
				return java.sql.Timestamp.valueOf(source);
			}
		}
	}
	/** 生成日期类型缺省值语句 */
	private String generateDateDefaultValue(String type, String parameter) {
		StringBuffer sb = new StringBuffer(100);
		Date parsedDate = parseSqlDate(parameter);
		String dateStr;
		switch(this.getMappedType()){
		case M_UTILDATE:{
			String instanceName="";
			if(parsedDate instanceof java.sql.Date){
				instanceName = "new java.text.SimpleDateFormat(\"yyyy-MM-dd\")";
			}else if(parsedDate instanceof java.sql.Time){
				instanceName = "new java.text.SimpleDateFormat(\"HH:mm:ss\")";
			}else if(parsedDate instanceof java.sql.Timestamp){
				instanceName = "new java.text.SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\")";
			}else{
				throw new IllegalStateException("invalid type");
			}
			sb.append(instanceName).append(".parse(\"").append(parsedDate.toString()).append("\",new java.text.ParsePosition(0))");
			break;
		}
		case M_SQLDATE:{
			dateStr = new java.sql.Date(parsedDate.getTime()).toString();
			sb.append(type).append(".valueOf(\"").append(dateStr).append("\")");	
			break;
		}
		case M_TIME:{
			dateStr = new java.sql.Time(parsedDate.getTime()).toString();
			sb.append(type).append(".valueOf(\"").append(dateStr).append("\")");	
			break;
		}
		case M_TIMESTAMP:{
			dateStr = new java.sql.Timestamp(parsedDate.getTime()).toString();
			sb.append(type).append(".valueOf(\"").append(dateStr).append("\")");	
			break;
		}
		default:
			return EMPTY_STRING;
		}
		return sb.toString();
	}	
	
	private String generateNewNumeric(String type, String parameter) {
		StringBuffer sb = new StringBuffer(70);
		sb.append("new ").append(type);
		sb.append('(').append(parameter).append(')');
		return sb.toString();
	}
	private String defaultValueForByte(String parameter) {
		return new StringBuffer(16).append("(byte)").append(parameter).toString();
	}

	/** 生成缺省值({@link #defaultValue})的注释信息 */
	public String commentOfDefaultValue(){
		return Strings.isNullOrEmpty(defaultValue)?EMPTY_STRING: "/* DEFAULT:'"+defaultValue+"'*/";
	}
	/** 生成缺省值赋值语句 */
    public String getDefaultValueAssignment(boolean nullInstead){
    	StringBuffer buffer = new StringBuffer();
    	String value = getDefaultValue(nullInstead);
    	if(!value.isEmpty())
    		buffer.append(" = ").append(value);
    	return buffer.toString();
    }
	public String getRemarks() {
		return this.remarks == null ? "" : this.remarks.getRemarks();
	}

	public String getJavaName() {
		return this.convertName(this.getName());
	}

	public String getSampleData() {
		if (this.getNullable() > 1 && rand.nextInt(20) == 10) {
			return "";
		}
		if (this.isColumnNumeric()) {
			return "" + rand.nextInt(100);
		}
		if (this.isDate()) {
			Calendar rightNow = Calendar.getInstance();
			rightNow.set(2000 + rand.nextInt(20), 1 + rand.nextInt(12), 1 + rand.nextInt(28), rand.nextInt(23),
					rand.nextInt(60), rand.nextInt(60));
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
			return dateFormat.format(rightNow.getTime());
		}
		return StringUtilities.getSampleString((int) this.getSize());
	}

	private String escape(String s) {
		return StringUtilities.escape((String) s);
	}

	private String escape() {
		return this.escape(this.getName());
	}

	public String convertName(String columnName) {
		return StringUtilities.convertName((String) columnName, true);
	}

	public String convertName(Column col) {
		return this.convertName(col.getName());
	}

	public String convertName() {
		return this.convertName(this.name);
	}

	public String getImportedKeyVarName() {
		return this.convertName(this.escape() + "_collection");
	}

	public String getGetMethod() {
		if(isBoolean()) {
			return this.convertName("is_" + this.escape());
		}
		return this.convertName("get_" + this.escape());
	}

	public String getSetMethod() {
		return this.convertName("set_" + this.escape());
	}
	public String getReadMethod() {
		return this.convertName("read_" + this.escape());
	}
	public String getWriteMethod() {
		return this.convertName("write_" + this.escape());
	}
	public String getModifiedMethod() {
		return this.convertName("check_" + this.escape() + "_modified");
	}

	public String getInitializedMethod() {
		return this.convertName("check_" + this.escape() + "_initialized");
	}
	public String getGetCacheMethod() {
		return this.convertName("get_bean_by_" + this.escape());
	}
	public String getPutCacheMethod() {
		return this.convertName("put_by_" + this.escape());
	}
	public String getPutIfAbsentCacheMethod() {
		return this.convertName("put_If_absent_by_" + this.escape());
	}
	public String getReplaceCacheMethod() {
		return this.convertName("replace_by_" + this.escape());
	}

	public String bitAndExpression(String varName){
		if(this.getTable().countColumns()>32){
			int pos = getOrdinalPosition()-1;
			return String.format("(%s[%d] & (1 << %d))",varName,pos>>6,pos & 0x3f);
		}else{
			return String.format("(%s & %s)", varName,getIDMaskConstName());
		}
	}
	
	public String bitORAssignExpression(String varName){
		if(this.getTable().countColumns()>32){
			int pos = getOrdinalPosition()-1;
			return String.format("%s[%d] |= (1 << %d)",varName,pos>>6,pos & 0x3f);
		}else{
			return String.format("%s |= %s", varName,getIDMaskConstName());
		}
	}	
	public String bitResetAssignExpression(String varName){
		if(this.getTable().countColumns()>32){
			int pos = getOrdinalPosition()-1;
			return String.format("%s[%d] &= (~(1 << %d))",varName,pos>>6,pos & 0x3f);
		}else{
			return String.format("%s &= (~%s)", varName,getIDMaskConstName());
		}
	}
	public String getWidgetMethod() {
		return this.convertName("get_" + this.escape() + "_widget");
	}

	public String getVarName() {
		return this.convertName(this.escape());
	}
	public String getCacheVarName() {
		return this.convertName(this.escape() + "_cacher");
	}
	public String getFullVarName() {
		return this.convertName(this.name +"_of_" + this.getTable().getBasename(true));
	}
	public String getModifiedVarName() {
		return this.convertName(this.escape() + "_is_modified");
	}

	public String getInitializedVarName() {
		return this.convertName(this.escape() + "_is_initialized");
	}

	public String getImportedKeyModifiedVarName() {
		return this.convertName(this.escape() + "_collection_is_modified");
	}

	public String getImportedKeyInitializedVarName() {
		return this.convertName(this.escape() + "_collection_is_initialized");
	}

	public String getImportedKeyInitializedMethod() {
		return this.convertName("is_" + this.escape() + "_collection_initialized");
	}

	public String getImportedKeyGetMethod() {
		return this.convertName("get_" + this.escape() + "_collection");
	}

	public String getImportedKeyAddMethod() {
		return this.convertName("add_" + this.escape() + "");
	}

	public String getImportedKeySetMethod() {
		return this.convertName("set_" + this.escape() + "_collection");
	}

	public String getImportedKeyModifiedMethod() {
		return this.convertName("is_" + this.escape() + "_collection_modified");
	}

	public String getForeignKeyVarName() {
		return this.convertName(this.escape() + "_object");
	}

	public String getForeignKeyModifiedVarName() {
		return this.convertName(this.escape() + "_object_is_modified");
	}

	public String getForeignKeyInitializedVarName() {
		return this.convertName(this.escape() + "_object_is_initialized");
	}

	public String getForeignKeyInitializedMethod() {
		return this.convertName("is_" + this.escape() + "_object_initialized");
	}

	public String getForeignKeyGetMethod(String col) {
		return this.convertName("get_" + this.escape() + "_object");
	}

	public String getForeignKeySetMethod(String col) {
		return this.convertName("set_" + this.escape() + "_object");
	}

	public String getForeignKeyModifiedMethod(String col) {
		return this.convertName("is_" + this.escape() + "_object_modified");
	}
	
	public String getTypeName() {
		return this.typeName;
	}

	public void setTypeName(String typeName) {
		this.typeName = typeName;
	}

	public int compareTo(Column obj) {
		return  this.ordinal - obj.ordinal;
	}

	public String getAutoincrement() {
		return autoincrement;
	}

	public void setAutoincrement(String autoincrement) {
		this.autoincrement = autoincrement;
	}
	public boolean isAutoincrement(){
		return "YES".equals(this.autoincrement);
	}
	public boolean isNotNull(){
		return DatabaseMetaData.columnNoNulls  == this.nullable ;
	}
	
	private static final String IV_PREFIX = "invalidvalue.";
	private static final String IV_NUMBER = IV_PREFIX + "number";
	private static final String IV_DATE = IV_PREFIX + "date";
	private static final String PA_PREFIX = "prealloc.";
	private static final String PA_STRING = PA_PREFIX + "string.limit";
	private static final String PA_BINARY = PA_PREFIX + "binary.limit";
	private String getCustomInvalidValueAnn(){
		String iv = CodeWriter.getProperty(IV_PREFIX + ".table." + getTableName() + "."+ getName());
		if(iv != null){
			return String.format("@CodegenInvalidValue(\"%s\")",iv);
		}
		String exp = CodeWriter.getProperty(IV_PREFIX + ".table." + getTableName() + "."+ getName()+".exp" );
		if(exp != null){
			return String.format("@CodegenInvalidValue(exp=\"%s\")",exp);
		}
		return null;
	}
	public String getInvalidValueAnn(){
		if(invalidValueAnn == null){
			synchronized (this) {
				if(invalidValueAnn == null){
					invalidValueAnn = getCustomInvalidValueAnn();
					if(invalidValueAnn == null){
						if(isAutoincrement() || (getForeignKeys().size() ==1 && getForeignColumn().isAutoincrement())){
							invalidValueAnn = "@CodegenInvalidValue(\"0\")";
						} else if(isString()){
							// 空字符串为无效值
							invalidValueAnn = "@CodegenInvalidValue";
						} else if(isBinary()){
							// 空数组为无效值
							invalidValueAnn = "@CodegenInvalidValue";
						} else if(isColumnNumeric()){
							String iv = CodeWriter.getProperty(IV_NUMBER , "-1");							
							invalidValueAnn = "@CodegenInvalidValue(\"" + iv + "\")";
						} else if(isDate()){
							String iv = CodeWriter.getProperty(IV_DATE , "0");				
							invalidValueAnn = "@CodegenInvalidValue(\"" + iv + "\")";
						}else {
							invalidValueAnn = "";
						}
					} 
				}
			}
		}
		return invalidValueAnn;
	}
	
	private boolean isPreAlloc0(){
		if(TypeToken.of(getJavaClass()).isPrimitive()){
			return true;
		}
		String columns = CodeWriter.getProperty(PA_PREFIX + ".table." + getTableName());
		if(columns != null){
			if( elementsOf(columns).contains(getName())){
				return true;
			}
		}
		if(isString()){
			return getSize() <= CodeWriter.getPropertyInteger(PA_STRING);
		}
		if(isBinary()){
			return getSize() <= CodeWriter.getPropertyInteger(PA_BINARY);			
		}
		return false;
	}
	public boolean isPreAlloc(){
		if(preAlloc == null){
			synchronized (this) {
				if(preAlloc == null){
					preAlloc = isPreAlloc0();
				}
			}
		}
		return preAlloc;
	}

	static void setJsonJacksonRawValue(boolean jsonJacksonRawValue) {
		Column.jsonJacksonRawValue = jsonJacksonRawValue;
	}

	static void setByteBufferAsString(boolean byteBufferAsString) {
		Column.byteBufferAsString = byteBufferAsString;
	}

	public static void setJacksonBeanSupport(boolean jacksonBeanSupport) {
		Column.jacksonBeanSupport = jacksonBeanSupport;
	}

	public static void setGeometrySerialType(String geometrySerialType) {
		Column.geometrySerialType = geometrySerialType;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy