Example #1
0
  public OverloadedMethod add(MethodAccess methodAccess) {

    if (lock) {
      Exceptions.die();
    }

    methodAccessList.add(methodAccess);

    if (!methodAccess.method().isVarArgs()) {
      List<MethodAccess> methodAccesses =
          methodAccessListByArgNumber.get(methodAccess.parameterTypes().length);
      if (methodAccesses == null) {
        methodAccesses = new ArrayList<>();
        methodAccessListByArgNumber.set(methodAccess.parameterTypes().length, methodAccesses);
      }
      methodAccesses.add(methodAccess);
    } else {
      List<MethodAccess> methodAccesses =
          methodAccessListByArgNumberWithVarArg.get(methodAccess.parameterTypes().length);
      if (methodAccesses == null) {
        methodAccesses = new ArrayList<>();
        methodAccessListByArgNumberWithVarArg.set(
            methodAccess.parameterTypes().length, methodAccesses);
      }
      methodAccesses.add(methodAccess);
    }
    return this;
  }
Example #2
0
  private void invokeEventMethod(Event<Object> event, MethodAccess methodAccess, Object listener) {
    if (event.body() instanceof Object[]) {
      methodAccess.invokeDynamic(listener, (Object[]) event.body());
    } else if (event.body() instanceof List) {
      final List body = (List) event.body();
      methodAccess.invokeDynamic(listener, body.toArray(new Object[body.size()]));

    } else {
      methodAccess.invokeDynamic(listener, event.body());
    }
  }
Example #3
0
  @SuppressWarnings("Convert2Lambda")
  private void extractListenerForRegularObject(
      final Object listener,
      final MethodAccess methodAccess,
      final String channel,
      final boolean consume) {

    logger.info(
        "EventManager {}:: {} is listening with method {} on channel {} and is consuming? {}",
        name,
        listener.getClass().getSimpleName(),
        methodAccess.name(),
        channel,
        consume);
    if (consume) {

      /* Do not use Lambda, this has to be a consume! */
      this.register(
          channel,
          new EventConsumer<Object>() {
            @Override
            public void listen(Event<Object> event) {

              invokeEventMethod(event, methodAccess, listener);
            }
          });
    } else {
      /* Do not use Lambda, this has to be a subscriber! */
      this.register(
          channel,
          new EventSubscriber<Object>() {
            @Override
            public void listen(Event<Object> event) {

              invokeEventMethod(event, methodAccess, listener);
            }
          });
    }
  }
Example #4
0
  private void extractEventListenerFromMethod(
      final Object listener,
      final MethodAccess methodAccess,
      final AnnotationData listen,
      final ServiceQueue serviceQueue) {

    logger.info(
        "EventManager {} ::extractEventListenerFromMethod  :: "
            + "{} is listening with method {} using annotation data {} ",
        name,
        serviceQueue,
        methodAccess.name(),
        listen.getValues());

    final String channel = listen.getValues().get("value").toString();
    final boolean consume = (boolean) listen.getValues().get("consume");

    if (serviceQueue == null) {
      extractListenerForRegularObject(listener, methodAccess, channel, consume);
    } else {
      extractListenerForService(serviceQueue, channel, consume);
    }
  }
Example #5
0
  @Override
  public Object invokeDynamic(Object object, Object... args) {

    final int length = args.length;

    final List<MethodAccess> methodAccesses = this.methodAccessListByArgNumber.get(length);

    int maxScore = Integer.MIN_VALUE;
    MethodAccess methodAccess = null;

    for (MethodAccess m : methodAccesses) {
      int score = 1;
      final List<TypeType> paramTypeEnumList = m.paramTypeEnumList();

      if (object == null && !m.isStatic()) {
        continue;
      }

      loop:
      for (int argIndex = 0; argIndex < args.length; argIndex++) {

        TypeType type = paramTypeEnumList.get(argIndex);
        Object arg = args[argIndex];

        final TypeType instanceType = TypeType.getInstanceType(arg);

        if (instanceType == type) {
          score += 2_000;
          continue;
        }

        switch (type) {
          case BYTE_WRAPPER:
          case BYTE:
            score = handleByteArg(score, arg, instanceType);
            break;

          case SHORT_WRAPPER:
          case SHORT:
            score = handleShortArg(score, arg, instanceType);
            break;

          case INTEGER_WRAPPER:
          case INT:
            score = handleIntArg(score, arg, instanceType);
            break;

          case NULL:
            score--;
            break;

          case LONG_WRAPPER:
          case LONG:
            score = handleLongArg(score, arg, instanceType);
            break;

          case FLOAT_WRAPPER:
          case FLOAT:
            score = handleFloatArg(score, arg, instanceType);
            break;

          case DOUBLE_WRAPPER:
          case DOUBLE:
            score = handleDoubleArg(score, arg, instanceType);
            break;

          case CHAR_WRAPPER:
          case CHAR:
            if (instanceType == TypeType.CHAR || instanceType == TypeType.CHAR_WRAPPER) {
              score += 1000;
            }
            break;

          case STRING:
            if (instanceType == TypeType.STRING) {
              score += 1_000;
            } else if (instanceType == TypeType.CHAR_SEQUENCE || arg instanceof CharSequence) {
              score += 500;
            }
            break;

          case INSTANCE:
            if (instanceType == TypeType.INSTANCE) {
              if (m.parameterTypes()[argIndex].isInstance(arg)) {
                score += 1000;
              }
            } else if (instanceType == TypeType.MAP) {
              score += 1_000;
            } else if (instanceType == TypeType.LIST) {
              score += 500;
            }
            break;

          default:
            if (instanceType == type) {
              score += 1000;
            } else {
              if (m.parameterTypes()[argIndex].isInstance(arg)) {
                score += 1000;
              }
            }
        }
      }

      if (score > maxScore) {
        maxScore = score;
        methodAccess = m;
      }
    }

    if (methodAccess != null) {
      return methodAccess.invokeDynamic(object, args);
    } else {
      /* Place holder for now. */
      List<MethodAccess> varargMethods = this.methodAccessListByArgNumberWithVarArg.get(0);
      if (varargMethods != null) {
        varargMethods.get(0).invokeDynamic(args);
      }
    }

    return null;
  }
Example #6
0
  private void doListen(final Object listener, final ServiceQueue serviceQueue) {

    if (debug) {
      logger.debug(
          "EventManager {}  registering listener {} with serviceQueue {}",
          name,
          listener,
          serviceQueue);
    }
    final ClassMeta<?> listenerClassMeta = ClassMeta.classMeta(listener.getClass());
    final Iterable<MethodAccess> listenerMethods = listenerClassMeta.methods();

    /* Add methods as listeners if they have a listen annotation. */
    for (final MethodAccess methodAccess : listenerMethods) {
      AnnotationData listenAnnotationData = getListenAnnotation(methodAccess);
      if (listenAnnotationData == null) continue;
      extractEventListenerFromMethod(listener, methodAccess, listenAnnotationData, serviceQueue);
    }

    /* Look for listener channel implementations. */
    final Class<?>[] interfacesFromListener = listenerClassMeta.cls().getInterfaces();

    /* Iterate through interfaces and see if any are marked with the event channel annotation. */
    for (Class<?> interfaceClass : interfacesFromListener) {
      final ClassMeta<?> metaFromListenerInterface = classMeta(interfaceClass);

      final AnnotationData eventChannelAnnotation =
          metaFromListenerInterface.annotation(AnnotationUtils.EVENT_CHANNEL_ANNOTATION_NAME);
      if (eventChannelAnnotation == null) {
        continue;
      }

      /* If we got this far, then we are dealing with an event channel interface
      so register the methods from this interface as channel listeners.
       */
      final Iterable<MethodAccess> interfaceMethods = metaFromListenerInterface.methods();

      final String classEventBusName =
          getClassEventChannelName(metaFromListenerInterface, eventChannelAnnotation);

      for (MethodAccess methodAccess : interfaceMethods) {

        /* By default the method name forms part of the event bus name,
        but this can be overridden by the EVENT_CHANNEL_ANNOTATION_NAME annotation on the method.
         */
        final AnnotationData methodAnnotation =
            methodAccess.annotation(AnnotationUtils.EVENT_CHANNEL_ANNOTATION_NAME);

        String methodEventBusName =
            methodAnnotation != null && methodAnnotation.getValues().get("value") != null
                ? methodAnnotation.getValues().get("value").toString()
                : null;

        if (Str.isEmpty(methodEventBusName)) {
          methodEventBusName = methodAccess.name();
        }

        final String channelName = createChannelName(null, classEventBusName, methodEventBusName);

        if (serviceQueue == null) {
          extractListenerForRegularObject(listener, methodAccess, channelName, false);
        } else {
          extractListenerForService(serviceQueue, channelName, false);
        }
      }
    }
  }
Example #7
0
  public Response<Object> mapArgsAsyncHandlersAndInvoke(
      MethodCall<Object> serviceMethodCall, MethodAccess serviceMethod) {

    if (serviceMethod.parameterTypes().length == 0
        && !(serviceMethod.returnType() == Promise.class)) {

      Object returnValue =
          serviceMethod.invokeDynamicObject(boonServiceMethodCallHandler.service, null);
      return boonServiceMethodCallHandler.response(serviceMethod, serviceMethodCall, returnValue);
    }

    boolean hasHandlers =
        boonServiceMethodCallHandler.hasHandlers(serviceMethodCall, serviceMethod);

    Object returnValue;

    if (hasHandlers) {
      Object body = serviceMethodCall.body();
      List<Object> argsList =
          boonServiceMethodCallHandler.prepareArgumentList(
              serviceMethodCall, serviceMethod.parameterTypes());
      if (body instanceof List || body instanceof Object[]) {
        boonServiceMethodCallHandler.extractHandlersFromArgumentList(
            serviceMethodCall.callback(), serviceMethod, body, argsList);
      } else {
        if (argsList.size() == 1 && !(argsList.get(0) instanceof Callback)) {
          argsList.set(0, body);
        }
      }
      returnValue =
          serviceMethod.invokeDynamicObject(boonServiceMethodCallHandler.service, argsList);

      if (returnValue instanceof Promise) {
        final Promise<Object> promise = ((Promise<Object>) returnValue);
        promise
            .then(
                value -> {
                  boonServiceMethodCallHandler.responseSendQueue.send(
                      ResponseImpl.response(serviceMethodCall, value));
                })
            .catchError(
                error -> {
                  boonServiceMethodCallHandler.responseSendQueue.send(
                      ResponseImpl.error(serviceMethodCall, error));
                })
            .invoke();

        return ServiceConstants.VOID;
      }

    } else {
      if (serviceMethodCall.body() instanceof List) {
        final List argsList = (List) serviceMethodCall.body();
        returnValue =
            serviceMethod.invokeDynamic(
                boonServiceMethodCallHandler.service,
                argsList.toArray(new Object[argsList.size()]));
      } else if (serviceMethodCall.body() instanceof Object[]) {
        final Object[] argsList = (Object[]) serviceMethodCall.body();
        returnValue = serviceMethod.invokeDynamic(boonServiceMethodCallHandler.service, argsList);
      } else {
        returnValue =
            serviceMethod.invokeDynamic(
                boonServiceMethodCallHandler.service, serviceMethodCall.body());
      }
    }

    return boonServiceMethodCallHandler.response(serviceMethod, serviceMethodCall, returnValue);
  }