package com.jqmobile.core.android.db.orm; import java.lang.reflect.Field; import java.math.BigInteger; import java.util.HashMap; import java.util.Map; import java.util.UUID; import android.database.Cursor; import com.jqmobile.core.orm.DBColumn; import com.jqmobile.core.orm.exception.ORMNotDBColumnException; import com.jqmobile.core.orm.exception.ORMParamNotRecognitionException; public class BaseDBColumn { private final Field field; private DBColumn dbLable; private final static Map<Field, BaseDBColumn> map = new HashMap<Field, BaseDBColumn>(); public static BaseDBColumn getInstance(Field f) { synchronized (map) { if(!map.containsKey(f)){ map.put(f, new BaseDBColumn(f)); } } return map.get(f); } public BaseDBColumn(Field f){ this.field = f; this.dbLable = f.getAnnotation(DBColumn.class); } public Field getField() { return field; } public boolean isMapping(){ return null == dbLable || dbLable.mapping(); } public String getColumnName(){ valiColumn(); if(null == dbLable || DBColumn.DefaultValue.equals(dbLable.name())) return field.getName(); return dbLable.name(); } public DBColumn getDBColumn(){ return dbLable; } public boolean isPaimaryId() { valiColumn(); return null != dbLable && dbLable.primaryId(); } public String getColumnType() { valiColumn(); if(null != dbLable && (dbLable.primaryId() || dbLable.id())){ return "binary(16)"; }else if(null == dbLable || DBColumn.DefaultValue.equals(dbLable.type())){ Class<?> fieldType = field.getType(); if (isIn(fieldType.getName(),"java.lang.Long","long")&&field.getAnnotation(DBColumn.class)!=null&&!field.getAnnotation(DBColumn.class).date()) { return "bigint(20)"; } else if (isIn(fieldType.getName(),"java.lang.Double","double")) { return "decimal(17,5)"; } else if (isIn(fieldType.getName(),"java.lang.Integer","int")) { return "int"; } else if (isIn(fieldType.getName(),"java.lang.Float","float")) { return "float"; }else if(isIn(fieldType.getName(), "java.util.Date","Date")){ return "timestamp"; } else if(isIn(fieldType.getName(), "java.sql.Date","Date")){ return "timestamp"; }else if(isIn(fieldType.getName(),"java.lang.Long","long")&&field.getAnnotation(DBColumn.class)!=null&&field.getAnnotation(DBColumn.class).date()){ return "timestamp"; }else { int length = null==dbLable?DBColumn.DefaultLength:dbLable.length(); if (isIn(fieldType.getName(),"java.lang.Byte","byte")) { return "binary("+length+")"; } else if (isIn(fieldType.getName(),"java.lang.Short", "short")) { return "smallint"; } else if (isIn(fieldType.getName(),"java.lang.Boolean", "boolean")) { return "boolean"; } else if (isIn(fieldType.getName(),"java.util.UUID")) { return "binary(16)"; } else if (isIn(fieldType.getName(),"java.lang.String")) { return "varchar("+length+")"; } else{ throw new ORMNotDBColumnException("暂时不支持此类型自动映射:【"+field.getName()+"】"+fieldType.getName()); } } } return dbLable.type()+getColumnOther(field, dbLable, getColumnType(), getColumnName()); } private String getColumnOther(Field f, DBColumn lable, String columnType, String columnName) { String str; if(columnType.contains("varchar")){ str = "CHARACTER SET utf8 DEFAULT "+getColumnDefault(lable); }else if(columnName.toUpperCase().equals("RECID")){ str = "NOT NULL"; }else if(!lable.canNull()){ str = "NOT Null"; }else{ str = ""; // str = "DEFAULT "+getColumnDefault(lable); } if(null != lable.comment() && !"".equals(lable.comment().trim())){ str = str + " COMMENT '"+ lable.comment()+"'"; } return str; } private static String getColumnDefault(DBColumn lable) { // if(DBColumn.DefaultValue.equals(lable.())){ return "NULL"; // } // return lable.value(); } public Object getFormatObj(Object obj){ if(null != dbLable && (dbLable.primaryId() || dbLable.id())){ if(obj instanceof UUID){ return obj.toString(); }else if(obj instanceof String){ return obj; }else{ throw new ORMParamNotRecognitionException("guid类型:"+obj); } } return obj; } public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException{ field.set(obj, value); } // private void valiColumn() throws ORMNotDBColumnException{ if(!isMapping()) throw new ORMNotDBColumnException(); } // @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((field == null) ? 0 : field.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; BaseDBColumn other = (BaseDBColumn) obj; if (field == null) { if (other.field != null) return false; } else if (!field.equals(other.field)) return false; return true; } public Object getValue(Cursor rs) { return getFieldValue(this, rs); } private static Object getFieldValue(BaseDBColumn field, Cursor rs) { Object obj = null; String name = field.getColumnName(); int columnIndex = rs.getColumnIndex(name); Class<?> fieldType = field.getField().getType(); DBColumn lable = field.getDBColumn(); if(null != lable && (lable.id() || lable.primaryId()) && isIn(fieldType.getName(),"java.lang.String")){ try { obj = rs.getString(columnIndex); } catch (Throwable e) { return null; } } else if (isIn(fieldType.getName(),"java.lang.Long","long")) { // if(null != lable && field.getField().getAnnotation(DBColumn.class).date()){ // try { // obj = rs.getTimestamp(columnIndex).getTime(); // } catch (Exception e) { // obj = getLong(rs, obj, columnIndex, fieldType); // } // }else{ // obj = getLong(rs, obj, columnIndex, fieldType); // } try { rs.getLong(columnIndex); } catch (Throwable e) { if(fieldType.getName().equals("double")) obj = 0l; else return null; } } else if (isIn(fieldType.getName(),"java.lang.Double","double")) { try { obj = rs.getDouble(columnIndex); } catch (Throwable e) { if(fieldType.getName().equals("double")) obj = 0d; else return null; } } else if (isIn(fieldType.getName(),"java.lang.Integer","int")) { try { obj = rs.getInt(columnIndex); } catch (Throwable e) { if(fieldType.getName().equals("int")) obj = 0; else return null; } } else if (isIn(fieldType.getName(),"java.lang.Float","float")) { try { obj = rs.getFloat(columnIndex); } catch (Throwable e) { if(fieldType.getName().equals("float")) obj = 0f; else return null; } } else if (isIn(fieldType.getName(),"java.lang.Byte","byte")) { try { obj = new Byte(rs.getString(columnIndex)); } catch (Throwable e) { return null; } } else if (isIn(fieldType.getName(),"java.lang.Short", "short")) { try { obj = rs.getShort(columnIndex); } catch (Throwable e) { if(fieldType.getName().equals("short")) obj = (short)0; else return null; } } else if (isIn(fieldType.getName(),"java.lang.Boolean", "boolean")) { try { obj = 1 == rs.getInt(columnIndex); } catch (Throwable e) { if(fieldType.getName().equals("boolean")) obj = false; else return null; } } else if (isIn(fieldType.getName(),"java.util.UUID")) { try { obj = UUID.fromString(rs.getString(columnIndex)); } catch (Throwable e) { return null; }//UUID.valueOf(str); } else if (isIn(fieldType.getName(),"java.lang.String")) { try { obj = rs.getString(columnIndex); } catch (Throwable e) { return null; } }else if(fieldType.isArray() && isIn(fieldType.getName(), "[B", "[Ljava.lang.Byte;")){ try{ obj = rs.getBlob(columnIndex); }catch(Throwable e){ return null; } }else if(isIn(fieldType.getName(),"java.math.BigInteger")){ try { obj = new BigInteger(rs.getString(columnIndex)); } catch (Throwable e) { return null; } } else{ obj = null; } return obj; } public static boolean isIn(String str, String...ins){ for(String s : ins){ if(s.equals(str)){ return true; } } return false; } }