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

shz.Request Maven / Gradle / Ivy

package shz;

import shz.model.IdPayload;
import shz.model.RpcPayload;
import shz.msg.ClientFailure;
import shz.msg.FailureMsg;
import shz.msg.ServerFailure;

import java.io.Serializable;
import java.util.Arrays;
import java.util.function.Function;

@SuppressWarnings("unchecked")
public class Request implements Serializable {
    private static final long serialVersionUID = 1334707764364480223L;
    protected final ID id;
    protected final String version;
    protected final T payload;
    protected final long timestamp;

    protected Request(ID id, String version, T payload) {
        this.id = id;
        this.version = version;
        this.payload = payload;
        this.timestamp = System.currentTimeMillis();
    }

    public static  Request of(ID id, String version, T payload) {
        return new Request<>(id, version, payload);
    }

    public static  Request of(ID id, T payload) {
        return of(id, "", payload);
    }

    public static  Request of(T payload) {
        return of(null, "", payload);
    }

    public static  Request of(Request request, T payload) {
        return request == null ? of(payload) : of(request.id, request.version, payload);
    }

    public static  Request of(Request request) {
        return of(request, null);
    }

    public static final class ClassInfo implements Serializable {
        private static final long serialVersionUID = 3665381348076587378L;
        private final String classpath;
        private final Object[] initargs;
        private final byte[] classByte;

        public ClassInfo(String classpath, Object[] initargs, byte[] classByte) {
            this.classpath = classpath;
            this.initargs = initargs;
            this.classByte = classByte;
        }
    }

    public final  Response> invoke(Function, Object> beanFunc) {
        if (Validator.isBlank(id)) return Response.fail(ClientFailure.MISSING_ID);
        IdPayload idPayload = IdPayload.of(id);
        if (!(payload instanceof RpcPayload)) return Response.fail(ServerFailure.IllegalStateException, idPayload);
        RpcPayload rpcPayload = (RpcPayload) payload;
        if (Validator.isBlank(rpcPayload.className()) || Validator.isBlank(rpcPayload.methodName()))
            return Response.fail(ClientFailure.RPC_MISSING_CLASS_NAME_OR_METHOD_NAME, idPayload);
        Object receiver = null;
        Object data = rpcPayload.data();
        if (data instanceof ClassInfo) {
            ClassInfo classInfo = (ClassInfo) data;
            if (Validator.nonEmpty(classInfo.classByte))
                receiver = AccessibleHelp.newObject(rpcPayload.className(), new AccessibleHelp.CustomClassLoader(t -> classInfo.classByte), classInfo.initargs);
            if (receiver == null && Validator.nonBlank(classInfo.classpath))
                receiver = AccessibleHelp.newObject(rpcPayload.className(), AccessibleHelp.getClassLoader(classInfo.classpath), classInfo.initargs);
        }
        if (receiver == null && beanFunc != null) try {
            receiver = beanFunc.apply(AccessibleHelp.forName(rpcPayload.className()));
        } catch (Throwable t) {
            return Response.fail(FailureMsg.fail(t), idPayload);
        }
        if (receiver == null) return Response.fail(ServerFailure.RPC_MISSING_INSTANCE, idPayload);
        Object invoke;
        try {
            Class[] ptypes = Arrays.stream(rpcPayload.ptypes()).map(AccessibleHelp::forName).toArray(Class[]::new);
            invoke = Validator.isBlank(rpcPayload.rtype())
                    ? AccessibleHelp.invoke(receiver, rpcPayload.methodName(), ptypes, rpcPayload.args())
                    : AccessibleHelp.invoke(receiver, rpcPayload.methodName(), AccessibleHelp.forName(rpcPayload.rtype()), ptypes, rpcPayload.args());
        } catch (Throwable t) {
            return Response.fail(FailureMsg.fail(t), idPayload);
        }
        if (invoke == null) return Response.ok(idPayload);
        if (invoke instanceof Response) {
            Response response = (Response) invoke;
            return Response.of(response, IdPayload.of(id, (R) response.getPayload()));
        }
        return Response.ok(IdPayload.of(id, (R) invoke));
    }

    public final  Response> invoke() {
        return invoke(AccessibleHelp::newObject);
    }

    public final ID id() {
        return id;
    }

    public final String version() {
        return version;
    }

    public final T payload() {
        return payload;
    }

    public final long timestamp() {
        return timestamp;
    }

    @Override
    public String toString() {
        return "Request{" +
                "id=" + id +
                ", version='" + version + '\'' +
                ", payload=" + payload +
                ", timestamp=" + timestamp +
                '}';
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy