Package aQute.jsonrpc.proxy

Source Code of aQute.jsonrpc.proxy.JSONRPCProxy

package aQute.jsonrpc.proxy;

import java.io.*;
import java.lang.reflect.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;

import aQute.jsonrpc.domain.JSON.Request;
import aQute.jsonrpc.domain.JSON.Response;
import aQute.lib.collections.*;
import aQute.lib.converter.*;
import aQute.lib.hex.*;
import aQute.lib.json.*;
import aQute.rest.urlclient.*;

@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 URLClient          host;
  final String          endpoint;
  private final Executor      executor;

  private JSONRPCProxy(URLClient host, String endpoint, Executor executor) {
    this.endpoint = endpoint;
    this.host = host;
    this.executor = executor;
  }

  public static <T> T createRPC(Class<T> interf, URLClient host, String endpoint) throws Exception {
    return createRPC(interf, host, endpoint, null);
  }

  public static <T> T createRPC(Class<T> interf, URLClient host, String endpoint, Executor executor) throws Exception {
    return (T) Proxy.newProxyInstance(interf.getClassLoader(), new Class[] {
      interf
    }, new JSONRPCProxy(host, endpoint, executor));
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (executor != null)
      return invokeAsync(proxy, method, args);
    else
      return invokeSync(proxy, method, args);
  }

  private <Y> Y invokeAsync(final Object proxy, final Method method, final Object[] args) throws Exception {
    FutureTask<Y> task = new FutureTask<Y>(new Callable<Y>() {

      @Override
      public Y call() throws Exception {
        try {
          return invokeSync(proxy, method, args);
        }
        catch (Throwable e) {
          throw new InvocationTargetException(e);
        }
      }

    });
    executor.execute(task);
    lastcall.set(task);
    return (Y) converter.convert(method.getGenericReturnType(), null);
  }

  private <Y> Y invokeSync(Object proxy, Method method, Object[] args) throws Exception {
    Request request = new Request();
    request.id = counter.incrementAndGet();
    request.method = method.getName();
    request.params = new ExtList<Object>(args);

    Response response = host.put(JSONRPC_2_0 + endpoint, request, Response.class, null);

    if (response == null)
      throw new FileNotFoundException("Not found url endpoint: " + host.getUrl());

    if (response.error != null)
      throw new JSONRpcException(response.error);

    if (method.getReturnType() == void.class || method.getReturnType() == Void.class || response.result == null)
      return null;

    return (Y) converter.convert(method.getGenericReturnType(), response.result);
  }

  public static <T> Future<T> async(T returnValue) {
    return (Future<T>) lastcall.get();
  }
}
TOP

Related Classes of aQute.jsonrpc.proxy.JSONRPCProxy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.