
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