package org.nutz.dao.impl.entity.field; import java.util.Collection; import java.util.Map; import org.nutz.castor.Castors; import org.nutz.dao.entity.Entity; import org.nutz.dao.entity.LinkField; import org.nutz.dao.entity.MappingField; import org.nutz.dao.impl.EntityHolder; import org.nutz.dao.impl.entity.info.LinkInfo; import org.nutz.dao.impl.sql.pojo.PojoFetchEntityCallback; import org.nutz.dao.impl.sql.pojo.PojoQueryEntityCallback; import org.nutz.dao.sql.PojoCallback; import org.nutz.lang.Mirror; public abstract class AbstractLinkField extends AbstractEntityField implements LinkField { protected EntityHolder holder; protected Class<?> targetType; protected Entity<?> target; private PojoCallback callback; protected String mapKey; protected MappingField hostField; protected MappingField linkedField; private boolean[] lock = new boolean[0];//最小化的锁对象 public AbstractLinkField(Entity<?> entity, EntityHolder holder, LinkInfo info) { super(entity); this.holder = holder; this.setName(info.name); this.setInjecting(info.injecting); this.setEjecting(info.ejecting); this.setType(info.fieldType); if (getTypeMirror().isOf(Collection.class)) { callback = new PojoQueryEntityCallback(); } else if (getTypeMirror().isOf(Map.class)) { callback = new PojoQueryEntityCallback(); } else if (getTypeClass().isArray()) { callback = new PojoQueryEntityCallback(); } else { callback = new PojoFetchEntityCallback(); } } @Override public void setValue(Object obj, Object value) { if (null != value) { if (!Mirror.me(value).canCastToDirectly(this.getTypeClass())) value = Castors.me().cast(value, value.getClass(), this.getTypeClass(), mapKey); } super.setValue(obj, value); } public Entity<?> getLinkedEntity() { if (null == target) { synchronized (lock) { if (null == target) { if (targetType.equals(getEntity().getType())) target = getEntity(); else target = holder.getEntity(targetType); } } } return target; } public PojoCallback getCallback() { return callback; } public MappingField getHostField() { return hostField; } public MappingField getLinkedField() { return linkedField; } protected Class<?> guessTargetClass(LinkInfo info, Class<?> klass) { if (!klass.equals(Object.class)) return klass; Mirror<?> mirror = Mirror.me(info.fieldType); if (mirror.isCollection()) { return (Class<?>) mirror.getGenericsType(0); } if (mirror.isMap()) { return (Class<?>) mirror.getGenericsType(1); } return mirror.getType(); } }