/**
* Copyright (c) 2012-2013, Michael Yang 杨福海 (www.yangfuhai.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.tsz.afinal.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.util.DeserializeBeanInfo;
import com.alibaba.fastjson.util.FieldInfo;
import com.mfh.comn.annotations.Id;
import com.mfh.comn.annotations.Table;
import net.tsz.afinal.db.table.ManyToOne;
import net.tsz.afinal.db.table.OneToMany;
import net.tsz.afinal.db.table.Property;
import net.tsz.afinal.db.table.TableInfo;
import net.tsz.afinal.exception.DbException;
public class ClassUtils {
/**
* 借助与阿里json开源工具,获取指定类的所有正常属性(包括父类的,有setter的或直接只定义field的,
* 不包括static和transient的)。
* 本afinal开源框架远远没有考虑周全。
* @param clazz
* @return
* @author zhangyz created on 2014-3-12
*/
public static List<FieldInfo> getAllNormalFields(Class<?> clazz) {
DeserializeBeanInfo beanInfo = new DeserializeBeanInfo(clazz);
DeserializeBeanInfo.computeSettersInner(beanInfo, (Type)clazz, true);
List<FieldInfo> fieldInfos = beanInfo.getFieldList();
return fieldInfos;
}
/**
* 根据实体类 获得 实体类对应的表名
* @param entity
* @return
*/
public static String getTableName(Class<?> clazz) {
Table table = clazz.getAnnotation(Table.class);
if(table == null || table.name().trim().length() == 0 ){
//当没有注解的时候默认用类的名称作为表名,并把点(.)替换为下划线(_)
return clazz.getName().replace('.', '_');
}
return table.name();
}
/**
*
* 获取指定对象的主键值
* @param entity
* @return
* @author zhangyz created on 2014-3-12
*/
public static Object getPrimaryKeyValue(Object entity) {
// ClassUtils.getPrimaryKeyField(entity.getClass())
return FieldUtils.getFieldValue(entity, TableInfo.get(entity.getClass()).getId().getField());
}
/**
* 根据实体类获得表的主键数据库字段名
* @param entity
* @return
*/
public static String getPrimaryKeyColumn(Class<?> clazz) {
return TableInfo.get(clazz).getId().getColumn();
/*String primaryKey = null ;//老的代码,无用
Field[] fields = clazz.getDeclaredFields();
if(fields != null){
Id idAnnotation = null ;
Field idField = null ;
for(Field field : fields){ //获取ID注解
idAnnotation = field.getAnnotation(Id.class);
if(idAnnotation != null){
idField = field;
break;
}
}
if(idAnnotation != null){ //有ID注解
primaryKey = idAnnotation.column();
if(primaryKey == null || primaryKey.trim().length() == 0)
primaryKey = idField.getName();
}
else{ //没有ID注解,默认去找 _id 和 id 为主键,优先寻找 _id
for(Field field : fields){
if("_id".equals(field.getName()))
return "_id";
}
for(Field field : fields){
if("id".equals(field.getName()))
return "id";
}
}
}else{
throw new RuntimeException("this model["+clazz+"] has no field");
}
return primaryKey;*/
}
/**
* 判断是否为主键字段
* @param field
* @return
* @author zhangyz created on 2014-3-12
*/
public static boolean isPrimaryKeyField(Field field) {
//获取ID注解
if(field.getAnnotation(Id.class) != null)
return true;
if("_id".equals(field.getName()))
return true;
if("id".equals(field.getName()))
return true;
return false;
}
/**
* 根据类名获得该类的主键java对象,原来的方法,老的代码已被zhangyz废弃
* @param entity
* @deprecated
* @return
*/
/*public static Field getPrimaryKeyField(Class<?> clazz) {
Field primaryKeyField = null ;
Field[] fields = clazz.getDeclaredFields();
if(fields != null){
for(Field field : fields){ //获取ID注解
if(field.getAnnotation(Id.class) != null){
primaryKeyField = field;
break;
}
}
if(primaryKeyField == null){ //没有ID注解
for(Field field : fields){
if("_id".equals(field.getName())){
primaryKeyField = field;
break;
}
}
}
if(primaryKeyField == null){ // 如果没有_id的字段
for(Field field : fields){
if("id".equals(field.getName())){
primaryKeyField = field;
break;
}
}
}
}else{
throw new RuntimeException("this model["+clazz+"] has no id field");
}
return primaryKeyField;
}*/
/**
* 根据类名获得该类的主键属性名
* @param entity
* @return
*/
public static String getPrimaryKeyFieldName(Class<?> clazz) {
net.tsz.afinal.db.table.Id id = TableInfo.get(clazz).getId();
return id == null ? null : id.getFieldName();
/*Field f = getPrimaryKeyField(clazz);
return f==null ? null:f.getName();*///老的代码,无用
}
/**
* 把java字段对象转换成本框架的property对象
* @param f
* @param clazz
* @return
* @author zhangyz created on 2014-3-12
*/
public static Property genProperty(Field f, Class<?> clazz) {
//必须是基本数据类型和没有标瞬时态的字段
if(!FieldUtils.isTransient(f)){
if (FieldUtils.isBaseDateType(f)) {
Property property = new Property();
//property.setColumn(FieldUtils.getColumnByField(f));
String[] colCaption = FieldUtils.getColumnByField(f);
property.setColumnAndCaption(colCaption[0], colCaption[1]);
property.setFieldName(f.getName());
property.setDataType(f.getType());
property.setDefaultValue(FieldUtils.getPropertyDefaultValue(f));
property.setSet(FieldUtils.getFieldSetMethod(clazz, f));
property.setGet(FieldUtils.getFieldGetMethod(clazz, f));
property.setField(f);
return property;
}
}
return null;
}
/**
* 将对象转换为ContentValues, 老的代码已被zhangyz废弃
* @deprecated
* @param entity
* @param selective 是否忽略 值为null的字段
* @return
*/
/*private static List<Property> getPropertyList(Class<?> clazz) {
List<Property> plist = new ArrayList<Property>();
try {
Field[] fs = clazz.getDeclaredFields();
String primaryKeyFieldName = getPrimaryKeyFieldName(clazz);
for (Field f : fs) {
//必须是基本数据类型和没有标瞬时态的字段
if(!FieldUtils.isTransient(f)){
if (FieldUtils.isBaseDateType(f)) {
if(f.getName().equals(primaryKeyFieldName)) //过滤主键
continue;
Property property = new Property();
//property.setColumn(FieldUtils.getColumnByField(f));
String[] colCaption = FieldUtils.getColumnByField(f);
property.setColumnAndCaption(colCaption[0], colCaption[1]);
property.setFieldName(f.getName());
property.setDataType(f.getType());
property.setDefaultValue(FieldUtils.getPropertyDefaultValue(f));
property.setSet(FieldUtils.getFieldSetMethod(clazz, f));
property.setGet(FieldUtils.getFieldGetMethod(clazz, f));
property.setField(f);
plist.add(property);
}
}
}
return plist;
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}*/
/**
* 将对象转换为ContentValues
*
* @param entity
* @param selective 是否忽略 值为null的字段
* @return
*/
public static List<ManyToOne> getManyToOneList(Class<?> clazz) {
List<ManyToOne> mList = new ArrayList<ManyToOne>();
try {
Field[] fs = clazz.getDeclaredFields();
for (Field f : fs) {
if (!FieldUtils.isTransient(f) && FieldUtils.isManyToOne(f)) {
ManyToOne mto = new ManyToOne();
mto.setManyClass(f.getType());
//mto.setColumn(FieldUtils.getColumnByField(f));
String[] colCaption = FieldUtils.getColumnByField(f);
mto.setColumnAndCaption(colCaption[0], colCaption[1]);
mto.setFieldName(f.getName());
mto.setDataType(f.getType());
mto.setSet(FieldUtils.getFieldSetMethod(clazz, f));
mto.setGet(FieldUtils.getFieldGetMethod(clazz, f));
mList.add(mto);
}
}
return mList;
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
/**
* 将对象转换为ContentValues
*
* @param entity
* @param selective 是否忽略 值为null的字段
* @return
*/
public static List<OneToMany> getOneToManyList(Class<?> clazz) {
List<OneToMany> oList = new ArrayList<OneToMany>();
try {
Field[] fs = clazz.getDeclaredFields();
for (Field f : fs) {
if (!FieldUtils.isTransient(f) && FieldUtils.isOneToMany(f)) {
OneToMany otm = new OneToMany();
//otm.setColumn(FieldUtils.getColumnByField(f));
String[] colCaption = FieldUtils.getColumnByField(f);
otm.setColumnAndCaption(colCaption[0], colCaption[1]);
otm.setFieldName(f.getName());
Type type = f.getGenericType();
if(type instanceof ParameterizedType){
ParameterizedType pType = (ParameterizedType) f.getGenericType();
Class<?> pClazz = (Class<?>)pType.getActualTypeArguments()[0];
if(pClazz!=null)
otm.setOneClass(pClazz);
}else{
throw new DbException("getOneToManyList Exception:"+f.getName()+"'s type is null");
}
otm.setDataType(f.getClass());
otm.setSet(FieldUtils.getFieldSetMethod(clazz, f));
otm.setGet(FieldUtils.getFieldGetMethod(clazz, f));
oList.add(otm);
}
}
return oList;
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}