package com.alibaba.tamper.core; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.tamper.core.config.BeanMappingBehavior; import com.alibaba.tamper.core.config.BeanMappingConfigHelper; import com.alibaba.tamper.core.config.BeanMappingField; import com.alibaba.tamper.core.config.BeanMappingObject; import com.alibaba.tamper.core.helper.BatchObjectHolder; import com.alibaba.tamper.core.introspect.BatchExecutor; import com.alibaba.tamper.core.introspect.FastPropertyGetExecutor; import com.alibaba.tamper.core.introspect.FastPropertySetExecutor; import com.alibaba.tamper.core.introspect.GetExecutor; import com.alibaba.tamper.core.introspect.MapSetExecutor; import com.alibaba.tamper.core.introspect.PropertyGetExecutor; import com.alibaba.tamper.core.introspect.PropertySetExecutor; import com.alibaba.tamper.core.introspect.SetExecutor; import com.alibaba.tamper.core.introspect.Uberspector; import com.alibaba.tamper.core.process.ValueProcessContext; import com.alibaba.tamper.core.process.ValueProcessInvocation; /** * Bean mapping具体的执行器 * * @author jianghang 2011-5-26 下午04:27:35 */ public class BeanMappingExecutor { private final static Logger logger = LoggerFactory.getLogger(BeanMappingExecutor.class); /** * 根据传递的param,进行mapping处理 */ public static void execute(BeanMappingParam param) { BeanMappingObject config = param.getConfig(); boolean isDebug = config.getBehavior().isDebug(); if (isDebug && logger.isDebugEnabled()) { logger.debug("====================== start mapping \n\t srcClass[" + param.getSrcRef().getClass().toString() + "] \n\t targetClass[" + param.getTargetRef().getClass().toString() + "]"); } BatchObjectHolder holder = null; BatchExecutor getBatchExecutor = null; BatchExecutor setBatchExecutor = null; if (config.isBatch()) { // 执行一次batch get操作,注意batch的获取操作需要放置在doFieldMapping/doBeanMapping之前 getBatchExecutor = getGetBatchExecutor(param, config); setBatchExecutor = getSetBatchExecutor(param, config); } if (config.isBatch() && getBatchExecutor != null) { // 执行一次batch get操作 Object[] batchValues = getBatchExecutor.gets(param.getSrcRef()); holder = new BatchObjectHolder(batchValues); } List<BeanMappingField> beanFields = config.getBeanFields(); for (int i = 0, size = beanFields.size(); i < size; i++) { BeanMappingField beanField = beanFields.get(i); if (beanField.isMapping()) { doBeanMapping(param, beanField, holder); } else { doFieldMapping(param, beanField, holder); } } if (config.isBatch() && setBatchExecutor != null && holder != null) { // 执行一次batch set操作 setBatchExecutor.sets(param.getTargetRef(), holder.getBatchValues()); } if (isDebug && logger.isDebugEnabled()) { logger.debug("====================== end mapping"); } } /** * 获取set操作的BatchExecutor */ private static BatchExecutor getSetBatchExecutor(BeanMappingParam param, BeanMappingObject config) { BatchExecutor executor = config.getSetBatchExecutor(); if (executor != null) { // 如果已经生成,则直接返回 return executor; } if (canBatch(config.getBehavior()) == false) { config.setBatch(false); return null; } // 处理target操作数据搜集 List<String> targetFields = new ArrayList<String>(); List<Class> targetArgs = new ArrayList<Class>(); Class locatorClass = param.getTargetRef().getClass(); // 检查一下locatorClass for (BeanMappingField beanField : config.getBeanFields()) { String targetField = beanField.getTargetField().getName(); Class targetArg = beanField.getTargetField().getClazz(); if (StringUtils.isEmpty(targetField) || targetArg == null) { return null; // 直接不予处理 } Class selfLocatorClass = beanField.getTargetField().getLocatorClass(); if (selfLocatorClass != null && selfLocatorClass != locatorClass) { config.setBatch(false);// 直接改写为false,发现locatorClass存在于不同的class return null; } if (canBatch(beanField.getBehavior()) == false) { config.setBatch(false); return null; } SetExecutor set = beanField.getSetExecutor();// 只针对property进行batch优化 if (set != null && (set instanceof FastPropertySetExecutor || set instanceof PropertySetExecutor) == false) { config.setBatch(false); return null; } // 搜集信息 targetFields.add(targetField); targetArgs.add(targetArg); } // 生成下target批量处理器 executor = Uberspector.getInstance().getBatchExecutor(locatorClass, targetFields.toArray(new String[targetFields.size()]), targetArgs.toArray(new Class[targetArgs.size()])); if (config.getBehavior().isDebug() && logger.isDebugEnabled()) { logger.debug("TargetClass[" + param.getTargetRef().getClass() + "]SetBatchExecutor is init"); } config.setSetBatchExecutor(executor); return executor; } /** * 获取get操作的BatchExecutor */ private static BatchExecutor getGetBatchExecutor(BeanMappingParam param, BeanMappingObject config) { BatchExecutor executor = config.getGetBatchExecutor(); if (executor != null) { // 如果已经生成,则直接返回 return executor; } if (canBatch(config.getBehavior()) == false) { config.setBatch(false); return null; } List<String> srcFields = new ArrayList<String>(); List<Class> srcArgs = new ArrayList<Class>(); // 处理src操作数据搜集 Class locatorClass = param.getSrcRef().getClass(); for (BeanMappingField beanField : config.getBeanFields()) { String srcField = beanField.getSrcField().getName(); Class srcArg = beanField.getSrcField().getClazz(); if (StringUtils.isEmpty(srcField) || srcArg == null) { return null; // 直接不予处理 } Class selfLocatorClass = beanField.getSrcField().getLocatorClass(); if (selfLocatorClass != null && selfLocatorClass != locatorClass) { config.setBatch(false);// 直接改写为false,发现locatorClass存在于不同的class } if (canBatch(beanField.getBehavior()) == false) { config.setBatch(false); return null; } GetExecutor get = beanField.getGetExecutor();// 只针对property进行batch优化 if (get != null && (get instanceof FastPropertyGetExecutor || get instanceof PropertyGetExecutor) == false) { config.setBatch(false); return null; } // 搜集信息 srcFields.add(srcField); srcArgs.add(srcArg); } // 生成下src批量处理器 executor = Uberspector.getInstance().getBatchExecutor(locatorClass, srcFields.toArray(new String[srcFields.size()]), srcArgs.toArray(new Class[srcArgs.size()])); if (config.getBehavior().isDebug() && logger.isDebugEnabled()) { logger.debug("SrcClass[" + param.getSrcRef().getClass() + "]GetBatchExecutor is init"); } config.setGetBatchExecutor(executor); return executor; } /** * 处理下模型的field的mapping动作 */ private static void doFieldMapping(BeanMappingParam param, BeanMappingField beanField, BatchObjectHolder holder) { // 定义valueContext ValueProcessContext valueContext = new ValueProcessContext(param, param.getConfig(), beanField, holder, param.getCustomValueContext()); // 设置getExecutor GetExecutor getExecutor = beanField.getGetExecutor();// 优先从beanField里取 if (getExecutor == null && StringUtils.isNotEmpty(beanField.getSrcField().getName())) {// 如果不为空,可能存在script Class locatorClass = beanField.getSrcField().getLocatorClass();// 从locatorClass中获取 if (locatorClass == null) { locatorClass = param.getSrcRef().getClass(); beanField.getSrcField().setLocatorClass(locatorClass); } getExecutor = Uberspector.getInstance().getGetExecutor(locatorClass, beanField.getSrcField().getName()); beanField.setGetExecutor(getExecutor); } // 设置setExecutor SetExecutor setExecutor = beanField.getSetExecutor();// 优先从beanField里取 if (setExecutor == null && StringUtils.isNotEmpty(beanField.getTargetField().getName())) { Class locatorClass = beanField.getTargetField().getLocatorClass();// 从locatorClass中获取 if (locatorClass == null) { locatorClass = param.getTargetRef().getClass(); beanField.getTargetField().setLocatorClass(locatorClass); } setExecutor = Uberspector.getInstance().getSetExecutor(locatorClass, beanField.getTargetField().getName(), beanField.getTargetField().getClazz()); beanField.setSetExecutor(setExecutor); } // 获取get结果 ValueProcessInvocation invocation = new ValueProcessInvocation(getExecutor, setExecutor, valueContext, param.getProcesses()); Object getResult = invocation.getInitialValue(); // 设置下srcClass Class getResultClass = (getResult != null) ? getResult.getClass() : null; if (getExecutor != null && beanField.getSrcField().getClazz() == null) { beanField.getSrcField().setClazz( Uberspector.getInstance().getGetClass(getExecutor, param.getSrcRef().getClass(), getResultClass)); } // 设置下targetClass if (setExecutor != null && beanField.getTargetField().getClazz() == null) { beanField.getTargetField().setClazz( Uberspector.getInstance().getSetClass(setExecutor, param.getTargetRef().getClass(), getResultClass)); } // 开始ValueProcess流程 invocation.proceed(getResult); } /** * 处理下子模型的嵌套mapping动作 */ private static void doBeanMapping(BeanMappingParam param, BeanMappingField beanField, BatchObjectHolder holder) { // 定义valueContext ValueProcessContext valueContext = new ValueProcessContext(param, param.getConfig(), beanField, holder, param.getCustomValueContext()); // 检查一下targetClass是否有设置,针对bean对象有效 // 如果目标对象是map,需要客户端强制设定targetClass GetExecutor getExecutor = beanField.getGetExecutor(); if (getExecutor == null && StringUtils.isNotEmpty(beanField.getSrcField().getName())) {// 可能存在为空 Class locatorClass = beanField.getSrcField().getLocatorClass();// 从locatorClass中获取 if (locatorClass == null) { locatorClass = param.getSrcRef().getClass(); beanField.getSrcField().setLocatorClass(locatorClass); } getExecutor = Uberspector.getInstance().getGetExecutor(locatorClass, beanField.getSrcField().getName()); beanField.setGetExecutor(getExecutor); } SetExecutor setExecutor = beanField.getSetExecutor(); if (setExecutor == null && StringUtils.isNotEmpty(beanField.getTargetField().getName())) {// 可能存在为空 Class locatorClass = beanField.getTargetField().getLocatorClass();// 从locatorClass中获取 if (locatorClass == null) { locatorClass = param.getTargetRef().getClass(); beanField.getTargetField().setLocatorClass(locatorClass); } setExecutor = Uberspector.getInstance().getSetExecutor(locatorClass, beanField.getTargetField().getName(), beanField.getTargetField().getClazz()); beanField.setSetExecutor(setExecutor); } // 获取新的srcRef // 获取get结果 ValueProcessInvocation invocation = new ValueProcessInvocation(getExecutor, setExecutor, valueContext, param.getProcesses()); Object srcRef = invocation.getInitialValue(); // 设置下srcClass Class getResultClass = (srcRef != null) ? srcRef.getClass() : null; // 设置下srcClass if (getExecutor != null && beanField.getSrcField().getClazz() == null) { beanField.getSrcField().setClazz( Uberspector.getInstance().getGetClass(getExecutor, param.getSrcRef().getClass(), getResultClass)); } if (setExecutor != null && beanField.getTargetField().getClazz() == null) { beanField.getTargetField().setClazz( Uberspector.getInstance().getSetClass(setExecutor, param.getTargetRef().getClass(), getResultClass)); if (setExecutor instanceof MapSetExecutor) { beanField.getTargetField().setClazz(HashMap.class);// 注意这里强制传递为HashMap.class } } // 执行set,反射构造一个子Model // 如果嵌套对象为null,则直接略过该对象处理,目标对象也为null,此时srcRef可能为null Object value = invocation.proceed(srcRef); // 在目标节点对象上,创建一个子节点 if (srcRef == null && value == null) { return; // 如果为null,则不做递归处理 } if (beanField.getSrcField().getClazz() == null || beanField.getTargetField().getClazz() == null) { throw new BeanMappingException("srcClass or targetClass is null , " + beanField.toString()); } // change for v1.0.2 BeanMappingObject object = beanField.getNestObject(); if (object == null) { if (StringUtils.isNotEmpty(beanField.getNestName())) { object = BeanMappingConfigHelper.getInstance().getBeanMappingObject(beanField.getNestName()); } else { object = BeanMappingConfigHelper.getInstance().getBeanMappingObject( beanField.getSrcField().getClazz(), beanField.getTargetField().getClazz()); } beanField.setNestObject(object);// cache一下结果 } if (object == null) { throw new BeanMappingException("no bean mapping config for " + beanField.toString()); } BeanMappingParam newParam = new BeanMappingParam(); newParam.setTargetRef(value);// 为新创建的子model,注意使用value,可以在SetValueProcess中会创建新对象 newParam.setSrcRef(srcRef); newParam.setConfig(object); // 复制并传递 newParam.setProcesses(param.getProcesses()); // 进行递归调用 execute(newParam); } /** * 判断一下是否可以执行batch优化 */ private static boolean canBatch(BeanMappingBehavior behavior) { return behavior.isMappingEmptyStrings() && behavior.isMappingNullValue(); } }