From ddad406347662d9310a8830b6c11e542e9762222 Mon Sep 17 00:00:00 2001 From: Thomas Segismont Date: Wed, 8 Jan 2025 17:49:21 +0100 Subject: [PATCH] Improve conversion of Mutiny handlers This is port of https://github.com/vert-x3/vertx-rx/pull/324 It fixes Vert.x Web router (and others) that is broken with Mutiny API. See https://github.com/vert-x3/vertx-rx/issues/314 The purpose of this change is to avoid decorating handlers if they are instances of a generated Mutiny type (e.g. io.vertx.mutiny.ext.web.handler.StaticHandler). --- .../smallrye/mutiny/vertx/MutinyDelegate.java | 13 ++++++++++ .../smallrye/mutiny/vertx/MutinyHelper.java | 24 +++++++++++++++++++ .../lang/ClassDeclarationCodeWriter.java | 1 + .../vertx/codegen/lang/CodeGenHelper.java | 4 ++-- .../lang/GetDelegateMethodCodeWriter.java | 1 + .../methods/ConsumerMethodGenerator.java | 2 +- 6 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 vertx-mutiny-clients/vertx-mutiny-runtime/src/main/java/io/smallrye/mutiny/vertx/MutinyDelegate.java diff --git a/vertx-mutiny-clients/vertx-mutiny-runtime/src/main/java/io/smallrye/mutiny/vertx/MutinyDelegate.java b/vertx-mutiny-clients/vertx-mutiny-runtime/src/main/java/io/smallrye/mutiny/vertx/MutinyDelegate.java new file mode 100644 index 0000000000..ad7913af24 --- /dev/null +++ b/vertx-mutiny-clients/vertx-mutiny-runtime/src/main/java/io/smallrye/mutiny/vertx/MutinyDelegate.java @@ -0,0 +1,13 @@ +package io.smallrye.mutiny.vertx; + +/** + * Interface implemented by every generated Mutiny type. + */ +public interface MutinyDelegate { + + /** + * @return the delegate used by this Mutiny object of generated type + */ + Object getDelegate(); + +} diff --git a/vertx-mutiny-clients/vertx-mutiny-runtime/src/main/java/io/smallrye/mutiny/vertx/MutinyHelper.java b/vertx-mutiny-clients/vertx-mutiny-runtime/src/main/java/io/smallrye/mutiny/vertx/MutinyHelper.java index f20d4f0b22..6028b056ec 100644 --- a/vertx-mutiny-clients/vertx-mutiny-runtime/src/main/java/io/smallrye/mutiny/vertx/MutinyHelper.java +++ b/vertx-mutiny-clients/vertx-mutiny-runtime/src/main/java/io/smallrye/mutiny/vertx/MutinyHelper.java @@ -2,13 +2,16 @@ import java.util.concurrent.Executor; import java.util.concurrent.Flow.Subscriber; +import java.util.function.Consumer; import java.util.function.Function; import io.smallrye.mutiny.vertx.impl.WriteStreamSubscriberImpl; +import io.vertx.core.Handler; import io.vertx.core.Vertx; import io.vertx.core.WorkerExecutor; import io.vertx.core.streams.WriteStream; +@SuppressWarnings({ "unchecked", "rawtypes" }) public class MutinyHelper { /** @@ -94,6 +97,27 @@ public static Class unwrap(Class type) { return type; } + /** + * Convert a handler for a generated Mutiny type to a handler for the corresponding core type. + */ + public static Handler convertHandler(Handler mutinyHandler, Function mapper) { + if (mutinyHandler instanceof MutinyDelegate) { + MutinyDelegate mutinyDelegate = (MutinyDelegate) mutinyHandler; + return (Handler) mutinyDelegate.getDelegate(); + } + return new DelegatingHandler<>(mutinyHandler, mapper); + } + + /** + * Convert a consumer for a generated Mutiny type to a handler of the same type. + */ + public static Handler convertConsumer(Consumer mutinyConsumer) { + if (mutinyConsumer instanceof MutinyDelegate) { + return (Handler) mutinyConsumer; + } + return mutinyConsumer != null ? new DelegatingConsumerHandler<>(mutinyConsumer) : null; + } + /** * Adapts a Vert.x {@link WriteStream} to a Mutiny {@link Subscriber}. *

diff --git a/vertx-mutiny-generator/src/main/java/io/smallrye/mutiny/vertx/codegen/lang/ClassDeclarationCodeWriter.java b/vertx-mutiny-generator/src/main/java/io/smallrye/mutiny/vertx/codegen/lang/ClassDeclarationCodeWriter.java index a082867090..3f49ad7daa 100644 --- a/vertx-mutiny-generator/src/main/java/io/smallrye/mutiny/vertx/codegen/lang/ClassDeclarationCodeWriter.java +++ b/vertx-mutiny-generator/src/main/java/io/smallrye/mutiny/vertx/codegen/lang/ClassDeclarationCodeWriter.java @@ -32,6 +32,7 @@ public void generate(ClassModel model, PrintWriter writer) { } List interfaces = new ArrayList<>(); + interfaces.add("io.smallrye.mutiny.vertx.MutinyDelegate"); if ("io.vertx.core.buffer.Buffer".equals(type.getName())) { interfaces.add("io.vertx.core.shareddata.impl.ClusterSerializable"); } diff --git a/vertx-mutiny-generator/src/main/java/io/smallrye/mutiny/vertx/codegen/lang/CodeGenHelper.java b/vertx-mutiny-generator/src/main/java/io/smallrye/mutiny/vertx/codegen/lang/CodeGenHelper.java index 61e699b293..8ef990c777 100644 --- a/vertx-mutiny-generator/src/main/java/io/smallrye/mutiny/vertx/codegen/lang/CodeGenHelper.java +++ b/vertx-mutiny-generator/src/main/java/io/smallrye/mutiny/vertx/codegen/lang/CodeGenHelper.java @@ -190,7 +190,7 @@ public static String genConvParam(Map> methodT ClassKind eventKind = eventType.getKind(); if (eventKind == ASYNC_RESULT) { TypeInfo resultType = ((ParameterizedTypeInfo) eventType).getArg(0); - return "new io.smallrye.mutiny.vertx.DelegatingHandler<>(" + expr + ", ar -> ar.map(event -> " + genConvReturn(methodTypeArgMap, resultType, method, "event") + "))"; + return "io.smallrye.mutiny.vertx.MutinyHelper.convertHandler(" + expr + ", ar -> ar.map(event -> " + genConvReturn(methodTypeArgMap, resultType, method, "event") + "))"; } else if (eventType.isParameterized() && eventType.getRaw().getName().equals(Promise.class.getName())) { return "new Handler<" + genTypeName(eventType) + ">() {\n" + " public void handle(" + genTypeName(eventType) + " event) {\n" + @@ -198,7 +198,7 @@ public static String genConvParam(Map> methodT " }\n" + " }"; } else { - return "new io.smallrye.mutiny.vertx.DelegatingHandler<>(" + expr + ", event -> " + genConvReturn(methodTypeArgMap, eventType, method, "event") + ")"; + return "io.smallrye.mutiny.vertx.MutinyHelper.convertHandler(" + expr + ", event -> " + genConvReturn(methodTypeArgMap, eventType, method, "event") + ")"; } } else if (kind == FUNCTION) { TypeInfo argType = parameterizedTypeInfo.getArg(0); diff --git a/vertx-mutiny-generator/src/main/java/io/smallrye/mutiny/vertx/codegen/lang/GetDelegateMethodCodeWriter.java b/vertx-mutiny-generator/src/main/java/io/smallrye/mutiny/vertx/codegen/lang/GetDelegateMethodCodeWriter.java index 4dbb867859..579130a687 100644 --- a/vertx-mutiny-generator/src/main/java/io/smallrye/mutiny/vertx/codegen/lang/GetDelegateMethodCodeWriter.java +++ b/vertx-mutiny-generator/src/main/java/io/smallrye/mutiny/vertx/codegen/lang/GetDelegateMethodCodeWriter.java @@ -7,6 +7,7 @@ public class GetDelegateMethodCodeWriter implements ConditionalCodeWriter { @Override public void generate(ClassModel model, PrintWriter writer) { + writer.println(" @Override"); writer.print(" public "); writer.print(model.getType().getName()); writer.println(" getDelegate() {"); diff --git a/vertx-mutiny-generator/src/main/java/io/smallrye/mutiny/vertx/codegen/methods/ConsumerMethodGenerator.java b/vertx-mutiny-generator/src/main/java/io/smallrye/mutiny/vertx/codegen/methods/ConsumerMethodGenerator.java index a5c8ceab86..735866e920 100644 --- a/vertx-mutiny-generator/src/main/java/io/smallrye/mutiny/vertx/codegen/methods/ConsumerMethodGenerator.java +++ b/vertx-mutiny-generator/src/main/java/io/smallrye/mutiny/vertx/codegen/methods/ConsumerMethodGenerator.java @@ -60,7 +60,7 @@ private void generateBody(MutinyMethodDescriptor descriptor) { } else if(param.getType().getName().equals(Runnable.class.getName())) { writer.println("ignored -> " + param.getName() + ".run()"); } else { - writer.print(param.getName() + " != null ? new io.smallrye.mutiny.vertx.DelegatingConsumerHandler(" + param.getName() + ") : null"); + writer.print("io.smallrye.mutiny.vertx.MutinyHelper.convertConsumer(" + param.getName() + ")"); } } }