├── .gitignore
├── CHANGES.txt
├── LICENSE.txt
├── README.md
├── pom.xml
└── src
├── main
├── java
│ └── com
│ │ └── alibaba
│ │ └── tamper
│ │ ├── BeanCopy.java
│ │ ├── BeanMap.java
│ │ ├── BeanMapping.java
│ │ ├── BeanMappingUtil.java
│ │ ├── core
│ │ ├── BeanMappingException.java
│ │ ├── BeanMappingExecutor.java
│ │ ├── BeanMappingParam.java
│ │ ├── builder
│ │ │ ├── BeanMappingBuilder.java
│ │ │ ├── Builder.java
│ │ │ └── impl
│ │ │ │ ├── BeanMappingBehaviorBuilder.java
│ │ │ │ ├── BeanMappingFieldAttributesBuilder.java
│ │ │ │ ├── BeanMappingFieldBuilder.java
│ │ │ │ └── BeanMappingObjectBuilder.java
│ │ ├── config
│ │ │ ├── BeanMappingBehavior.java
│ │ │ ├── BeanMappingConfigHelper.java
│ │ │ ├── BeanMappingConfigRespository.java
│ │ │ ├── BeanMappingEnvironment.java
│ │ │ ├── BeanMappingField.java
│ │ │ ├── BeanMappingFieldAttributes.java
│ │ │ ├── BeanMappingObject.java
│ │ │ └── parse
│ │ │ │ ├── BeanMappingBehaviorParse.java
│ │ │ │ ├── BeanMappingParse.java
│ │ │ │ ├── BeanMappingParser.java
│ │ │ │ ├── ClassAliasParse.java
│ │ │ │ ├── ConvertorParse.java
│ │ │ │ └── FunctionClassParse.java
│ │ ├── helper
│ │ │ ├── BatchObjectHolder.java
│ │ │ ├── ContextObjectHolder.java
│ │ │ ├── ReflectionHelper.java
│ │ │ └── XmlHelper.java
│ │ ├── introspect
│ │ │ ├── AbstractBatchExecutor.java
│ │ │ ├── AbstractExecutor.java
│ │ │ ├── BatchExecutor.java
│ │ │ ├── FastPropertyGetExecutor.java
│ │ │ ├── FastPropertySetExecutor.java
│ │ │ ├── FieldGetExecutor.java
│ │ │ ├── FieldSetExecutor.java
│ │ │ ├── GetExecutor.java
│ │ │ ├── Introspector.java
│ │ │ ├── MapBatchExecutor.java
│ │ │ ├── MapGetExecutor.java
│ │ │ ├── MapSetExecutor.java
│ │ │ ├── NullSymbolGetExecutor.java
│ │ │ ├── PropertyBatchExecutor.java
│ │ │ ├── PropertyGetExecutor.java
│ │ │ ├── PropertySetExecutor.java
│ │ │ ├── SetExecutor.java
│ │ │ ├── ThisSymbolGetExecutor.java
│ │ │ ├── Uberspect.java
│ │ │ ├── UberspectImpl.java
│ │ │ └── Uberspector.java
│ │ └── process
│ │ │ ├── ValueProcess.java
│ │ │ ├── ValueProcessContext.java
│ │ │ └── ValueProcessInvocation.java
│ │ └── process
│ │ ├── BeanCreatorValueProcess.java
│ │ ├── BehaviorValueProcess.java
│ │ ├── ConvertorValueProcess.java
│ │ ├── DebugValueProcess.java
│ │ ├── DefaultValueValueProcess.java
│ │ ├── ScriptValueProcess.java
│ │ ├── convertor
│ │ ├── AbastactConvertor.java
│ │ ├── CollectionAndCollectionConvertor.java
│ │ ├── CollectionConvertor.java
│ │ ├── CommonAndCommonConvertor.java
│ │ ├── Convertor.java
│ │ ├── ConvertorHelper.java
│ │ ├── ConvertorRepository.java
│ │ ├── SqlDateAndDateConvertor.java
│ │ ├── StringAndCommonConvertor.java
│ │ ├── StringAndDateConvertor.java
│ │ ├── StringAndEnumConvertor.java
│ │ └── StringAndObjectConvertor.java
│ │ └── script
│ │ ├── ScriptContext.java
│ │ ├── ScriptExecutor.java
│ │ ├── ScriptHelper.java
│ │ ├── jexl
│ │ └── JexlScriptExecutor.java
│ │ └── lifecyle
│ │ ├── DisposableScript.java
│ │ └── InitializingScript.java
└── resources
│ ├── META-INF
│ └── mapping.xsd
│ └── mapping.properties
└── test
├── java
└── com
│ └── alibaba
│ └── tamper
│ ├── BeanCopyTest.java
│ ├── BeanMapTest.java
│ ├── BeanMappingDymaicTest.java
│ ├── BeanMappingNestAndNameTest.java
│ ├── BeanMappingTest.java
│ ├── ConfigTest.java
│ ├── InheritObjectMappingTest.java
│ ├── TestUtils.java
│ ├── builder
│ └── BeanMappingBuilderTest.java
│ ├── convertor
│ ├── CollectionAndCollectionTest.java
│ ├── CommonAndCommonTest.java
│ ├── ConvertorModel.java
│ ├── ConvertorOtherModel.java
│ ├── DateAndSqlDateTest.java
│ ├── StringAndEnumTest.java
│ └── StringConvertorTest.java
│ ├── object
│ ├── NestedSrcMappingObject.java
│ ├── NestedTargetMappingObject.java
│ ├── SrcMappingObject.java
│ ├── TargetMappingObject.java
│ └── inherit
│ │ ├── FirstObject.java
│ │ └── TwoObject.java
│ ├── performace
│ ├── AbstractPerformance.java
│ ├── CopyBean.java
│ ├── CopyPerformance.java
│ └── MapPerformance.java
│ └── script
│ ├── CustomFunctionClass.java
│ ├── CustomFunctionTest.java
│ ├── ScriptExecutorTest.java
│ └── ScriptTest.java
└── resources
├── META-INF
└── services
│ └── BeanMapping.Script.Executor
├── log4j.xml
└── mapping
├── config.xml
├── mapping.xml
└── script-mapping.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | .project
2 | .classpath
3 | target
4 | classes
5 | tmp
6 | temp
7 | *.log*
8 | .settings
9 | antx.properties
10 | test-output
11 | bin
12 | docs
13 |
--------------------------------------------------------------------------------
/CHANGES.txt:
--------------------------------------------------------------------------------
1 | Release 1.0.2
2 | convetor包名重构,拼写错误
3 | ScriptExecutor接口重构,加上ScriptContext操作
4 | FiledSetExecutor去除对args的强制匹配依赖
5 | mapping支持name定义
6 | mapping支持嵌套映射/集合映射对象的name定义
7 | 增加NullSymbolGetExecutor的实现,支持无源属性的映射
8 |
9 | Release 1.0.1
10 | "this" symbol GetExecutor bugfix
11 | boolean isSuccessed generated set/get methods for the isSucessed()/setSuccessed(), should filter attribute is the prefix
12 | Add date and sqlDate convertor
13 | Add String and Enum convertor
14 | Add mapping.propertis define ValueProcess plugins
15 |
16 | Release 1.0.0
17 | Initial mapping code
18 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/BeanCopy.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper;
2 |
3 | import com.alibaba.tamper.core.BeanMappingException;
4 | import com.alibaba.tamper.core.BeanMappingExecutor;
5 | import com.alibaba.tamper.core.BeanMappingParam;
6 | import com.alibaba.tamper.core.config.BeanMappingConfigHelper;
7 | import com.alibaba.tamper.core.config.BeanMappingEnvironment;
8 | import com.alibaba.tamper.core.config.BeanMappingObject;
9 |
10 | /**
11 | * Bean copy操作的处理单元
12 | *
13 | *
14 | *
15 | * 使用例子:
16 | * BeanCopy beanCopy = BeanCopy.create(srcClass , targetClass);
17 | * beanCopy.copy(src,target);//完成copy动作
18 | *
19 | *
20 | *
21 | * @author jianghang 2011-6-8 上午11:10:47
22 | */
23 | public class BeanCopy {
24 |
25 | private BeanMappingObject config; // 对应的Bean Mapping配置
26 |
27 | BeanCopy(BeanMappingObject config){
28 | this.config = config;
29 | }
30 |
31 | /**
32 | * 创建srcClass和targetClass之间的BeanCopy操作
33 | */
34 | public static BeanCopy create(Class srcClass, Class targetClass) {
35 | BeanMappingObject config = BeanMappingConfigHelper.getInstance().getBeanMappingObject(srcClass, targetClass,
36 | true);
37 | return new BeanCopy(config);
38 | }
39 |
40 | /**
41 | * 对象属性的拷贝,与BeanUtils , BeanCopier功能类似
42 | *
43 | * @param src
44 | * @param target
45 | * @throws BeanMappingException
46 | */
47 | public void copy(Object src, Object target) throws BeanMappingException {
48 | BeanMappingParam param = new BeanMappingParam();
49 | param.setSrcRef(src);
50 | param.setTargetRef(target);
51 | param.setConfig(this.config);
52 | param.setProcesses(BeanMappingEnvironment.getBeanCopyVps());
53 |
54 | // 执行mapping处理
55 | BeanMappingExecutor.execute(param);
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/BeanMap.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import com.alibaba.tamper.core.BeanMappingException;
7 | import com.alibaba.tamper.core.BeanMappingExecutor;
8 | import com.alibaba.tamper.core.BeanMappingParam;
9 | import com.alibaba.tamper.core.config.BeanMappingConfigHelper;
10 | import com.alibaba.tamper.core.config.BeanMappingEnvironment;
11 | import com.alibaba.tamper.core.config.BeanMappingObject;
12 |
13 | /**
14 | * Bean<->Map操作的处理单元
15 | *
16 | *
17 | *
18 | * 使用例子:
19 | * BeanMap beanMap = BeanMap.create(srcClass);
20 | * Map properties = beanMap.describe(src);// 将bean的属性设置到map对象上
21 | * beanMap.populate(src,properties); // 将map对象数据设置到bean的属性上
22 | *
23 | *
24 | *
25 | * TODO : 后期支持单个属性的put/get操作
26 | *
27 | * @author jianghang 2011-6-8 上午11:11:13
28 | */
29 | public class BeanMap {
30 |
31 | private BeanMappingObject describeConfig; // 对应的Bean Mapping配置
32 | private BeanMappingObject populateConfig; // 对应的Bean Mapping配置
33 |
34 | BeanMap(BeanMappingObject describeConfig, BeanMappingObject populateConfig){
35 | this.describeConfig = describeConfig;
36 | this.populateConfig = populateConfig;
37 | }
38 |
39 | /**
40 | * 创建srcClass和targetClass之间的BeanMapping操作
41 | */
42 | public static BeanMap create(Class srcClass) {
43 | BeanMappingObject describeConfig = BeanMappingConfigHelper.getInstance().getBeanMapObject(srcClass, Map.class,
44 | true);
45 |
46 | BeanMappingObject populateConfig = BeanMappingConfigHelper.getInstance().getBeanMapObject(Map.class, srcClass,
47 | true);
48 | return new BeanMap(describeConfig, populateConfig);
49 | }
50 |
51 | /**
52 | * 将bean的属性转化为Map对象
53 | *
54 | * @param src
55 | * @return
56 | * @throws BeanMappingException
57 | */
58 | public Map describe(Object src) throws BeanMappingException {
59 | Map result = new HashMap();
60 | BeanMappingParam param = new BeanMappingParam();
61 | param.setSrcRef(src);
62 | param.setTargetRef(result);
63 | param.setConfig(this.describeConfig);
64 | param.setProcesses(BeanMappingEnvironment.getBeanMapVps());
65 | // 执行mapping处理
66 | BeanMappingExecutor.execute(param);
67 | return result;
68 | }
69 |
70 | /**
71 | * 将map的属性映射到bean对象
72 | *
73 | * @param target
74 | * @param properties
75 | * @throws BeanMappingException
76 | */
77 | public void populate(Object target, Map properties) throws BeanMappingException {
78 | BeanMappingParam param = new BeanMappingParam();
79 | param.setSrcRef(properties);
80 | param.setTargetRef(target);
81 | param.setConfig(this.populateConfig);
82 | param.setProcesses(BeanMappingEnvironment.getBeanMapVps());
83 | // 执行mapping处理
84 | BeanMappingExecutor.execute(param);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/BeanMapping.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper;
2 |
3 | import java.util.List;
4 |
5 | import com.alibaba.tamper.core.BeanMappingException;
6 | import com.alibaba.tamper.core.BeanMappingExecutor;
7 | import com.alibaba.tamper.core.BeanMappingParam;
8 | import com.alibaba.tamper.core.builder.BeanMappingBuilder;
9 | import com.alibaba.tamper.core.config.BeanMappingConfigHelper;
10 | import com.alibaba.tamper.core.config.BeanMappingEnvironment;
11 | import com.alibaba.tamper.core.config.BeanMappingObject;
12 | import com.alibaba.tamper.core.helper.ContextObjectHolder;
13 | import com.alibaba.tamper.core.process.ValueProcess;
14 | import com.alibaba.tamper.process.script.ScriptHelper;
15 |
16 | /**
17 | * Bean Mapping操作的处理单元
18 | *
19 | *
20 | *
21 | * 使用例子:
22 | * BeanMapping beanMapping = BeanMapping.create(srcClass,targetClass);
23 | * beanMapping.mapping(src,target);// 将src的属性mapping到target
24 | *
25 | * 注意:srcClass/targetClass的映射关系必须实现通过{@linkplain BeanMappingConfigHelper}的registerConfig方法注册mapping配置
26 | *
27 | *
28 | * changelog
29 | * v1.0.2
30 | * mapping执行会有context的概念,缓存一下当前的一些执行信息
31 | *
32 | *
33 | * @author jianghang 2011-6-8 上午11:10:24
34 | */
35 | public class BeanMapping {
36 |
37 | private BeanMappingObject config; // 对应的Bean Mapping配置
38 |
39 | public BeanMapping(BeanMappingObject config){
40 | this.config = config;
41 | }
42 |
43 | public BeanMapping(BeanMappingBuilder builder){
44 | this.config = builder.get();
45 | }
46 |
47 | /**
48 | * 创建指定name的BeanMapping操作
49 | */
50 | public static BeanMapping create(String mappingName) {
51 | BeanMappingObject config = BeanMappingConfigHelper.getInstance().getBeanMappingObject(mappingName);
52 | if (config == null) {
53 | throw new BeanMappingException("can not found mapping config for name[" + mappingName + "]");
54 | }
55 |
56 | return new BeanMapping(config);
57 | }
58 |
59 | /**
60 | * 创建srcClass和targetClass之间的BeanMapping操作
61 | */
62 | public static BeanMapping create(Class srcClass, Class targetClass) {
63 | BeanMappingObject config = BeanMappingConfigHelper.getInstance().getBeanMappingObject(srcClass, targetClass);
64 | if (config == null) {
65 | throw new BeanMappingException("can not found mapping config for srcClass[" + srcClass.toString()
66 | + "] targetClass[" + targetClass + "]");
67 | }
68 |
69 | return new BeanMapping(config);
70 | }
71 |
72 | /**
73 | * 根据定义的bean-mapping配置进行对象属性的mapping拷贝 , 允许自定义{@linkplain ValueProcess} {@linkplain SetValueProcess}
74 | *
75 | * @param src
76 | * @param target
77 | * @throws BeanMappingException
78 | */
79 | public void mapping(Object src, Object target) throws BeanMappingException {
80 | boolean first = ContextObjectHolder.getInstance().enter();
81 | boolean isBeanMappingSupportScript = BeanMappingEnvironment.isBeanMappingSupportScript();
82 | BeanMappingParam param = new BeanMappingParam();
83 | param.setSrcRef(src);
84 | param.setTargetRef(target);
85 | param.setConfig(this.config);
86 | List vps = BeanMappingEnvironment.getBeanMappingVps();
87 | param.setProcesses(vps);
88 |
89 | // 执行mapping处理
90 | try {
91 | BeanMappingExecutor.execute(param);
92 | } finally {
93 | if (first) {// 第一个进入的负责清空数据,可能存在递归调用处理
94 | ContextObjectHolder.getInstance().clear();
95 | if (isBeanMappingSupportScript) {
96 | ScriptHelper.getInstance().getScriptExecutor().disposeFunctions();// 清空记录
97 | }
98 | }
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/BeanMappingUtil.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper;
2 |
3 | import java.util.Map;
4 |
5 | import com.alibaba.tamper.core.BeanMappingException;
6 |
7 | /**
8 | * Bean mapping处理的一些常用方法
9 | *
10 | * @author jianghang 2011-5-27 下午12:27:12
11 | */
12 | public class BeanMappingUtil {
13 |
14 | /**
15 | * 根据定义的bean-mapping配置进行对象属性的mapping拷贝
16 | *
17 | * @param src
18 | * @param target
19 | */
20 | public static void mapping(Object src, Object target) throws BeanMappingException {
21 | BeanMapping mapping = BeanMapping.create(src.getClass(), target.getClass());
22 | mapping.mapping(src, target);
23 | }
24 |
25 | /**
26 | * 对象属性的拷贝,与BeanUtils , BeanCopier功能类似
27 | *
28 | * @param src
29 | * @param target
30 | */
31 | public static void copy(Object src, Object target) throws BeanMappingException {
32 | BeanCopy copy = BeanCopy.create(src.getClass(), target.getClass());
33 | copy.copy(src, target);
34 | }
35 |
36 | /**
37 | *将bean的属性转化为Map对象
38 | *
39 | * @param src
40 | * @return
41 | * @throws BeanMappingException
42 | */
43 | public static Map describe(Object src) throws BeanMappingException {
44 | BeanMap map = BeanMap.create(src.getClass());
45 | return map.describe(src);
46 | }
47 |
48 | /**
49 | * 将map的属性映射到bean对象
50 | *
51 | * @param target
52 | * @param properties
53 | * @throws BeanMappingException
54 | */
55 | public static void populate(Object target, Map properties) throws BeanMappingException {
56 | BeanMap map = BeanMap.create(target.getClass());
57 | map.populate(target, properties);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/BeanMappingException.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core;
2 |
3 | import org.apache.commons.lang.exception.NestableRuntimeException;
4 |
5 | /**
6 | * @author jianghang 2011-5-25 上午11:23:59
7 | */
8 | public class BeanMappingException extends NestableRuntimeException {
9 |
10 | private static final long serialVersionUID = -4176128184885659405L;
11 |
12 | public BeanMappingException(){
13 | super();
14 | }
15 |
16 | public BeanMappingException(String message, Throwable cause){
17 | super(message, cause);
18 | }
19 |
20 | public BeanMappingException(String message){
21 | super(message);
22 | }
23 |
24 | public BeanMappingException(Throwable cause){
25 | super(cause);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/BeanMappingParam.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core;
2 |
3 | import java.io.Serializable;
4 | import java.util.HashMap;
5 | import java.util.List;
6 | import java.util.Map;
7 |
8 | import org.apache.commons.lang.builder.ToStringBuilder;
9 | import org.apache.commons.lang.builder.ToStringStyle;
10 |
11 | import com.alibaba.tamper.core.config.BeanMappingObject;
12 | import com.alibaba.tamper.core.process.ValueProcess;
13 |
14 | /**
15 | * bean mapping传递的参数
16 | *
17 | * @author jianghang 2011-5-26 下午06:39:29
18 | */
19 | public class BeanMappingParam implements Serializable {
20 |
21 | private static final long serialVersionUID = 2371233083866029415L;
22 | private Object srcRef; // 待转化src
23 | private Object targetRef; // 转化的目标dest
24 | private BeanMappingObject config; // bean mapping相关配置
25 |
26 | // =========================== ValueProcess 扩展参数==============================
27 | private List processes; // 自定义的valueProcess
28 | private Map customValueContext = new HashMap(); // 自定义的valueProcess上下文处理
29 |
30 | public Object getSrcRef() {
31 | return srcRef;
32 | }
33 |
34 | public void setSrcRef(Object srcRef) {
35 | this.srcRef = srcRef;
36 | }
37 |
38 | public Object getTargetRef() {
39 | return targetRef;
40 | }
41 |
42 | public void setTargetRef(Object targetRef) {
43 | this.targetRef = targetRef;
44 | }
45 |
46 | public BeanMappingObject getConfig() {
47 | return config;
48 | }
49 |
50 | public void setConfig(BeanMappingObject config) {
51 | this.config = config;
52 | }
53 |
54 | public Map getCustomValueContext() {
55 | return customValueContext;
56 | }
57 |
58 | public void setCustomValueContext(Map customValueContext) {
59 | this.customValueContext = customValueContext;
60 | }
61 |
62 | public List getProcesses() {
63 | return processes;
64 | }
65 |
66 | public void setProcesses(List processes) {
67 | this.processes = processes;
68 | }
69 |
70 | @Override
71 | public String toString() {
72 | return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/builder/BeanMappingBuilder.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.builder;
2 |
3 | import com.alibaba.tamper.core.builder.impl.BeanMappingBehaviorBuilder;
4 | import com.alibaba.tamper.core.builder.impl.BeanMappingFieldAttributesBuilder;
5 | import com.alibaba.tamper.core.builder.impl.BeanMappingFieldBuilder;
6 | import com.alibaba.tamper.core.builder.impl.BeanMappingObjectBuilder;
7 | import com.alibaba.tamper.core.config.BeanMappingBehavior;
8 | import com.alibaba.tamper.core.config.BeanMappingConfigHelper;
9 | import com.alibaba.tamper.core.config.BeanMappingConfigRespository;
10 | import com.alibaba.tamper.core.config.BeanMappingObject;
11 |
12 | /**
13 | * mapping对象的构造器, 可直接注册到{@linkplain BeanMappingConfigRespository}
14 | *
15 | *
16 | * BeanMappingConfigRespository.register(BeanMappingBuilder);
17 | *
18 | *
19 | * @author jianghang 2011-6-22 上午10:31:35
20 | */
21 | public class BeanMappingBuilder implements Builder {
22 |
23 | private BeanMappingObject object;
24 | private BeanMappingBehavior global = BeanMappingConfigHelper.getInstance().getGlobalBehavior();
25 |
26 | public BeanMappingBuilder(){
27 | configure();
28 | }
29 |
30 | protected void configure() {
31 | // 需要客户端实现
32 | }
33 |
34 | public BeanMappingObjectBuilder mapping(String name, Class srcClass, Class targetClass) {
35 | BeanMappingObjectBuilder builder = new BeanMappingObjectBuilder(name, srcClass, targetClass, global);
36 | object = builder.get();
37 | return builder;
38 | }
39 |
40 | public BeanMappingObjectBuilder mapping(Class srcClass, Class targetClass) {
41 | BeanMappingObjectBuilder builder = new BeanMappingObjectBuilder(srcClass, targetClass, global);
42 | object = builder.get();
43 | return builder;
44 | }
45 |
46 | public BeanMappingFieldBuilder fields(BeanMappingFieldAttributesBuilder srcFieldBuilder,
47 | BeanMappingFieldAttributesBuilder targetFieldBuilder) {
48 | BeanMappingFieldBuilder fieldCriterion = new BeanMappingFieldBuilder(srcFieldBuilder, targetFieldBuilder,
49 | this.object.getBehavior());
50 | this.object.addBeanField(fieldCriterion.get());
51 | return fieldCriterion;
52 | }
53 |
54 | public BeanMappingBehaviorBuilder behavior() {
55 | BeanMappingBehaviorBuilder builder = new BeanMappingBehaviorBuilder();
56 | global = builder.get();
57 | return builder;
58 |
59 | }
60 |
61 | public BeanMappingBehaviorBuilder behavior(boolean debug, boolean mappingNullValue, boolean mappingEmptyStrings,
62 | boolean trimStrings) {
63 | BeanMappingBehaviorBuilder builder = new BeanMappingBehaviorBuilder(debug, mappingNullValue,
64 | mappingEmptyStrings, trimStrings);
65 | global = builder.get();
66 | return builder;
67 |
68 | }
69 |
70 | public BeanMappingFieldAttributesBuilder srcField(String name) {
71 | return new BeanMappingFieldAttributesBuilder(name);
72 | }
73 |
74 | public BeanMappingFieldAttributesBuilder srcField(String name, Class clazz) {
75 | return new BeanMappingFieldAttributesBuilder(name, clazz);
76 | }
77 |
78 | public BeanMappingFieldAttributesBuilder targetField(String name) {
79 | return new BeanMappingFieldAttributesBuilder(name);
80 | }
81 |
82 | public BeanMappingFieldAttributesBuilder targetField(String name, Class clazz) {
83 | return new BeanMappingFieldAttributesBuilder(name, clazz);
84 | }
85 |
86 | @Override
87 | public BeanMappingObject get() {
88 | return object;
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/builder/Builder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 1999-2004 Alibaba.com All right reserved. This software is the confidential and proprietary information of
3 | * Alibaba.com ("Confidential Information"). You shall not disclose such Confidential Information and shall use it only
4 | * in accordance with the terms of the license agreement you entered into with Alibaba.com.
5 | */
6 | package com.alibaba.tamper.core.builder;
7 |
8 | /**
9 | * 定义builder的接口
10 | *
11 | * @author jianghang 2011-6-22 下午12:20:15
12 | */
13 | public interface Builder {
14 |
15 | public T get();
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/builder/impl/BeanMappingBehaviorBuilder.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.builder.impl;
2 |
3 | import com.alibaba.tamper.core.builder.Builder;
4 | import com.alibaba.tamper.core.config.BeanMappingBehavior;
5 |
6 | /**
7 | * {@linkplain BeanMappingBehavior}构造器
8 | *
9 | * @author jianghang 2011-6-22 下午12:47:50
10 | */
11 | public class BeanMappingBehaviorBuilder implements Builder {
12 |
13 | private BeanMappingBehavior behavior;
14 |
15 | public BeanMappingBehaviorBuilder(){
16 | this.behavior = new BeanMappingBehavior();
17 | }
18 |
19 | public BeanMappingBehaviorBuilder(boolean debug, boolean mappingNullValue, boolean mappingEmptyStrings,
20 | boolean trimStrings){
21 | this.behavior = new BeanMappingBehavior();
22 | behavior.setDebug(debug);
23 | behavior.setMappingNullValue(mappingNullValue);
24 | behavior.setMappingEmptyStrings(mappingEmptyStrings);
25 | behavior.setTrimStrings(trimStrings);
26 | }
27 |
28 | public BeanMappingBehaviorBuilder debug(boolean debug) {
29 | behavior.setDebug(debug);
30 | return this;
31 | }
32 |
33 | public BeanMappingBehaviorBuilder mappingNullValue(boolean mappingNullValue) {
34 | behavior.setMappingNullValue(mappingNullValue);
35 | return this;
36 | }
37 |
38 | public BeanMappingBehaviorBuilder mappingEmptyStrings(boolean mappingEmptyStrings) {
39 | behavior.setMappingEmptyStrings(mappingEmptyStrings);
40 | return this;
41 | }
42 |
43 | public BeanMappingBehaviorBuilder trimStrings(boolean trimStrings) {
44 | behavior.setTrimStrings(trimStrings);
45 | return this;
46 | }
47 |
48 | @Override
49 | public BeanMappingBehavior get() {
50 | return behavior;
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/builder/impl/BeanMappingFieldAttributesBuilder.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.builder.impl;
2 |
3 | import java.util.Arrays;
4 |
5 | import com.alibaba.tamper.core.builder.Builder;
6 | import com.alibaba.tamper.core.config.BeanMappingFieldAttributes;
7 |
8 | /**
9 | * {@linkplain BeanMappingFieldAttributes} 构造器
10 | *
11 | * @author jianghang 2011-6-22 上午10:44:13
12 | */
13 | public class BeanMappingFieldAttributesBuilder implements Builder {
14 |
15 | private BeanMappingFieldAttributes attributes;
16 |
17 | public BeanMappingFieldAttributesBuilder(String name){
18 | this(name, null);
19 | }
20 |
21 | public BeanMappingFieldAttributesBuilder(String name, Class clazz){
22 | attributes = new BeanMappingFieldAttributes();
23 | attributes.setName(name);
24 | attributes.setClazz(clazz);
25 | }
26 |
27 | /**
28 | * 设置属性对应的class对象
29 | */
30 | public BeanMappingFieldAttributesBuilder clazz(Class clazz) {
31 | attributes.setClazz(clazz);
32 | return this;
33 | }
34 |
35 | /**
36 | * 设置查找对应属性的目标class,默认会以mapping中定义的class进行查找
37 | *
38 | * 针对存在子父属性进行mapping时,可设置此locatorClass进行区分
39 | */
40 | public BeanMappingFieldAttributesBuilder locatorClass(Class locatorClass) {
41 | attributes.setLocatorClass(locatorClass);
42 | return this;
43 | }
44 |
45 | /**
46 | * 针对Collection的属性,可以设置嵌套的内部对象类型
47 | *
48 | *
49 | * 针对嵌套处理说明: 比如List<Set<List<Model>>>,
50 | * 此时对应的componentClasses存在3个Class,分别为Set.class(第一层),List.class(第二层),Model.class(第三层)
51 | *
52 | *
53 | */
54 | public BeanMappingFieldAttributesBuilder componentClasses(Class... componentClasses) {
55 | attributes.setComponentClasses(Arrays.asList(componentClasses));
56 | return this;
57 | }
58 |
59 | public BeanMappingFieldAttributes get() {
60 | return attributes;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/builder/impl/BeanMappingFieldBuilder.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.builder.impl;
2 |
3 | import com.alibaba.tamper.core.builder.BeanMappingBuilder;
4 | import com.alibaba.tamper.core.builder.Builder;
5 | import com.alibaba.tamper.core.config.BeanMappingBehavior;
6 | import com.alibaba.tamper.core.config.BeanMappingField;
7 |
8 | /**
9 | * {@linkplain BeanMappingField}构造器
10 | *
11 | * @author jianghang 2011-6-22 上午10:42:38
12 | */
13 | public class BeanMappingFieldBuilder implements Builder {
14 |
15 | private BeanMappingField field;
16 |
17 | public BeanMappingFieldBuilder(BeanMappingFieldAttributesBuilder srcField,
18 | BeanMappingFieldAttributesBuilder targetField, BeanMappingBehavior parent){
19 | this(srcField, targetField, false, parent);
20 | }
21 |
22 | public BeanMappingFieldBuilder(BeanMappingFieldAttributesBuilder srcField,
23 | BeanMappingFieldAttributesBuilder targetField, boolean mapping,
24 | BeanMappingBehavior parent){
25 | field = new BeanMappingField();
26 | field.setSrcField(srcField.get());
27 | field.setTargetField(targetField.get());
28 | field.setMapping(mapping);
29 | field.setBehavior(parent.clone());
30 | }
31 |
32 | /**
33 | * 是否打印debug信息
34 | */
35 | public BeanMappingFieldBuilder debug(boolean debug) {
36 | field.getBehavior().setDebug(debug);
37 | return this;
38 | }
39 |
40 | /**
41 | * 针对null value是否进行mapping set操作
42 | */
43 | public BeanMappingFieldBuilder mappingNullValue(boolean mappingNullValue) {
44 | field.getBehavior().setMappingNullValue(mappingNullValue);
45 | return this;
46 | }
47 |
48 | /**
49 | * 针对empty String value是否进行mapping set操作
50 | */
51 | public BeanMappingFieldBuilder mappingEmptyStrings(boolean mappingEmptyStrings) {
52 | field.getBehavior().setMappingEmptyStrings(mappingEmptyStrings);
53 | return this;
54 | }
55 |
56 | /**
57 | * 是否需要进行trim操作
58 | */
59 | public BeanMappingFieldBuilder trimStrings(boolean trimStrings) {
60 | field.getBehavior().setTrimStrings(trimStrings);
61 | return this;
62 | }
63 |
64 | /**
65 | * 指定使用的Convertor alias
66 | */
67 | public BeanMappingFieldBuilder convertor(String alias) {
68 | field.setConvertor(alias);
69 | return this;
70 | }
71 |
72 | /**
73 | * 指定使用的Convertor Class
74 | */
75 | public BeanMappingFieldBuilder convertor(Class convertorClass) {
76 | field.setConvertorClass(convertorClass);
77 | return this;
78 | }
79 |
80 | /**
81 | * 指定使用的script脚本
82 | */
83 | public BeanMappingFieldBuilder script(String script) {
84 | field.setScript(script);
85 | return this;
86 | }
87 |
88 | /**
89 | * 指定使用的defaultValue
90 | */
91 | public BeanMappingFieldBuilder defaultValue(String value) {
92 | field.setDefaultValue(value);
93 | return this;
94 | }
95 |
96 | /**
97 | * 设置是否需要进行递归mapping处理
98 | */
99 | public BeanMappingFieldBuilder recursiveMapping(boolean mapping) {
100 | field.setMapping(mapping);
101 | return this;
102 | }
103 |
104 | /**
105 | * 设置是否需要进行递归mapping处理
106 | */
107 | public BeanMappingFieldBuilder recursiveMapping(boolean mapping, String nestname) {
108 | field.setMapping(mapping);
109 | field.setNestName(nestname);
110 | return this;
111 | }
112 |
113 | /**
114 | * 设置是进行递归mapping对象的name
115 | */
116 | public BeanMappingFieldBuilder nestName(String nestname) {
117 | field.setNestName(nestname);
118 | return this;
119 | }
120 |
121 | /**
122 | * 设置是进行递归mapping对象
123 | */
124 | public BeanMappingFieldBuilder nestObject(BeanMappingBuilder nestBuilder) {
125 | field.setNestObject(nestBuilder.get());
126 | return this;
127 | }
128 |
129 | public BeanMappingField get() {
130 | return field;
131 | }
132 |
133 | }
134 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/builder/impl/BeanMappingObjectBuilder.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.builder.impl;
2 |
3 | import com.alibaba.tamper.core.builder.Builder;
4 | import com.alibaba.tamper.core.config.BeanMappingBehavior;
5 | import com.alibaba.tamper.core.config.BeanMappingObject;
6 |
7 | /**
8 | * {@linkplain BeanMappingObject}构造器
9 | *
10 | * @author jianghang 2011-6-22 上午10:10:30
11 | */
12 | public class BeanMappingObjectBuilder implements Builder {
13 |
14 | private static final long serialVersionUID = 358128791476093909L;
15 |
16 | private BeanMappingObject object;
17 |
18 | public BeanMappingObjectBuilder(String name, Class srcClass, Class targetClass, BeanMappingBehavior parent){
19 | object = new BeanMappingObject();
20 | object.setName(name);
21 | object.setSrcClass(srcClass);
22 | object.setTargetClass(targetClass);
23 | object.setBehavior(parent.clone());
24 | }
25 |
26 | public BeanMappingObjectBuilder(Class srcClass, Class targetClass, BeanMappingBehavior parent){
27 | object = new BeanMappingObject();
28 | object.setSrcClass(srcClass);
29 | object.setTargetClass(targetClass);
30 | object.setBehavior(parent.clone());
31 | }
32 |
33 | /**
34 | * 是否打印debug信息
35 | */
36 | public BeanMappingObjectBuilder debug(boolean debug) {
37 | object.getBehavior().setDebug(debug);
38 | return this;
39 | }
40 |
41 | /**
42 | * 针对null value是否进行mapping set操作
43 | */
44 | public BeanMappingObjectBuilder mappingNullValue(boolean mappingNullValue) {
45 | object.getBehavior().setMappingNullValue(mappingNullValue);
46 | return this;
47 | }
48 |
49 | /**
50 | * 针对empty String value是否进行mapping set操作
51 | */
52 | public BeanMappingObjectBuilder mappingEmptyStrings(boolean mappingEmptyStrings) {
53 | object.getBehavior().setMappingEmptyStrings(mappingEmptyStrings);
54 | return this;
55 | }
56 |
57 | /**
58 | * 是否需要进行trim操作
59 | */
60 | public BeanMappingObjectBuilder trimStrings(boolean trimStrings) {
61 | object.getBehavior().setTrimStrings(trimStrings);
62 | return this;
63 | }
64 |
65 | /**
66 | * 设置是否进行batch优化,默认为true
67 | */
68 | public BeanMappingObjectBuilder batch(boolean isBatch) {
69 | object.setBatch(isBatch);
70 | return this;
71 | }
72 |
73 | /**
74 | * 设置是否允许反向mapping,默认为false
75 | */
76 | public BeanMappingObjectBuilder reversable(boolean reversable) {
77 | object.setReversable(reversable);
78 | return this;
79 | }
80 |
81 | /**
82 | * 指定对应的key,用于script中属性获取
83 | */
84 | public BeanMappingObjectBuilder keys(String srcKey, String targetKey) {
85 | object.setSrcKey(srcKey);
86 | object.setTargetKey(targetKey);
87 | return this;
88 | }
89 |
90 | public BeanMappingObject get() {
91 | return object;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/config/BeanMappingBehavior.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.config;
2 |
3 | import org.apache.commons.lang.builder.ToStringBuilder;
4 | import org.apache.commons.lang.builder.ToStringStyle;
5 |
6 | /**
7 | * BeanMapping的一些mapping行为参数
8 | *
9 | * @author jianghang 2011-6-13 下午10:27:07
10 | */
11 | public class BeanMappingBehavior {
12 |
13 | private boolean debug = false; // 是否打印debug信息
14 | private boolean mappingNullValue = true; // 针对nullValue是否需要进行处理
15 | private boolean mappingEmptyStrings = true; // 针对Empty String是否需要进行处理
16 | private boolean trimStrings = false; // 针对String进行trim处理
17 |
18 | public boolean isDebug() {
19 | return debug;
20 | }
21 |
22 | public void setDebug(boolean debug) {
23 | this.debug = debug;
24 | }
25 |
26 | public boolean isMappingNullValue() {
27 | return mappingNullValue;
28 | }
29 |
30 | public void setMappingNullValue(boolean mappingNullValue) {
31 | this.mappingNullValue = mappingNullValue;
32 | }
33 |
34 | public boolean isMappingEmptyStrings() {
35 | return mappingEmptyStrings;
36 | }
37 |
38 | public void setMappingEmptyStrings(boolean mappingEmptyStrings) {
39 | this.mappingEmptyStrings = mappingEmptyStrings;
40 | }
41 |
42 | public boolean isTrimStrings() {
43 | return trimStrings;
44 | }
45 |
46 | public void setTrimStrings(boolean trimStrings) {
47 | this.trimStrings = trimStrings;
48 | }
49 |
50 | public BeanMappingBehavior clone() {
51 | BeanMappingBehavior behavior = new BeanMappingBehavior();
52 | behavior.setDebug(this.debug);
53 | behavior.setMappingEmptyStrings(this.mappingEmptyStrings);
54 | behavior.setMappingNullValue(this.mappingNullValue);
55 | behavior.setTrimStrings(this.trimStrings);
56 | return behavior;
57 | }
58 |
59 | @Override
60 | public String toString() {
61 | return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/config/BeanMappingConfigHelper.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.config;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.util.Map;
6 |
7 | import com.alibaba.tamper.core.builder.BeanMappingBuilder;
8 |
9 | /**
10 | * Bean Mapping配置操作的相关helper类
11 | *
12 | * @author jianghang 2011-5-28 上午11:00:34
13 | */
14 | public class BeanMappingConfigHelper {
15 |
16 | private static volatile BeanMappingConfigHelper singleton = null;
17 | private BeanMappingConfigRespository repository = null; // 基于文件的配置
18 | private BeanMappingConfigRespository autoRepository = null; // 自动注册的配置
19 | private volatile BeanMappingBehavior globalBehavior = null; // 定义为voolatile,允许动态修改
20 |
21 | public BeanMappingConfigHelper(){
22 | repository = new BeanMappingConfigRespository();
23 | autoRepository = new BeanMappingConfigRespository();
24 | globalBehavior = new BeanMappingBehavior();
25 | }
26 |
27 | public BeanMappingConfigHelper(BeanMappingConfigRespository repository){
28 | // 允许传入自定义仓库
29 | this.repository = repository;
30 | autoRepository = new BeanMappingConfigRespository();
31 | globalBehavior = new BeanMappingBehavior();
32 | }
33 |
34 | /**
35 | * 单例方法
36 | */
37 | public static BeanMappingConfigHelper getInstance() {
38 | if (singleton == null) {
39 | synchronized (BeanMappingConfigHelper.class) {
40 | if (singleton == null) { // double check
41 | singleton = new BeanMappingConfigHelper();
42 | }
43 | }
44 | }
45 | return singleton;
46 | }
47 |
48 | /**
49 | * 根据class查找对应的{@linkplain BeanMappingObject}
50 | */
51 | public BeanMappingObject getBeanMappingObject(Class src, Class target) {
52 | return getFromRepository(src, target, this.repository);
53 | }
54 |
55 | /**
56 | * 根据name查找对应的{@linkplain BeanMappingObject}
57 | */
58 | public BeanMappingObject getBeanMappingObject(String name) {
59 | return repository.getBeanMappingObject(name);
60 | }
61 |
62 | /**
63 | * 根据class查找对应的{@linkplain BeanMappingObject},如果不存在则进行自动注册
64 | */
65 | public BeanMappingObject getBeanMappingObject(Class src, Class target, boolean autoRegister) {
66 | BeanMappingObject object = autoRepository.getBeanMappingObject(src, target);
67 | if (object == null && autoRegister) {
68 | autoRepository.register(src, target);
69 | object = getFromRepository(src, target, this.autoRepository);
70 | }
71 | return object;
72 | }
73 |
74 | /**
75 | * 根据class查找对应的{@linkplain BeanMappingObject},如果不存在则进行自动注册
76 | */
77 | public BeanMappingObject getBeanMapObject(Class src, Class target, boolean autoRegister) {
78 | BeanMappingObject object = autoRepository.getBeanMappingObject(src, target);
79 | if (object == null && autoRegister) {
80 | if (isMap(src)) {// 判断是否为map接口的子类
81 | autoRepository.registerMap(target);
82 | } else {
83 | autoRepository.registerMap(src);
84 | }
85 |
86 | object = getFromRepository(src, target, this.autoRepository);
87 | }
88 | return object;
89 | }
90 |
91 | /**
92 | * 直接注册一个解析好的{@linkplain BeanMappingObject}
93 | */
94 | public void register(BeanMappingObject object) {
95 | repository.register(object);
96 | }
97 |
98 | /**
99 | * 直接注册一个解析好的{@linkplain BeanMappingBuilder}
100 | */
101 | public void register(BeanMappingBuilder builder) {
102 | repository.register(builder);
103 | }
104 |
105 | public void registerConfig(String file) {
106 | InputStream in = null;
107 | ClassLoader cl = Thread.currentThread().getContextClassLoader();
108 | if (cl == null) {
109 | cl = BeanMappingConfigRespository.class.getClassLoader();
110 | }
111 | in = cl.getResourceAsStream(file);
112 | // 自己打开的文件需要关闭
113 | try {
114 | repository.registerConfig(in);
115 | } finally {
116 | if (in != null) {
117 | try {
118 | in.close();
119 | } catch (IOException e) {
120 | // ignore
121 | }
122 | }
123 | }
124 | }
125 |
126 | public void registerConfig(InputStream in) {
127 | repository.registerConfig(in);
128 | }
129 |
130 | // ======================== helper method ======================
131 |
132 | /**
133 | * @param src
134 | * @param target
135 | * @return
136 | */
137 | private BeanMappingObject getFromRepository(Class src, Class target, BeanMappingConfigRespository repository) {
138 | BeanMappingObject object = repository.getBeanMappingObject(src, target);
139 | if (object == null) { // 再尝试一下map接口的处理
140 | boolean isSrcMap = isMap(src);
141 | boolean isTargetMap = isMap(target);
142 | if (isSrcMap && isTargetMap) {
143 | object = repository.getBeanMappingObject(Map.class, Map.class);
144 | } else if (isSrcMap) {
145 | object = repository.getBeanMappingObject(Map.class, target);
146 | } else if (isMap(target)) {
147 | object = repository.getBeanMappingObject(src, Map.class);
148 | }
149 | }
150 |
151 | return object;
152 | }
153 |
154 | private boolean isMap(Class clazz) {
155 | return clazz != null && Map.class.isAssignableFrom(clazz);
156 | }
157 |
158 | // ========================= setter / getter ===================
159 |
160 | public void setRepository(BeanMappingConfigRespository repository) {
161 | this.repository = repository;
162 | }
163 |
164 | public BeanMappingBehavior getGlobalBehavior() {
165 | return globalBehavior;
166 | }
167 |
168 | public void setGlobalBehavior(BeanMappingBehavior globalBehavior) {
169 | this.globalBehavior = globalBehavior;
170 | }
171 |
172 | }
173 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/config/BeanMappingConfigRespository.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.config;
2 |
3 | import java.io.InputStream;
4 | import java.util.List;
5 | import java.util.Map;
6 | import java.util.concurrent.ConcurrentHashMap;
7 |
8 | import org.apache.commons.lang.StringUtils;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | import com.alibaba.tamper.core.builder.BeanMappingBuilder;
13 | import com.alibaba.tamper.core.config.parse.BeanMappingParser;
14 |
15 | /**
16 | * BeanMappingObject对应的仓库,解析一次Object后会进行cache
17 | *
18 | * @author jianghang 2011-5-26 下午07:57:33
19 | */
20 | public class BeanMappingConfigRespository {
21 |
22 | private final static Logger logger = LoggerFactory.getLogger(BeanMappingConfigRespository.class);
23 | private static final String SEPERATOR = ":";
24 | private Map mappings = new ConcurrentHashMap(10);
25 |
26 | /**
27 | * 根据class查找对应的{@linkplain BeanMappingObject}
28 | */
29 | public BeanMappingObject getBeanMappingObject(Class src, Class target) {
30 | return mappings.get(mapperObjectName(src, target));
31 | }
32 |
33 | /**
34 | * 根据name查找对应的{@linkplain BeanMappingObject}
35 | */
36 | public BeanMappingObject getBeanMappingObject(String name) {
37 | return mappings.get(name);
38 | }
39 |
40 | /**
41 | * 直接注册一个解析好的{@linkplain BeanMappingBuilder}
42 | */
43 | public void register(BeanMappingBuilder builder) {
44 | if (builder != null) {
45 | BeanMappingObject object = builder.get();
46 | register(object);
47 | }
48 | }
49 |
50 | /**
51 | * 直接注册一个解析号的{@linkplain BeanMappingObject}
52 | */
53 | public void register(BeanMappingObject object) {
54 | BeanMappingObject old = null;
55 | String name = null;
56 | if (object != null) {
57 | if (StringUtils.isEmpty(object.getName())) {
58 | name = mapperObjectName(object.getSrcClass(), object.getTargetClass());
59 | } else {
60 | name = object.getName();
61 | }
62 |
63 | old = mappings.put(name, object);
64 | }
65 |
66 | if (old != null) {
67 | logger.warn("{} has been replaced by : {}", name, object.toString());
68 | }
69 | }
70 |
71 | /**
72 | * 直接注册为默认mapping
73 | *
74 | * @param src
75 | * @param dest
76 | */
77 | public void register(Class src, Class target) {
78 | List objects = BeanMappingParser.parseMapping(src, target);
79 | for (BeanMappingObject object : objects) {
80 | register(object);
81 | }
82 | }
83 |
84 | /**
85 | * 直接注册bean和map的mapping关系
86 | */
87 | public void registerMap(Class src) {
88 | List objects = BeanMappingParser.parseMapMapping(src);
89 | for (BeanMappingObject object : objects) {
90 | register(object);
91 | }
92 | }
93 |
94 | /**
95 | * 注册beanMapping配置的流
96 | */
97 | public void registerConfig(InputStream in) {
98 | List objects = BeanMappingParser.parseMapping(in);
99 | for (BeanMappingObject object : objects) {
100 | register(object);
101 | }
102 | }
103 |
104 | // ==========================helper method =========================
105 |
106 | private String mapperObjectName(Class src, Class dest) {
107 | String name1 = src.getName();
108 | String name2 = dest.getName();
109 |
110 | return name1 + SEPERATOR + name2;
111 | }
112 |
113 | }
114 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/config/BeanMappingEnvironment.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.config;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.util.ArrayList;
6 | import java.util.List;
7 | import java.util.Properties;
8 |
9 | import org.apache.commons.lang.StringUtils;
10 |
11 | import com.alibaba.tamper.core.BeanMappingException;
12 | import com.alibaba.tamper.core.helper.ReflectionHelper;
13 | import com.alibaba.tamper.core.introspect.Uberspect;
14 | import com.alibaba.tamper.core.introspect.UberspectImpl;
15 | import com.alibaba.tamper.core.process.ValueProcess;
16 |
17 | /**
18 | * mapping的一些环境变量配置
19 | *
20 | * @author jianghang 2012-1-30 下午03:59:21
21 | */
22 | public class BeanMappingEnvironment {
23 |
24 | private static final String config = "mapping.properties";
25 | private static final String BEANMAP_VPS = "beanMap.valueProcess.list";
26 | private static final String BEANMAPPING_VPS = "beanMapping.valueProcess.list";
27 | private static final String BEANCOPY_VPS = "beanCopy.valueProcess.list";
28 |
29 | private static final String VALUEPROCESS_PREFIX = "valueProcess.";
30 | private static final String UBERSPECTOR_IMPL = "uberspect.impl";
31 |
32 | private static Properties properties = new Properties(System.getProperties());
33 | private static List beanMappingVps;
34 | private static List beanMapVps;
35 | private static List beanCopyVps;
36 | private static Class uberspectClazz;
37 | private static boolean isBeanMappingSupportScript = false;
38 |
39 | static {
40 | InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(config);
41 | try {
42 | properties.load(stream);
43 | } catch (IOException e) {
44 | throw new BeanMappingException("can't found " + config);
45 | }
46 | try {
47 | // 解析value process
48 | String vps = properties.getProperty(BEANMAPPING_VPS, StringUtils.EMPTY);
49 | beanMappingVps = parseVps(vps);
50 | isBeanMappingSupportScript = StringUtils.containsIgnoreCase(vps, "script");
51 |
52 | beanMapVps = parseVps(properties.getProperty(BEANMAP_VPS, StringUtils.EMPTY));
53 | beanCopyVps = parseVps(properties.getProperty(BEANCOPY_VPS, StringUtils.EMPTY));
54 | // 解析uberspect
55 | String uberspectClazzName = properties.getProperty(UBERSPECTOR_IMPL, UberspectImpl.class.getName());
56 | uberspectClazz = Class.forName(uberspectClazzName);
57 | } catch (Exception e) {
58 | throw new BeanMappingException(e);
59 | }
60 | }
61 |
62 | public static boolean isBeanMappingSupportScript() {
63 | return isBeanMappingSupportScript;
64 | }
65 |
66 | public static List getBeanMappingVps() {
67 | return beanMappingVps;
68 | }
69 |
70 | public static List getBeanMapVps() {
71 | return beanMapVps;
72 | }
73 |
74 | public static List getBeanCopyVps() {
75 | return beanCopyVps;
76 | }
77 |
78 | public static Uberspect getUberspect() {
79 | return (Uberspect) ReflectionHelper.newInstance(uberspectClazz);
80 | }
81 |
82 | public static void setBeanMappingVps(String vps) {
83 | beanMappingVps = parseVps(vps);
84 | isBeanMappingSupportScript = StringUtils.containsIgnoreCase(vps, "script");
85 | }
86 |
87 | public static void setBeanMapVps(String vps) {
88 | beanMapVps = parseVps(vps);
89 | }
90 |
91 | public static void setBeanCopyVps(String vps) {
92 | beanCopyVps = parseVps(vps);
93 | }
94 |
95 | public static void setValueProcess(String vp, Class clazz) {
96 | properties.put(vp, clazz.getName());
97 | }
98 |
99 | public static void setUberspect(Class uberspectClazz) {
100 | BeanMappingEnvironment.uberspectClazz = uberspectClazz;
101 | }
102 |
103 | // =================== help method =======================
104 |
105 | private static List parseVps(String vps) {
106 | String[] strs = StringUtils.split(vps, ",");
107 | List result = new ArrayList();
108 | for (String str : strs) {
109 | result.add(initValueProcess(str));
110 | }
111 |
112 | return result;
113 | }
114 |
115 | private static ValueProcess initValueProcess(String name) {
116 | String className = (String) properties.get(VALUEPROCESS_PREFIX + name);
117 | try {
118 | Class clazz = Class.forName(className);
119 | if (ValueProcess.class.isAssignableFrom(clazz) == false) {
120 | throw new BeanMappingException(className + " is not assign From ValueProcess!");
121 | }
122 |
123 | return (ValueProcess) ReflectionHelper.newInstance(clazz);
124 | } catch (ClassNotFoundException e) {
125 | throw new BeanMappingException(e);
126 | }
127 | }
128 |
129 | }
130 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/config/BeanMappingField.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.config;
2 |
3 | import java.io.Serializable;
4 |
5 | import org.apache.commons.lang.builder.ToStringBuilder;
6 | import org.apache.commons.lang.builder.ToStringStyle;
7 |
8 | import com.alibaba.tamper.core.introspect.GetExecutor;
9 | import com.alibaba.tamper.core.introspect.SetExecutor;
10 | import com.alibaba.tamper.process.convertor.Convertor;
11 |
12 | /**
13 | * 解析完成后的一个BeanMapping的field配置对象
14 | *
15 | *
16 | * changeLog
17 | * v1.0.2
18 | * 两种条件满足时可以触发使用nestObject对象
19 | * a. mapping=true,需要进行递归映射,会读取nestObject定义的映射规则
20 | * b. 针对field为collection类型,需要进行循环映射,会读取nestObject定义的映射规则
21 | *
22 | *
23 | * @author jianghang 2011-5-23 下午04:25:06
24 | */
25 | public class BeanMappingField implements Serializable {
26 |
27 | private static final long serialVersionUID = 3673414855182044438L;
28 | private BeanMappingFieldAttributes srcField = new BeanMappingFieldAttributes(); // 源属性配置信息
29 | private BeanMappingFieldAttributes targetField = new BeanMappingFieldAttributes(); // 目标属性配置信息
30 | private String defaultValue = null; // 默认值,配置文件中定义的字符串
31 | private String convertor = null; // 自定义conveterName
32 | private Class convertorClass = null; // 指定convertor的class
33 | private String script = null; // format script字符串
34 | private boolean mapping = false; // 是否深度递归mapping
35 | private String nestName = null; // 定义嵌套映射的名字
36 | private BeanMappingBehavior behavior = null; // mapping的处理行为参数
37 |
38 | // ======================= 内部数据,外部请勿直接操作 ==================
39 | private BeanMappingObject nestObject = null; // 定义嵌套的配置
40 | private Convertor convertorRef = null; // convertor对应的对象引用
41 | private GetExecutor getExecutor = null; // get操作的执行引擎
42 | private SetExecutor setExecutor = null; // set操作的执行引擎
43 |
44 | public String getDefaultValue() {
45 | return defaultValue;
46 | }
47 |
48 | public void setDefaultValue(String defaultValue) {
49 | this.defaultValue = defaultValue;
50 | }
51 |
52 | public String getConvertor() {
53 | return convertor;
54 | }
55 |
56 | public void setConvertor(String convertor) {
57 | this.convertor = convertor;
58 | }
59 |
60 | public String getScript() {
61 | return script;
62 | }
63 |
64 | public void setScript(String script) {
65 | this.script = script;
66 | }
67 |
68 | public boolean isMapping() {
69 | return mapping;
70 | }
71 |
72 | public void setMapping(boolean mapping) {
73 | this.mapping = mapping;
74 | }
75 |
76 | public Class getConvertorClass() {
77 | return convertorClass;
78 | }
79 |
80 | public void setConvertorClass(Class convertorClass) {
81 | this.convertorClass = convertorClass;
82 | }
83 |
84 | public Convertor getConvertorRef() {
85 | return convertorRef;
86 | }
87 |
88 | public void setConvertorRef(Convertor convertorRef) {
89 | this.convertorRef = convertorRef;
90 | }
91 |
92 | public BeanMappingBehavior getBehavior() {
93 | return behavior;
94 | }
95 |
96 | public void setBehavior(BeanMappingBehavior behavior) {
97 | this.behavior = behavior;
98 | }
99 |
100 | public GetExecutor getGetExecutor() {
101 | return getExecutor;
102 | }
103 |
104 | public void setGetExecutor(GetExecutor getExecutor) {
105 | this.getExecutor = getExecutor;
106 | }
107 |
108 | public SetExecutor getSetExecutor() {
109 | return setExecutor;
110 | }
111 |
112 | public void setSetExecutor(SetExecutor setExecutor) {
113 | this.setExecutor = setExecutor;
114 | }
115 |
116 | public BeanMappingFieldAttributes getSrcField() {
117 | return srcField;
118 | }
119 |
120 | public void setSrcField(BeanMappingFieldAttributes srcField) {
121 | this.srcField = srcField;
122 | }
123 |
124 | public BeanMappingFieldAttributes getTargetField() {
125 | return targetField;
126 | }
127 |
128 | public void setTargetField(BeanMappingFieldAttributes targetField) {
129 | this.targetField = targetField;
130 | }
131 |
132 | public BeanMappingObject getNestObject() {
133 | return nestObject;
134 | }
135 |
136 | public void setNestObject(BeanMappingObject nestObject) {
137 | this.nestObject = nestObject;
138 | }
139 |
140 | public String getNestName() {
141 | return nestName;
142 | }
143 |
144 | public void setNestName(String nestName) {
145 | this.nestName = nestName;
146 | }
147 |
148 | @Override
149 | public String toString() {
150 | return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/config/BeanMappingFieldAttributes.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.config;
2 |
3 | import java.io.Serializable;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | import org.apache.commons.lang.builder.ToStringBuilder;
8 | import org.apache.commons.lang.builder.ToStringStyle;
9 |
10 | /**
11 | * mapping配置的field信息配置
12 | *
13 | * @author jianghang 2011-6-21 上午11:32:56
14 | */
15 | public class BeanMappingFieldAttributes implements Serializable {
16 |
17 | private static final long serialVersionUID = -4833554213883478310L;
18 | private Class locatorClass; // 指定在该LocatorClass,查找对应的目标数据name的属性方法,解决继承属性
19 | private String name; // 源数据的name
20 | private Class clazz; // 源数据的class
21 |
22 | // 允许出现嵌套数组,比如List>>,
23 | // 此时对应的componentClasses存在3个Class,分别为Set.class(第一层),List.class(第二层),Model.class(第三层)
24 | private List componentClasses; // 指定Collection/Array的ComponentType
25 |
26 | public Class getLocatorClass() {
27 | return locatorClass;
28 | }
29 |
30 | public void setLocatorClass(Class locatorClass) {
31 | this.locatorClass = locatorClass;
32 | }
33 |
34 | public String getName() {
35 | return name;
36 | }
37 |
38 | public void setName(String name) {
39 | this.name = name;
40 | }
41 |
42 | public Class getClazz() {
43 | return clazz;
44 | }
45 |
46 | public void setClazz(Class clazz) {
47 | this.clazz = clazz;
48 | }
49 |
50 | public List getComponentClasses() {
51 | return componentClasses;
52 | }
53 |
54 | public void setComponentClasses(List componentClasses) {
55 | this.componentClasses = componentClasses;
56 | }
57 |
58 | public void addComponentClasses(Class componentClass) {
59 | if (componentClasses == null) {
60 | componentClasses = new ArrayList();
61 | }
62 |
63 | componentClasses.add(componentClass);
64 | }
65 |
66 | @Override
67 | public String toString() {
68 | return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/config/BeanMappingObject.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.config;
2 |
3 | import java.io.Serializable;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | import org.apache.commons.lang.builder.ToStringBuilder;
8 | import org.apache.commons.lang.builder.ToStringStyle;
9 |
10 | import com.alibaba.tamper.core.introspect.BatchExecutor;
11 |
12 | /**
13 | * 解析完成后的一个BeanMapping配置对象
14 | *
15 | *
16 | * ChangeLog :
17 | * a. 1.0.2支持mapping定义alias name,用于解决map<->map对象的多种映射定义
18 | *
19 | *
20 | * @author jianghang 2011-5-26 下午07:16:10
21 | */
22 | public class BeanMappingObject implements Serializable {
23 |
24 | private static final long serialVersionUID = 9099474060890980056L;
25 | private String name; // 定义mapping配置name,默认为srcClass:targetClass
26 | private String srcKey = "src"; // format上下文中src key,默认:src
27 | private Class srcClass = null; // mapping的原始class
28 | private String targetKey = "target"; // format上下文中targetkey,默认:target
29 | private Class targetClass = null; // mapping的目标class
30 | private boolean reversable = true; // 原始和目标的mapping是否可逆,如果有自定义的convertor,强制修改为不可逆
31 | private List beanFields = new ArrayList(); // 具体字段的mapping配置
32 | private boolean batch = false; // 优化参数,是否开启批量处理操作.
33 | private BeanMappingBehavior behavior = null; // mapping的处理行为参数
34 |
35 | // ======================= 内部数据,外部请勿直接操作 ==================
36 | private BatchExecutor getBatchExecutor = null; // get操作的batch执行引擎
37 | private BatchExecutor setBatchExecutor = null; // set操作的batch执行引擎
38 |
39 | public String getName() {
40 | return name;
41 | }
42 |
43 | public void setName(String name) {
44 | this.name = name;
45 | }
46 |
47 | public Class getSrcClass() {
48 | return srcClass;
49 | }
50 |
51 | public void setSrcClass(Class srcClass) {
52 | this.srcClass = srcClass;
53 | }
54 |
55 | public Class getTargetClass() {
56 | return targetClass;
57 | }
58 |
59 | public void setTargetClass(Class targetClass) {
60 | this.targetClass = targetClass;
61 | }
62 |
63 | public boolean isReversable() {
64 | return reversable;
65 | }
66 |
67 | public void setReversable(boolean reversable) {
68 | this.reversable = reversable;
69 | }
70 |
71 | public List getBeanFields() {
72 | return beanFields;
73 | }
74 |
75 | public void setBeanFields(List beanFields) {
76 | this.beanFields = beanFields;
77 | }
78 |
79 | public void addBeanField(BeanMappingField beanField) {
80 | if (beanFields == null) {
81 | beanFields = new ArrayList();
82 | }
83 |
84 | beanFields.add(beanField);
85 | }
86 |
87 | public String getSrcKey() {
88 | return srcKey;
89 | }
90 |
91 | public void setSrcKey(String srcKey) {
92 | this.srcKey = srcKey;
93 | }
94 |
95 | public String getTargetKey() {
96 | return targetKey;
97 | }
98 |
99 | public void setTargetKey(String targetKey) {
100 | this.targetKey = targetKey;
101 | }
102 |
103 | public boolean isBatch() {
104 | return batch;
105 | }
106 |
107 | public void setBatch(boolean batch) {
108 | this.batch = batch;
109 | }
110 |
111 | public BatchExecutor getGetBatchExecutor() {
112 | return getBatchExecutor;
113 | }
114 |
115 | public void setGetBatchExecutor(BatchExecutor getBatchExecutor) {
116 | this.getBatchExecutor = getBatchExecutor;
117 | }
118 |
119 | public BatchExecutor getSetBatchExecutor() {
120 | return setBatchExecutor;
121 | }
122 |
123 | public void setSetBatchExecutor(BatchExecutor setBatchExecutor) {
124 | this.setBatchExecutor = setBatchExecutor;
125 | }
126 |
127 | public BeanMappingBehavior getBehavior() {
128 | return behavior;
129 | }
130 |
131 | public void setBehavior(BeanMappingBehavior behavior) {
132 | this.behavior = behavior;
133 | }
134 |
135 | @Override
136 | public String toString() {
137 | return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/config/parse/BeanMappingBehaviorParse.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.config.parse;
2 |
3 | import org.w3c.dom.Node;
4 |
5 | import com.alibaba.tamper.core.config.BeanMappingBehavior;
6 |
7 | /**
8 | * 解析下Beahvior相关配置
9 | *
10 | * @author jianghang 2011-6-21 下午01:28:28
11 | */
12 | public class BeanMappingBehaviorParse {
13 |
14 | public static BeanMappingBehavior parse(Node node, BeanMappingBehavior parent) {
15 | Node debug = node.getAttributes().getNamedItem("debug");
16 | Node mappingNullValue = node.getAttributes().getNamedItem("mappingNullValue");
17 | Node mappingEmptyStrings = node.getAttributes().getNamedItem("mappingEmptyStrings");
18 | Node trimStrings = node.getAttributes().getNamedItem("trimStrings");
19 |
20 | boolean isConfig = false;
21 | BeanMappingBehavior behavior = parent.clone();// 从上一个节点复制配置,进行替换处理
22 |
23 | if (debug != null) {
24 | behavior.setDebug(Boolean.valueOf(debug.getNodeValue()));
25 | isConfig = true;
26 | }
27 | if (mappingNullValue != null) {
28 | behavior.setMappingNullValue(Boolean.valueOf(mappingNullValue.getNodeValue()));
29 | isConfig = true;
30 | }
31 | if (mappingEmptyStrings != null) {
32 | behavior.setMappingEmptyStrings(Boolean.valueOf(mappingEmptyStrings.getNodeValue()));
33 | isConfig = true;
34 | }
35 | if (trimStrings != null) {
36 | behavior.setTrimStrings(Boolean.valueOf(trimStrings.getNodeValue()));
37 | isConfig = true;
38 | }
39 |
40 | return isConfig ? behavior : parent;// 如果未设置,则直接使用parent
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/config/parse/ClassAliasParse.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.config.parse;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.w3c.dom.Node;
6 | import org.w3c.dom.NodeList;
7 |
8 | import com.alibaba.tamper.core.BeanMappingException;
9 | import com.alibaba.tamper.core.helper.ReflectionHelper;
10 |
11 | /**
12 | * 解析下Class alias的相关配置
13 | *
14 | * @author jianghang 2011-6-21 下午01:33:28
15 | */
16 | public class ClassAliasParse {
17 |
18 | private final static Logger logger = LoggerFactory.getLogger(ClassAliasParse.class);
19 |
20 | public static void parseAndRegister(Node node) {
21 | NodeList nodeList = node.getChildNodes();
22 | for (int i = 0; i < nodeList.getLength(); i++) {
23 | Node aliasClassNode = nodeList.item(i);
24 | if ("classAlias".equals(aliasClassNode.getNodeName())) {
25 | Node aliasNode = aliasClassNode.getAttributes().getNamedItem("alias");
26 | Node clazzNode = aliasClassNode.getAttributes().getNamedItem("class");
27 | if (aliasNode == null || clazzNode == null) {
28 | throw new BeanMappingException("alias or class is null , please check!");
29 | }
30 |
31 | String alias = aliasNode.getNodeValue();
32 | Class clazz = ReflectionHelper.forName(clazzNode.getNodeValue());
33 | ReflectionHelper.registerClassAlias(aliasNode.getNodeValue(), clazz);
34 | if (logger.isDebugEnabled()) {
35 | logger.debug("register class[" + clazz.toString() + "] to alias[" + alias + "]");
36 | }
37 | }
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/config/parse/ConvertorParse.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.config.parse;
2 |
3 | import org.apache.commons.lang.StringUtils;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.w3c.dom.Node;
7 | import org.w3c.dom.NodeList;
8 |
9 | import com.alibaba.tamper.core.BeanMappingException;
10 | import com.alibaba.tamper.core.helper.ReflectionHelper;
11 | import com.alibaba.tamper.process.convertor.Convertor;
12 | import com.alibaba.tamper.process.convertor.ConvertorHelper;
13 |
14 | /**
15 | * 解析下Convertor的相关配置,直接注册到仓库
16 | *
17 | * @author jianghang 2011-6-21 下午01:33:38
18 | */
19 | public class ConvertorParse {
20 |
21 | private final static Logger logger = LoggerFactory.getLogger(ConvertorParse.class);
22 |
23 | public static void parseAndRegister(Node convertorsNode) {
24 | NodeList nodeList = convertorsNode.getChildNodes();
25 | for (int i = 0; i < nodeList.getLength(); i++) {
26 | Node node = nodeList.item(i);
27 | if ("convertor".equals(node.getNodeName())) {
28 | Node aliasNode = node.getAttributes().getNamedItem("alias");
29 | Node clazzNode = node.getAttributes().getNamedItem("class");
30 | Node srcClassNode = node.getAttributes().getNamedItem("srcClass");
31 | Node targetClassNode = node.getAttributes().getNamedItem("targetClass");
32 | if (clazzNode != null) {
33 | Class clazz = ReflectionHelper.forName(clazzNode.getNodeValue());
34 | if (!Convertor.class.isAssignableFrom(clazz)) { // 检查下必须为Convertor的子类
35 | throw new BeanMappingException(clazz.toString() + " is not implements Convertor");
36 | }
37 |
38 | Convertor convertor = (Convertor) ReflectionHelper.newInstance(clazz);
39 | if (aliasNode != null) {
40 | // 注册为别名
41 | String alias = aliasNode.getNodeValue();
42 | ConvertorHelper.getInstance().registerConvertor(alias, convertor);
43 |
44 | if (logger.isDebugEnabled()) {
45 | logger.debug("register Convertor[" + clazz.toString() + "] to alias[" + alias + "]");
46 | }
47 | } else {
48 | String srcClass = srcClassNode.getNodeValue();
49 | String targetClass = targetClassNode.getNodeValue();
50 | if (StringUtils.isEmpty(srcClass) || StringUtils.isEmpty(targetClass)) {
51 | throw new BeanMappingException(clazz.toString() + " should fix srcClass and targetClass!");
52 | }
53 | Class srcClazz = ReflectionHelper.forName(srcClassNode.getNodeValue());
54 | Class targetClazz = ReflectionHelper.forName(targetClassNode.getNodeValue());
55 | // 根据srcClass/targetClass进行自动匹配
56 | ConvertorHelper.getInstance().registerConvertor(srcClazz, targetClazz, convertor);
57 | if (logger.isDebugEnabled()) {
58 | logger.debug("register Convertor[" + clazz.toString() + "] used by srcClass["
59 | + srcClass.toString() + "]" + " targetClass[" + targetClass.toString() + "]");
60 | }
61 | }
62 | }
63 | }
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/config/parse/FunctionClassParse.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.config.parse;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.w3c.dom.Node;
6 | import org.w3c.dom.NodeList;
7 |
8 | import com.alibaba.tamper.core.BeanMappingException;
9 | import com.alibaba.tamper.core.helper.ReflectionHelper;
10 | import com.alibaba.tamper.process.script.ScriptHelper;
11 |
12 | /**
13 | * 解析下Function class的相关配置
14 | *
15 | * @author jianghang 2011-6-21 下午01:33:28
16 | */
17 | public class FunctionClassParse {
18 |
19 | private final static Logger logger = LoggerFactory.getLogger(FunctionClassParse.class);
20 |
21 | public static void parseAndRegister(Node node) {
22 | NodeList nodeList = node.getChildNodes();
23 | for (int i = 0; i < nodeList.getLength(); i++) {
24 | Node aliasClassNode = nodeList.item(i);
25 | if ("functionClass".equals(aliasClassNode.getNodeName())) {
26 | Node nameNode = aliasClassNode.getAttributes().getNamedItem("name");
27 | Node clazzNode = aliasClassNode.getAttributes().getNamedItem("class");
28 | if (nameNode == null || clazzNode == null) {
29 | throw new BeanMappingException("alias or class is null , please check!");
30 | }
31 |
32 | String name = nameNode.getNodeValue();
33 | Class clazz = ReflectionHelper.forName(clazzNode.getNodeValue());
34 | ScriptHelper.getInstance().registerFunctionClass(name, ReflectionHelper.newInstance(clazz));
35 | if (logger.isDebugEnabled()) {
36 | logger.debug("register class[" + clazz.toString() + "] to name[" + name + "]");
37 | }
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/helper/BatchObjectHolder.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.helper;
2 |
3 | import com.alibaba.tamper.core.BeanMappingException;
4 |
5 | /**
6 | * 批量处理对象的holder处理
7 | *
8 | * @author jianghang 2011-6-2 下午12:44:26
9 | */
10 | public class BatchObjectHolder {
11 |
12 | private Object[] batchValues = null;
13 | private int currentIndex;
14 |
15 | public void setBatchValues(Object[] batchValues) {
16 | this.batchValues = batchValues;
17 | }
18 |
19 | public BatchObjectHolder(Object[] values){
20 | if (values == null) {
21 | throw new BeanMappingException("batch values is null!");
22 | }
23 | this.batchValues = values;
24 | this.currentIndex = -1;
25 | }
26 |
27 | public Object[] getBatchValues() {
28 | return batchValues;
29 | }
30 |
31 | public Object getNext() {
32 | currentIndex = currentIndex + 1;
33 | if (currentIndex > batchValues.length) {
34 | throw new BeanMappingException("batch values index is out of Array!");
35 | }
36 | return batchValues[currentIndex];
37 | }
38 |
39 | public void setObject(Object value) {
40 | batchValues[currentIndex] = value;
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/alibaba/tamper/core/helper/ContextObjectHolder.java:
--------------------------------------------------------------------------------
1 | package com.alibaba.tamper.core.helper;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * 每个mapping执行过程都认为是在一个独立的Region中进行处理,在Region中会记录一下当前的一些信息
8 | *
9 | * @author jianghang 2012-4-5 下午02:27:41
10 | */
11 | public class ContextObjectHolder {
12 |
13 | private static volatile ContextObjectHolder singleton = null;
14 | public static final String MAPPING_ENTER = "_mapping_enter_";
15 | public static final String SCRIPT_CONTEXT = "_script_context_";
16 | public static final String PROCESS_CONTEXT = "_process_context_";
17 | private ThreadLocal