Package com.alibaba.tamper.core

Source Code of com.alibaba.tamper.core.BeanMappingExecutor

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

}
TOP

Related Classes of com.alibaba.tamper.core.BeanMappingExecutor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.