package com.alibaba.tamper;
import java.util.List;
import com.alibaba.tamper.core.BeanMappingException;
import com.alibaba.tamper.core.BeanMappingExecutor;
import com.alibaba.tamper.core.BeanMappingParam;
import com.alibaba.tamper.core.builder.BeanMappingBuilder;
import com.alibaba.tamper.core.config.BeanMappingConfigHelper;
import com.alibaba.tamper.core.config.BeanMappingEnvironment;
import com.alibaba.tamper.core.config.BeanMappingObject;
import com.alibaba.tamper.core.helper.ContextObjectHolder;
import com.alibaba.tamper.core.process.ValueProcess;
import com.alibaba.tamper.process.script.ScriptHelper;
/**
* Bean Mapping操作的处理单元
*
* <pre>
* <code>
* 使用例子:
* BeanMapping beanMapping = BeanMapping.create(srcClass,targetClass);
* beanMapping.mapping(src,target);// 将src的属性mapping到target
*
* 注意:srcClass/targetClass的映射关系必须实现通过{@linkplain BeanMappingConfigHelper}的registerConfig方法注册mapping配置
* </code>
*
* changelog
* v1.0.2
* mapping执行会有context的概念,缓存一下当前的一些执行信息
* </pre>
*
* @author jianghang 2011-6-8 上午11:10:24
*/
public class BeanMapping {
private BeanMappingObject config; // 对应的Bean Mapping配置
public BeanMapping(BeanMappingObject config){
this.config = config;
}
public BeanMapping(BeanMappingBuilder builder){
this.config = builder.get();
}
/**
* 创建指定name的BeanMapping操作
*/
public static BeanMapping create(String mappingName) {
BeanMappingObject config = BeanMappingConfigHelper.getInstance().getBeanMappingObject(mappingName);
if (config == null) {
throw new BeanMappingException("can not found mapping config for name[" + mappingName + "]");
}
return new BeanMapping(config);
}
/**
* 创建srcClass和targetClass之间的BeanMapping操作
*/
public static BeanMapping create(Class srcClass, Class targetClass) {
BeanMappingObject config = BeanMappingConfigHelper.getInstance().getBeanMappingObject(srcClass, targetClass);
if (config == null) {
throw new BeanMappingException("can not found mapping config for srcClass[" + srcClass.toString()
+ "] targetClass[" + targetClass + "]");
}
return new BeanMapping(config);
}
/**
* 根据定义的bean-mapping配置进行对象属性的mapping拷贝 , 允许自定义{@linkplain ValueProcess} {@linkplain SetValueProcess}
*
* @param src
* @param target
* @throws BeanMappingException
*/
public void mapping(Object src, Object target) throws BeanMappingException {
boolean first = ContextObjectHolder.getInstance().enter();
boolean isBeanMappingSupportScript = BeanMappingEnvironment.isBeanMappingSupportScript();
BeanMappingParam param = new BeanMappingParam();
param.setSrcRef(src);
param.setTargetRef(target);
param.setConfig(this.config);
List<ValueProcess> vps = BeanMappingEnvironment.getBeanMappingVps();
param.setProcesses(vps);
// 执行mapping处理
try {
BeanMappingExecutor.execute(param);
} finally {
if (first) {// 第一个进入的负责清空数据,可能存在递归调用处理
ContextObjectHolder.getInstance().clear();
if (isBeanMappingSupportScript) {
ScriptHelper.getInstance().getScriptExecutor().disposeFunctions();// 清空记录
}
}
}
}
}