From e54c0e09edbd0457725fcca8fb7b63761d2b301b Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Wed, 6 Sep 2023 14:35:56 +0300 Subject: [PATCH] Fix generic handling of ParamConverter Fixes: #35774 (cherry picked from commit c3479a053cc89bcf4c5d4e46f0115e3d37456c12) --- .../simple/GenericsParamConverterTest.java | 109 ++++++++++++++++++ .../startup/RuntimeResourceDeployment.java | 2 + 2 files changed, 111 insertions(+) create mode 100644 extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/GenericsParamConverterTest.java diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/GenericsParamConverterTest.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/GenericsParamConverterTest.java new file mode 100644 index 0000000000000..f2ff7dd22e7cf --- /dev/null +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/GenericsParamConverterTest.java @@ -0,0 +1,109 @@ +package io.quarkus.resteasy.reactive.server.test.simple; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.is; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.List; +import java.util.stream.Collectors; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.QueryParam; +import jakarta.ws.rs.ext.ParamConverter; +import jakarta.ws.rs.ext.ParamConverterProvider; +import jakarta.ws.rs.ext.Provider; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; + +public class GenericsParamConverterTest { + + @RegisterExtension + static QuarkusUnitTest test = new QuarkusUnitTest() + .withApplicationRoot((jar) -> jar + .addClasses(TestEnum.class, Wrapper.class, + WrapperParamConverterProvider.class, WrapperParamConverterProvider.WrapperParamConverter.class, + TestResource.class)); + + @Test + public void wrapper() { + given() + .when().get("/test/single?wrapper=ACTIVE") + .then() + .statusCode(200) + .body(is("ACTIVE")); + } + + @Test + public void wrapperList() { + given() + .when().get("/test/list?wrapperList=INACTIVE&wrapperList=ACTIVE") + .then() + .statusCode(200) + .body(is("INACTIVE,ACTIVE")); + } + + @Path("/test") + public static class TestResource { + + @GET + @Path("/list") + public String list(@QueryParam("wrapperList") final List> wrapperList) { + return wrapperList.stream().map(w -> w.getValue().name()).collect(Collectors.joining(",")); + } + + @GET + @Path("/single") + public String single(@QueryParam("wrapper") final Wrapper wrapper) { + return wrapper.getValue().toString(); + } + } + + public enum TestEnum { + ACTIVE, + INACTIVE + } + + public static class Wrapper> { + private final E value; + + public Wrapper(final E value) { + this.value = value; + } + + public E getValue() { + return value; + } + } + + @Provider + public static class WrapperParamConverterProvider implements ParamConverterProvider { + + @Override + @SuppressWarnings("unchecked") + public ParamConverter getConverter(final Class rawType, final Type genericType, + final Annotation[] annotations) { + if (Wrapper.class.isAssignableFrom(rawType)) { + return (ParamConverter) new WrapperParamConverter(); + } + return null; + } + + public static class WrapperParamConverter implements ParamConverter> { + + @Override + public Wrapper fromString(String value) { + return new Wrapper<>(Enum.valueOf(TestEnum.class, value)); + } + + @Override + public String toString(Wrapper wrapper) { + return wrapper != null ? wrapper.getValue().toString() : null; + } + } + } +} diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/startup/RuntimeResourceDeployment.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/startup/RuntimeResourceDeployment.java index f3ef562e331b5..452207eb3770d 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/startup/RuntimeResourceDeployment.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/startup/RuntimeResourceDeployment.java @@ -527,6 +527,8 @@ private static void smartInitParameterConverter(int i, ParameterConverter quarku Type genericType = genericArguments[0]; if (genericType instanceof Class) { genericTypeClassName = ((Class) genericType).getName(); + } else if (genericType instanceof ParameterizedType) { + genericTypeClassName = ((ParameterizedType) genericType).getRawType().getTypeName(); } else if (genericType instanceof WildcardType) { WildcardType genericTypeWildcardType = (WildcardType) genericType; Type[] upperBounds = genericTypeWildcardType.getUpperBounds();