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

com.github.harbby.dsxparser.UserFuncWrapper Maven / Gradle / Ivy

The newest version!
package com.github.harbby.dsxparser;

import com.github.harbby.dsxparser.tree.Expression;
import com.github.harbby.dsxparser.tree.QualifiedName;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static com.github.harbby.gadtry.base.MoreObjects.checkArgument;
import static com.github.harbby.gadtry.base.MoreObjects.checkState;
import static java.util.Objects.requireNonNull;

public class UserFuncWrapper {
    private final Class funcClass;

    private final String funcName;

    private final int[] argsNumber;

    private final Constructor constructor;

    public UserFuncWrapper(Class funcClass,
                           String funcName,
                           int[] argsNumber,
                           Constructor constructor) {
        this.funcClass = funcClass;
        this.funcName = funcName;
        this.argsNumber = argsNumber;
        this.constructor = constructor;
    }

    public static UserFuncWrapper of(Class funcClass) {
        requireNonNull(funcClass, "funcClass is null");
        Constructor constructor = null;
        try {
            constructor = funcClass.getConstructor(QualifiedName.class, List.class);
        } catch (NoSuchMethodException e) {
            throw new IllegalArgumentException(funcClass + " not found public Constructor(QualifiedName, List)", e);
        }
        FuncInfo funcInfo = funcClass.getAnnotation(FuncInfo.class);
        requireNonNull(funcInfo, "User Function: " + funcClass + " not add @UserFunc");
        String name = funcInfo.value().toLowerCase(Locale.ROOT);
        checkState(funcInfo.argsNumber().length > 0, "@FuncInfo(argsNumber should not Empty)");
        return new UserFuncWrapper(funcClass, name, funcInfo.argsNumber(), constructor);
    }

    public int[] getArgsNumber() {
        return argsNumber;
    }

    public String getFuncName() {
        return funcName;
    }

    public Class getFuncClass() {
        return funcClass;
    }

    public DsxFunc newInstance(QualifiedName qualifiedName, List arguments)
            throws InvocationTargetException, InstantiationException, IllegalAccessException {
        String name = qualifiedName.toString();
        checkArgument(this.funcName.equals(name), "function name should be %s, but is %s", this.funcName, name);
        checkArgumentsNumber(name, arguments, this.argsNumber);
        return constructor.newInstance(qualifiedName, arguments);
    }

    private static void checkArgumentsNumber(String funcName, List arguments, int... numberArray) {
        int size = arguments.size();
        for (int num : numberArray) {
            if (num == size) {
                return;
            }
        }
        String requiresArray = IntStream.of(numberArray)
                .mapToObj(String::valueOf)
                .collect(Collectors.joining("/"));
        throw new ParsingException(String.format("The `%s` requires %s parameters but the actual number is %s",
                funcName, requiresArray, size));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy