package aQute.bnd.jpm.util; import java.io.FileNotFoundException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.Type; import java.net.URI; import java.util.concurrent.Executor; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicLong; import aQute.bnd.http.HttpClient; import aQute.jsonrpc.domain.JSON.Request; import aQute.jsonrpc.domain.JSON.Response; import aQute.lib.collections.ExtList; import aQute.lib.converter.Converter; import aQute.lib.hex.Hex; import aQute.lib.json.JSONCodec; @SuppressWarnings("unchecked") public class JSONRPCProxy implements InvocationHandler { public static final String JSONRPC_2_0 = "jsonrpc/2.0/"; static AtomicLong counter = new AtomicLong(System.currentTimeMillis()); static JSONCodec codec = new JSONCodec(); static Converter converter = new Converter(); static ThreadLocal<Future< ? >> lastcall = new ThreadLocal<Future< ? >>(); static { converter.hook(byte[].class, new Converter.Hook() { @Override public Object convert(Type dest, Object o) throws Exception { if (o instanceof String) { return Hex.toByteArray((String) o); } return null; } }); } final HttpClient host; final URI endpoint; private JSONRPCProxy(HttpClient host, URI endpoint) { this.endpoint = endpoint; this.host = host; } public static <T> T createRPC(Class<T> interf, HttpClient host, URI endpoint) throws Exception { return createRPC(interf, host, endpoint, null); } public static <T> T createRPC(Class<T> interf, HttpClient host, URI endpoint, Executor executor) throws Exception { return (T) Proxy.newProxyInstance(interf.getClassLoader(), new Class[] { interf }, new JSONRPCProxy(host, endpoint)); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Request request = new Request(); request.id = counter.incrementAndGet(); request.method = method.getName(); request.params = new ExtList<Object>(args); Response response = host.build().upload(request).put().get(Response.class).go(endpoint.toURL()); if (response == null) throw new FileNotFoundException("Not found url endpoint: " + endpoint); if (method.getReturnType() == void.class || method.getReturnType() == Void.class || response.result == null) return null; return converter.convert(method.getGenericReturnType(), response.result); } }