package com.github.aesteve.vertx.nubes.handlers.impl; import com.github.aesteve.vertx.nubes.Config; import com.github.aesteve.vertx.nubes.exceptions.params.WrongParameterException; import com.github.aesteve.vertx.nubes.handlers.AbstractMethodInvocationHandler; import com.github.aesteve.vertx.nubes.marshallers.Payload; import io.vertx.core.http.HttpServerResponse; import io.vertx.core.logging.Logger; import io.vertx.core.logging.LoggerFactory; import io.vertx.ext.web.RoutingContext; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.function.BiConsumer; public class DefaultMethodInvocationHandler<T> extends AbstractMethodInvocationHandler<T> { private static final Logger LOG = LoggerFactory.getLogger(DefaultMethodInvocationHandler.class); public DefaultMethodInvocationHandler(Object instance, Method method, Config config, boolean hasNext, BiConsumer<RoutingContext, T> returnHandler) { super(instance, method, config, hasNext, returnHandler); } @Override public void handle(RoutingContext routingContext) { if (routingContext.response().ended()) { return; } if (routingContext.failed()) { return; } Object[] parameters; try { parameters = getParameters(routingContext); } catch (WrongParameterException e) { //NOSONAR DefaultErrorHandler.badRequest(routingContext, e.getMessage()); return; } try { handleInvokation(routingContext, parameters); } catch (InvocationTargetException | IllegalAccessException ite) { LOG.error(ite); routingContext.fail(ite.getCause()); } } @SuppressWarnings("unchecked") private void handleInvokation(RoutingContext routingContext, Object[] parameters) throws IllegalAccessException, InvocationTargetException { final T returned = (T) method.invoke(instance, parameters); if (returnsSomething) { handleMethodReturn(routingContext, returned); } if (!usesRoutingContext && hasNext) { // cannot call context.next(), assume the method is sync routingContext.next(); } if (!usesRoutingContext && !usesHttpResponse && !hasNext) { sendResponse(routingContext); } } private void sendResponse(RoutingContext routingContext) { HttpServerResponse response = routingContext.response(); try { response.setStatusCode(204); response.end(); } catch (IllegalStateException ise) { //NOSONAR // do not log for the user, this means the response has already been written // that'd mean something is wrong with the **framework** not users' code routingContext.next(); } } private void handleMethodReturn(RoutingContext routingContext, T returned) { final boolean contentTypeSet = routingContext.get(ContentTypeProcessor.BEST_CONTENT_TYPE) != null; if (returnHandler != null) { returnHandler.accept(routingContext, returned); } else if (hasNext && contentTypeSet) { // try to set as Payload Payload<Object> payload = routingContext.get(Payload.DATA_ATTR); if (payload == null) { payload = new Payload<>(); routingContext.put(Payload.DATA_ATTR, payload); } payload.set(returned); } else if (returned instanceof String) { routingContext.response().end((String) returned); } } }