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

shz.core.InterfaceProxy Maven / Gradle / Ivy

There is a newer version: 2024.0.2
Show newest version
package shz.core;

import shz.core.cl.ClassLoaderHelp;
import shz.core.type.TypeHelp;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.function.Function;

@SuppressWarnings("unchecked")
public final class InterfaceProxy implements InvocationHandler {
    public static final class Param {
        public final Object proxy;
        public final Method method;
        public final Object[] args;

        Param(Object proxy, Method method, Object[] args) {
            this.proxy = proxy;
            this.method = method;
            this.args = args;
        }
    }

    private final Function executor;

    private InterfaceProxy(Function executor) {
        this.executor = executor;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
        Class dCls = method.getDeclaringClass();
        if (dCls == Object.class) {
            switch (method.getName()) {
                case "hashCode":
                    return System.identityHashCode(proxy);
                case "equals":
                    return proxy == args[0];
                case "toString":
                    return executor.toString();
                default:
                    return null;
            }
        }
        Object invoke = executor.apply(new Param(proxy, method, args));
        if (invoke == null) return null;
        Class rt = method.getReturnType();
        if (rt == void.class || rt == Void.class) return null;
        if (!rt.isInstance(invoke)) invoke = FieldSetter.create(invoke, rt, method.getGenericReturnType());
        return invoke;
    }

    public static  T getProxy(Class cls, Function executor, boolean save) {
        NullHelp.requireNonNull(executor);
        List> interfaces = TypeHelp.getInterfaces(cls);
        NullHelp.requireNonEmpty(interfaces);
        ClassLoader cl = ClassLoaderHelp.get(cls);
        if (cl != null) {
            interfaces = ToList.explicitCollect(interfaces.stream().filter(c -> {
                try {
                    return c.getClassLoader() == cl;
                } catch (SecurityException ignored) {
                }
                try {
                    return c == cl.loadClass(c.getName());
                } catch (ClassNotFoundException e) {
                    return false;
                }
            }), interfaces.size());
            NullHelp.requireNonEmpty(interfaces);
        }
        if (save) System.getProperties().setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        return (T) Proxy.newProxyInstance(cl, interfaces.toArray(new Class[0]), new InterfaceProxy(executor));
    }

    public static  T getProxy(Class cls, Function executor) {
        return getProxy(cls, executor, false);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy