package org.nutz.dao.impl.entity.info;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.nutz.dao.DaoException;
import org.nutz.dao.entity.annotation.ColDefine;
import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Comment;
import org.nutz.dao.entity.annotation.Default;
import org.nutz.dao.entity.annotation.Id;
import org.nutz.dao.entity.annotation.Many;
import org.nutz.dao.entity.annotation.ManyMany;
import org.nutz.dao.entity.annotation.Name;
import org.nutz.dao.entity.annotation.Next;
import org.nutz.dao.entity.annotation.One;
import org.nutz.dao.entity.annotation.PK;
import org.nutz.dao.entity.annotation.Prev;
import org.nutz.dao.entity.annotation.Readonly;
import org.nutz.lang.Lang;
import org.nutz.lang.Mirror;
import org.nutz.lang.eject.EjectByField;
import org.nutz.lang.eject.EjectByGetter;
import org.nutz.lang.inject.InjectByField;
import org.nutz.lang.inject.InjectBySetter;
import org.nutz.lang.util.Callback3;
public class _Infos {
private final static String ERR_MSG = "Method '%s'(%s) can not add '@Column', it MUST be a setter or getter!";
private static <T extends FieldInfo> T create(Class<T> classOfT, Field field) {
T info = Mirror.me(classOfT).born();
info.name = field.getName();
info.fieldType = field.getGenericType();
info.injecting = new InjectByField(field);
info.ejecting = new EjectByField(field);
return info;
}
private static <T extends FieldInfo> T create(Class<T> classOfT, final Method method) {
final T info = Mirror.me(classOfT).born();
Mirror.evalGetterSetter(method, ERR_MSG, new Callback3<String, Method, Method>() {
public void invoke(String name, Method getter, Method setter) {
// 木有 getter
if (null == getter) {
throw Lang.makeThrow( "Method '%s'(%s) has '@Column', but NO setter!",
method.getName(),
method.getDeclaringClass().getName());
}
// 木有 setter
if (null == setter) {
throw Lang.makeThrow( "Method '%s'(%s) has '@Column', but NO setter!",
method.getName(),
method.getDeclaringClass().getName());
}
// 正常,开始设值
info.name = name;
info.fieldType = getter.getGenericReturnType();
info.ejecting = new EjectByGetter(getter);
info.injecting = new InjectBySetter(setter);
}
});
return info;
}
public static LinkInfo createLinkInfo(Method method) {
LinkInfo info = create(LinkInfo.class, method);
info.one = method.getAnnotation(One.class);
info.many = method.getAnnotation(Many.class);
info.manymany = method.getAnnotation(ManyMany.class);
return info;
}
public static LinkInfo createLinkInfo(Field field) {
LinkInfo info = create(LinkInfo.class, field);
info.one = field.getAnnotation(One.class);
info.many = field.getAnnotation(Many.class);
info.manymany = field.getAnnotation(ManyMany.class);
info.comment = field.getAnnotation(Comment.class);
return info;
}
/**
* 根据 getter/setter 函数获取一个实体字段信息对象
*
* @param pk
* 复合主键
* @param method
* 方法:可能是 getter 或者是 setter
* @return 字段信息对象
*/
public static MappingInfo createMapingInfo(PK pk, Method method) {
MappingInfo info = create(MappingInfo.class, method);
info.annPK = pk;
info.annColumn = method.getAnnotation(Column.class);
info.annDefine = method.getAnnotation(ColDefine.class);
info.annDefault = method.getAnnotation(Default.class);
info.annId = method.getAnnotation(Id.class);
info.annName = method.getAnnotation(Name.class);
info.annNext = method.getAnnotation(Next.class);
info.annPrev = method.getAnnotation(Prev.class);
info.annReadonly = method.getAnnotation(Readonly.class);
return info;
}
/**
* 根据 Java 字段创建一个实体字段信息对象
*
* @param pk
* 复合主键
* @param field
* Java 字段
* @return 字段信息对象
*/
public static MappingInfo createMappingInfo(PK pk, Field field) {
MappingInfo info = create(MappingInfo.class, field);
info.annPK = pk;
info.annColumn = field.getAnnotation(Column.class);
info.annDefine = field.getAnnotation(ColDefine.class);
info.annDefault = field.getAnnotation(Default.class);
info.annId = field.getAnnotation(Id.class);
info.annName = field.getAnnotation(Name.class);
info.annNext = field.getAnnotation(Next.class);
info.annPrev = field.getAnnotation(Prev.class);
info.annReadonly = field.getAnnotation(Readonly.class);
info.columnComment = field.getAnnotation(Comment.class);
//检查@Id和@Name的属性类型
if (info.annId != null) {
if (!Mirror.me(field.getType()).isIntLike())
throw Lang.makeThrow(DaoException.class, "Field(%s) annotation @Id , but not Number type!!", field);
}
if (info.annName != null)
if (!Mirror.me(field.getType()).isStringLike())
throw Lang.makeThrow(DaoException.class, "Field(%s) annotation @Name , but not String type!!", field);
return info;
}
}