All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.nomou.mybatis.builder.spi.SqlSourceCreators Maven / Gradle / Ivy

There is a newer version: 1.0.0-BETA-20210819
Show newest version
package com.github.nomou.mybatis.builder.spi;

import com.github.nomou.mybatis.util.ServiceTypeLoader;
import freework.function.Condition;
import freework.reflect.Types;
import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.session.Configuration;

import java.lang.reflect.*;

/**
 * {@link SqlSourceCreator}工厂类.
 *
 * @author vacoor
 */
public abstract class SqlSourceCreators {
    /**
     * {@link SqlSourceCreator}支持的驱动类型参数.
     */
    private static final TypeVariable> SQL_SOURCE_CREATOR_SUPPORT_TYPE = SqlSourceCreator.class.getTypeParameters()[0];

    /**
     * 所有{@link SqlSourceCreator}实现类.
     */
    private static final Iterable> SQL_SOURCE_CREATOR_TYPES = ServiceTypeLoader.load(SqlSourceCreator.class);

    /**
     * 使用给定参数创建对应的{@link SqlSourceCreator}实现.
     *
     * @param mapperInterface mapper接口
     * @param method          mapper方法
     * @param exceptDriver    期望使用的语言驱动
     * @param configuration   mybatis配置对象
     * @return SqlSourceCreator实现
     */
    public static SqlSourceCreator create(final Class mapperInterface, final Method method,
                                             final LanguageDriver exceptDriver, final Configuration configuration) {
        final Class exceptDriverClass = exceptDriver.getClass();
        final Class sqlSourceCreatorClass = determineSqlSourceCreatorClass(exceptDriverClass, configuration);
        if (null == sqlSourceCreatorClass) {
            throw new UnsupportedOperationException(String.format("No provider available for the service: %s", SqlSourceCreator.class));
        }

        final Class driverClass = (Class) Types.resolveType(SqlSourceCreator.class.getTypeParameters()[0], sqlSourceCreatorClass);
        final LanguageDriver driver = driverClass.isAssignableFrom(exceptDriverClass) ? exceptDriver : configuration.getLanguageRegistry().getDriver(driverClass);

        Constructor ctor;
        try {
            ctor = sqlSourceCreatorClass.getConstructor(Class.class, Method.class, driverClass, Configuration.class);
        } catch (final NoSuchMethodException e) {
            try {
                ctor = sqlSourceCreatorClass.getConstructor(Class.class, Method.class, LanguageDriver.class, Configuration.class);
            } catch (final NoSuchMethodException ignore) {
                throw new IllegalStateException(String.format("No constructor public %s(Class, Method, %s, Configuration)", sqlSourceCreatorClass, driverClass.getCanonicalName()), e);
            }
        }
        try {
            return ctor.newInstance(mapperInterface, method, driver, configuration);
        } catch (final Exception e) {
            final Throwable cause = e.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            }
            throw new UndeclaredThrowableException(cause, "Create SqlSourceCreator failed");
        }
    }

    /**
     * 确定{@link SqlSourceCreator}实现类.
     *
     * @param languageDriverClass 期望的驱动类型
     * @param configuration       mybatis配置
     * @return 匹配到的SqlSourceCreator实现, 如果不存在返回null
     */
    private static Class determineSqlSourceCreatorClass(final Class languageDriverClass,
                                                                                    final Configuration configuration) {
        Class sqlSourceCreatorClass = findSqlSourceCreatorClass(new Condition>() {
            @Override
            public boolean value(Class type) {
                return type.isAssignableFrom(languageDriverClass);
            }
        });

        if (null == sqlSourceCreatorClass) {
            final Class defaultDriverClass = configuration.getLanguageRegistry().getDefaultDriverClass();
            sqlSourceCreatorClass = findSqlSourceCreatorClass(new Condition>() {
                @Override
                public boolean value(Class type) {
                    return type.isAssignableFrom(defaultDriverClass);
                }
            });
        }

        if (null == sqlSourceCreatorClass) {
            sqlSourceCreatorClass = findSqlSourceCreatorClass(new Condition>() {
                @Override
                public boolean value(Class type) {
                    return null != configuration.getLanguageRegistry().getDriver(type);
                }
            });
        }
        return sqlSourceCreatorClass;
    }

    /**
     * 查找{@link SqlSourceCreator}实现类.
     *
     * @param condition 匹配条件
     * @return 匹配成功返回对应class, 否则返回null
     */
    private static Class findSqlSourceCreatorClass(final Condition> condition) {
        for (final Class sqlSourceCreatorType : SQL_SOURCE_CREATOR_TYPES) {
            final Class type = (Class) Types.resolveType(SQL_SOURCE_CREATOR_SUPPORT_TYPE, sqlSourceCreatorType);
            if (null != type && condition.value(type)) {
                return sqlSourceCreatorType;
            }
        }
        return null;
    }

    /**
     * Non-instantiate.
     */
    private SqlSourceCreators() {
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy