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

as.leap.vertx.rpc.impl.RPCBase Maven / Gradle / Ivy

package as.leap.vertx.rpc.impl;

import as.leap.vertx.rpc.WireProtocol;
import io.protostuff.JsonIOUtil;
import io.protostuff.LinkedBuffer;
import io.protostuff.ProtobufIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;

import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;

/**
 * Created by stream.
 */
abstract class RPCBase {
  protected static final String CALLBACK_TYPE = "callbackType";

  private WireProtocol wireProtocol;

  public RPCBase(WireProtocol wireProtocol) {
    this.wireProtocol = wireProtocol;
  }

  void checkBusAddress(String address) {
    Objects.requireNonNull(address, "service's event bus address can not be null.");
  }

  boolean isWrapType(Class clazz) {
    return clazz.isPrimitive() || Collection.class.isAssignableFrom(clazz) || clazz.isArray()
        || Map.class.isAssignableFrom(clazz) || clazz.isEnum()
        || Modifier.isAbstract(clazz.getModifiers()) || Modifier.isInterface(clazz.getModifiers());
  }

  private  byte[] toBytes(Schema schema, T object) throws Exception {
    LinkedBuffer buffer = LinkedBuffer.allocate();
    byte[] bytes = new byte[0];
    try {
      switch (wireProtocol) {
        case PROTOBUF:
          bytes = ProtobufIOUtil.toByteArray(object, schema, buffer);
          break;
        case JSON:
          bytes = JsonIOUtil.toByteArray(object, schema, false, buffer);
          break;
      }
    } finally {
      buffer.clear();
    }
    return bytes;
  }

   byte[] getWrapTypeBytes(Object object, Class clazz) throws Exception {
    WrapperType wrapperType = new WrapperType(object, clazz);
    Schema schema = RuntimeSchema.getSchema(WrapperType.class);
    return toBytes(schema, wrapperType);
  }

   byte[] asBytes(T object) throws Exception {
    return asBytes(object, object.getClass());
  }

  byte[] asBytes(Object object, Class clazz) throws Exception {
    if (isWrapType(clazz)) {
      return getWrapTypeBytes(object, clazz);
    } else {
      Schema schema = RuntimeSchema.getSchema((Class) clazz);
      return toBytes(schema, object);
    }
  }

   T asObject(byte[] bytes, Class clazz) throws IOException {
    Schema schema = RuntimeSchema.getSchema(clazz);
    T object = schema.newMessage();
    switch (wireProtocol) {
      case PROTOBUF:
        ProtobufIOUtil.mergeFrom(bytes, object, schema);
        break;
      case JSON:
        //if length of bytes is zero, we have to wrap it as null.
        if (bytes.length == 0) object = null;
        else JsonIOUtil.mergeFrom(bytes, object, schema, false);
        break;
    }
    return object;
  }

  protected enum CallbackType {
    ASYNC_HANDLER, REACTIVE, COMPLETABLE_FUTURE, SYNC
  }
}