package com.alibaba.tamper.core.config;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import com.alibaba.tamper.core.builder.BeanMappingBuilder;
/**
* Bean Mapping配置操作的相关helper类
*
* @author jianghang 2011-5-28 上午11:00:34
*/
public class BeanMappingConfigHelper {
private static volatile BeanMappingConfigHelper singleton = null;
private BeanMappingConfigRespository repository = null; // 基于文件的配置
private BeanMappingConfigRespository autoRepository = null; // 自动注册的配置
private volatile BeanMappingBehavior globalBehavior = null; // 定义为voolatile,允许动态修改
public BeanMappingConfigHelper(){
repository = new BeanMappingConfigRespository();
autoRepository = new BeanMappingConfigRespository();
globalBehavior = new BeanMappingBehavior();
}
public BeanMappingConfigHelper(BeanMappingConfigRespository repository){
// 允许传入自定义仓库
this.repository = repository;
autoRepository = new BeanMappingConfigRespository();
globalBehavior = new BeanMappingBehavior();
}
/**
* 单例方法
*/
public static BeanMappingConfigHelper getInstance() {
if (singleton == null) {
synchronized (BeanMappingConfigHelper.class) {
if (singleton == null) { // double check
singleton = new BeanMappingConfigHelper();
}
}
}
return singleton;
}
/**
* 根据class查找对应的{@linkplain BeanMappingObject}
*/
public BeanMappingObject getBeanMappingObject(Class src, Class target) {
return getFromRepository(src, target, this.repository);
}
/**
* 根据name查找对应的{@linkplain BeanMappingObject}
*/
public BeanMappingObject getBeanMappingObject(String name) {
return repository.getBeanMappingObject(name);
}
/**
* 根据class查找对应的{@linkplain BeanMappingObject},如果不存在则进行自动注册
*/
public BeanMappingObject getBeanMappingObject(Class src, Class target, boolean autoRegister) {
BeanMappingObject object = autoRepository.getBeanMappingObject(src, target);
if (object == null && autoRegister) {
autoRepository.register(src, target);
object = getFromRepository(src, target, this.autoRepository);
}
return object;
}
/**
* 根据class查找对应的{@linkplain BeanMappingObject},如果不存在则进行自动注册
*/
public BeanMappingObject getBeanMapObject(Class src, Class target, boolean autoRegister) {
BeanMappingObject object = autoRepository.getBeanMappingObject(src, target);
if (object == null && autoRegister) {
if (isMap(src)) {// 判断是否为map接口的子类
autoRepository.registerMap(target);
} else {
autoRepository.registerMap(src);
}
object = getFromRepository(src, target, this.autoRepository);
}
return object;
}
/**
* 直接注册一个解析好的{@linkplain BeanMappingObject}
*/
public void register(BeanMappingObject object) {
repository.register(object);
}
/**
* 直接注册一个解析好的{@linkplain BeanMappingBuilder}
*/
public void register(BeanMappingBuilder builder) {
repository.register(builder);
}
public void registerConfig(String file) {
InputStream in = null;
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl == null) {
cl = BeanMappingConfigRespository.class.getClassLoader();
}
in = cl.getResourceAsStream(file);
// 自己打开的文件需要关闭
try {
repository.registerConfig(in);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// ignore
}
}
}
}
public void registerConfig(InputStream in) {
repository.registerConfig(in);
}
// ======================== helper method ======================
/**
* @param src
* @param target
* @return
*/
private BeanMappingObject getFromRepository(Class src, Class target, BeanMappingConfigRespository repository) {
BeanMappingObject object = repository.getBeanMappingObject(src, target);
if (object == null) { // 再尝试一下map接口的处理
boolean isSrcMap = isMap(src);
boolean isTargetMap = isMap(target);
if (isSrcMap && isTargetMap) {
object = repository.getBeanMappingObject(Map.class, Map.class);
} else if (isSrcMap) {
object = repository.getBeanMappingObject(Map.class, target);
} else if (isMap(target)) {
object = repository.getBeanMappingObject(src, Map.class);
}
}
return object;
}
private boolean isMap(Class clazz) {
return clazz != null && Map.class.isAssignableFrom(clazz);
}
// ========================= setter / getter ===================
public void setRepository(BeanMappingConfigRespository repository) {
this.repository = repository;
}
public BeanMappingBehavior getGlobalBehavior() {
return globalBehavior;
}
public void setGlobalBehavior(BeanMappingBehavior globalBehavior) {
this.globalBehavior = globalBehavior;
}
}