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();
}
}