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

fun.langel.cql.bind.CaveMethod Maven / Gradle / Ivy

The newest version!
package fun.langel.cql.bind;

import fun.langel.cql.annotation.*;
import fun.langel.cql.datasource.DataSource;
import fun.langel.cql.datasource.DataSourceHolder;
import fun.langel.cql.exception.DataSourceException;
import fun.langel.cql.invoke.Invocation;
import fun.langel.cql.invoke.Invoker;
import fun.langel.cql.invoke.Result;
import fun.langel.cql.invoke.support.DeleteInvoker;
import fun.langel.cql.invoke.support.InsertInvoker;
import fun.langel.cql.invoke.support.SelectInvoker;
import fun.langel.cql.invoke.support.UpdateInvoker;
import fun.langel.cql.parameter.ParameterResolver;
import fun.langel.cql.spring.Configuration;
import fun.langel.cql.util.Pair;
import fun.langel.cql.util.StringUtil;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

/**
 * @author [email protected](GuHan)
 * @since 2021/10/19 8:59 下午
 **/
public class CaveMethod {

    private Class klass;

    private MethodSignature signature;

    private Invocation invocation;

    private final Configuration configuration;

    public CaveMethod(final Configuration configuration,
                      final Class klass, final Method method) {
        this.configuration = configuration;
        this.klass = klass;
        this.signature = new MethodSignature(method);
        this.invocation = new Invocation(this.signature);
    }

    public Object execute(Object... values) {
        checkArguments(values);
        Arg[] args = args(this.signature.method.getParameters(), values);
        Target target = target(args);
        Invoker invoker = Invoker.EMPTY;
        ParameterResolver resolver = new ParameterResolver();
        Pair> pair = resolver.resolve(this.signature.sql(), args);

        DataSourceHolder holder = resolveDataSource(this.signature.direct());
        if (holder == null) {
            throw new DataSourceException("Not matched any datasource " + this.signature.direct);
        }
        if (this.signature.isSelect()) {
            invoker = new SelectInvoker(target, holder.getDataSource(), this.signature.sql(), pair);
        } else if (this.signature.isDelete()) {
            invoker = new DeleteInvoker(target, holder.getDataSource(), this.signature.sql(), pair);
        } else if (this.signature.isInsert()) {
            invoker = new InsertInvoker();
        } else if (this.signature.isUpdate()) {
            invoker = new UpdateInvoker();
        }
        Result result = invoker.invoke(this.invocation);
        return result.getValue();
    }


    private void checkArguments(Object... args) {
        if (args != null && args.length < 0) {
            throw new IllegalArgumentException("Illegal argument size.");
        }
    }

    private Target target(final Arg[] args) {
        return () -> args;
    }

    private Arg[] args(final Parameter[] parameters, Object... values) {
        if (values == null) {
            return new Arg[0];
        }
        final Arg[] args = new Arg[parameters.length];
        for (int idx = 0, len = values.length; idx < len; idx++) {
            Parameter parameter = parameters[idx];
            Param param = parameter.getDeclaredAnnotation(Param.class);
            String alias = null;
            if (param != null) {
                alias = param.name();
            }
            args[idx] = new Arg(parameter.getName(), alias, values[idx], parameter.getType());
        }
        return args;
    }


    private DataSourceHolder resolveDataSource(final String direct) {
        if (StringUtil.isEmpty(direct)) {
            return this.configuration.getFirstDataSource();
        }
        return this.configuration.getDataSource(direct);
    }

    public static class MethodSignature {

        private Method method;

        private Select selectAnno;

        private Update updateAnno;

        private Delete deleteAnno;

        private Insert insertAnno;

        private String sql;

        // private Class returnType;

        private String direct;

        public MethodSignature(final Method method) {
            this.method = method;
            this.selectAnno = this.method.getDeclaredAnnotation(Select.class);
            this.updateAnno = this.method.getDeclaredAnnotation(Update.class);
            this.deleteAnno = this.method.getDeclaredAnnotation(Delete.class);
            this.insertAnno = this.method.getDeclaredAnnotation(Insert.class);
            parse();
        }

        public String sql() {
            return this.sql;
        }

        public Method method() {
            return this.method;
        }

        public void parse() {
            if (selectAnno != null) {
                this.sql = this.selectAnno.sql();
                this.direct = this.selectAnno.direct();
            } else if (deleteAnno != null) {
                this.sql = this.deleteAnno.sql();
                this.direct = this.deleteAnno.direct();
            } else if (insertAnno != null) {
                this.sql = this.insertAnno.sql();
                this.direct = this.insertAnno.direct();
            } else if (updateAnno != null) {
                this.sql = this.updateAnno.sql();
                this.direct = this.updateAnno.direct();

            }
        }

        public String direct() {
            return this.direct;
        }

        public boolean isSelect() {
            return this.selectAnno != null;
        }

        public boolean isDelete() {
            return this.deleteAnno != null;
        }

        public boolean isUpdate() {
            return this.deleteAnno != null;
        }

        public boolean isInsert() {
            return this.insertAnno != null;
        }

        public Class actualType() {
            Class returnType = returnType();
            if (List.class.isAssignableFrom(returnType())) {
                // if (Object.class != returnType) {
                //     return returnType;
                // }
                return (Class) ((ParameterizedType) this.method.getGenericReturnType()).getActualTypeArguments()[0];
            }
            return returnType;
        }

        public Class returnType() {
            return this.method.getReturnType();
        }
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy