From bf9da5e5898fc78ec6290940c2d3b3a40ab8ed7b Mon Sep 17 00:00:00 2001 From: jansupol Date: Fri, 12 May 2023 21:11:01 +0200 Subject: [PATCH] allow for resource methods to return Signed-off-by: jansupol --- .../jersey/server/ContainerResponse.java | 16 +++++- .../tests/e2e/server/CompletionStageTest.java | 19 ++++++- .../tests/e2e/server/TypedVariableTest.java | 56 +++++++++++++++++++ 3 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/TypedVariableTest.java diff --git a/core-server/src/main/java/org/glassfish/jersey/server/ContainerResponse.java b/core-server/src/main/java/org/glassfish/jersey/server/ContainerResponse.java index 5e0a1e8389..cf6799ed25 100644 --- a/core-server/src/main/java/org/glassfish/jersey/server/ContainerResponse.java +++ b/core-server/src/main/java/org/glassfish/jersey/server/ContainerResponse.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -21,6 +21,8 @@ import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.lang.reflect.WildcardType; import java.net.URI; import java.util.Date; import java.util.Locale; @@ -308,6 +310,18 @@ public void setEntityType(final Type type) { if (parameterizedType.getRawType().equals(GenericEntity.class)) { t = parameterizedType.getActualTypeArguments()[0]; } + } else if (type instanceof TypeVariable) { + final TypeVariable typeVariable = (TypeVariable) type; + final Type[] bounds = typeVariable.getBounds(); + if (bounds.length == 1) { + t = bounds[0]; + } + } else if (type instanceof WildcardType) { + final WildcardType wildcardType = (WildcardType) type; + final Type[] bounds = wildcardType.getUpperBounds(); + if (bounds.length == 1) { + t = bounds[0]; + } } messageContext.setEntityType(t); diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/CompletionStageTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/CompletionStageTest.java index 262bd0eb2f..205a5ff5bf 100644 --- a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/CompletionStageTest.java +++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/CompletionStageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -18,7 +18,6 @@ import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.ServerProperties; -import org.glassfish.jersey.server.ServerRuntime; import org.glassfish.jersey.test.JerseyTest; import org.junit.jupiter.api.Test; @@ -160,7 +159,15 @@ public void test4463() { @Test public void testCompletionStageUnwrappedInGenericType() { - try (Response r = target("cs/databeanlist").request().get()){ + try (Response r = target("cs/databeanlist").request().get()) { + assertEquals(200, r.getStatus()); + assertTrue(r.readEntity(String.class).startsWith(ENTITY)); + } + } + + @Test + void testExtends() { + try (Response r = target("cs/csextends").request().get()) { assertEquals(200, r.getStatus()); assertTrue(r.readEntity(String.class).startsWith(ENTITY)); } @@ -291,6 +298,12 @@ public CompletionStage getCustomCompletionStageAsync() { return cs; } + @GET + @Path("csextends") + public CompletionStage csExtends() { + return CompletableFuture.completedFuture(ENTITY); + } + private void delaySubmit(Runnable runnable) { EXECUTOR_SERVICE.submit(() -> { try { diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/TypedVariableTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/TypedVariableTest.java new file mode 100644 index 0000000000..bb8369cd7a --- /dev/null +++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/TypedVariableTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.tests.e2e.server; + +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.test.JerseyTest; +import org.junit.jupiter.api.Test; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.core.Application; +import javax.ws.rs.core.Response; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class TypedVariableTest extends JerseyTest { + + private static final String ENTITY = "entity"; + + @Path("/typed") + public static class Resource { + @GET + @Path("extends") + public T justExtends() { + return (T) ENTITY; + } + } + + @Override + protected Application configure() { + return new ResourceConfig(Resource.class); + } + + @Test + void testExtends() { + try (Response r = target("typed/extends").request().get()) { + assertEquals(200, r.getStatus()); + assertTrue(r.readEntity(String.class).startsWith(ENTITY)); + } + } +}