package org.nutz.dao.impl.entity.field; import org.nutz.dao.Cnd; import org.nutz.dao.Condition; import org.nutz.dao.DaoException; import org.nutz.dao.entity.Entity; import org.nutz.dao.entity.LinkType; import org.nutz.dao.entity.MappingField; import org.nutz.dao.impl.EntityHolder; import org.nutz.dao.impl.entity.NutEntity; import org.nutz.dao.impl.entity.info.LinkInfo; import org.nutz.lang.Each; import org.nutz.lang.ExitLoop; import org.nutz.lang.Lang; import org.nutz.lang.LoopException; import org.nutz.lang.Mirror; import org.nutz.lang.Strings; public class ManyLinkField extends AbstractLinkField { public ManyLinkField(Entity<?> entity, EntityHolder holder, LinkInfo info) { super(entity, holder, info); this.targetType = guessTargetClass(info, info.many.target()); this.mapKey = info.many.key(); Entity<?> ta = this.getLinkedEntity(); if (Strings.isBlank(info.many.field())) { hostField = null; linkedField = null; return; } String targetFieldName = "_".equals(info.many.field()) ? Strings.lowerFirst(getEntity().getType() .getSimpleName()) + "Id" : info.many.field(); linkedField = ta.getField(targetFieldName); if (null == linkedField) { throw new DaoException(String.format("host class=%s, props=%s @Many(field=\"%s\",key=\"%s\")) expect prop=%s found at target class=%s", getEntity().getType().getName(), info.name, targetFieldName, info.many.key(), targetFieldName, targetType.getName())); } // 宿主实体的字段 - 应该是主键 boolean intLike = linkedField.getTypeMirror().isIntLike(); if (Strings.isBlank(mapKey) || Mirror.me(info.fieldType).isMap()) { hostField = intLike ? getEntity().getIdField() : getEntity().getNameField(); if (hostField == null) { throw new DaoException(String.format("host class=%s, prop=%s @Many(field=\"%s\",key=\"%s\")) expect any field %s found at target class=%s", getEntity().getType().getName(), info.name, targetFieldName, info.many.key(), intLike ? "@Id" : "@Name", targetType.getName())); } } else { hostField = this.getEntity().getField(mapKey); if (hostField == null) { throw new DaoException(String.format("host class=%s, prop=%s @Many(field=\"%s\",key=\"%s\")) expect prop=%s found at target class=%s", getEntity().getType().getName(), info.name, targetFieldName, info.many.key(), mapKey, targetType.getName())); } } } public ManyLinkField(NutEntity<?> en, EntityHolder holder, LinkInfo info, Class<?> klass, MappingField mf, MappingField mfKey) { super(en, holder, info); this.targetType = klass; this.hostField = mf; this.linkedField = mfKey; } public Condition createCondition(Object host) { return null == linkedField ? null : Cnd.where(linkedField.getName(), "=", hostField.getValue(host)); } public void updateLinkedField(Object obj, Object linked) { if (null != hostField) { final Object v = hostField.getValue(obj); Lang.each(linked, new Each<Object>() { public void invoke(int i, Object ele, int length) throws ExitLoop, LoopException { linkedField.setValue(ele, v); } }); } } public MappingField getHostField() { return hostField; } public MappingField getLinkedField() { return linkedField; } public void saveLinkedField(Object obj, Object linked) {} public LinkType getLinkType() { return LinkType.MANY; } }