Skip to content

Commit c42a6a2

Browse files
committed
allow for resource methods to return <? extends XYZ>
Signed-off-by: jansupol <jan.supol@oracle.com>
1 parent 1f0dbfa commit c42a6a2

File tree

3 files changed

+87
-4
lines changed

3 files changed

+87
-4
lines changed

core-server/src/main/java/org/glassfish/jersey/server/ContainerResponse.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -21,6 +21,8 @@
2121
import java.lang.annotation.Annotation;
2222
import java.lang.reflect.ParameterizedType;
2323
import java.lang.reflect.Type;
24+
import java.lang.reflect.TypeVariable;
25+
import java.lang.reflect.WildcardType;
2426
import java.net.URI;
2527
import java.util.Date;
2628
import java.util.Locale;
@@ -308,6 +310,18 @@ public void setEntityType(final Type type) {
308310
if (parameterizedType.getRawType().equals(GenericEntity.class)) {
309311
t = parameterizedType.getActualTypeArguments()[0];
310312
}
313+
} else if (type instanceof TypeVariable) {
314+
final TypeVariable typeVariable = (TypeVariable) type;
315+
final Type[] bounds = typeVariable.getBounds();
316+
if (bounds.length == 1) {
317+
t = bounds[0];
318+
}
319+
} else if (type instanceof WildcardType) {
320+
final WildcardType wildcardType = (WildcardType) type;
321+
final Type[] bounds = wildcardType.getUpperBounds();
322+
if (bounds.length == 1) {
323+
t = bounds[0];
324+
}
311325
}
312326

313327
messageContext.setEntityType(t);

tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/CompletionStageTest.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2022 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2023 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -18,7 +18,6 @@
1818

1919
import org.glassfish.jersey.server.ResourceConfig;
2020
import org.glassfish.jersey.server.ServerProperties;
21-
import org.glassfish.jersey.server.ServerRuntime;
2221
import org.glassfish.jersey.test.JerseyTest;
2322
import org.junit.jupiter.api.Test;
2423

@@ -160,7 +159,15 @@ public void test4463() {
160159

161160
@Test
162161
public void testCompletionStageUnwrappedInGenericType() {
163-
try (Response r = target("cs/databeanlist").request().get()){
162+
try (Response r = target("cs/databeanlist").request().get()) {
163+
assertEquals(200, r.getStatus());
164+
assertTrue(r.readEntity(String.class).startsWith(ENTITY));
165+
}
166+
}
167+
168+
@Test
169+
void testExtends() {
170+
try (Response r = target("cs/csextends").request().get()) {
164171
assertEquals(200, r.getStatus());
165172
assertTrue(r.readEntity(String.class).startsWith(ENTITY));
166173
}
@@ -291,6 +298,12 @@ public CompletionStage<String> getCustomCompletionStageAsync() {
291298
return cs;
292299
}
293300

301+
@GET
302+
@Path("csextends")
303+
public CompletionStage<? extends CharSequence> csExtends() {
304+
return CompletableFuture.completedFuture(ENTITY);
305+
}
306+
294307
private void delaySubmit(Runnable runnable) {
295308
EXECUTOR_SERVICE.submit(() -> {
296309
try {
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package org.glassfish.jersey.tests.e2e.server;
18+
19+
import org.glassfish.jersey.server.ResourceConfig;
20+
import org.glassfish.jersey.test.JerseyTest;
21+
import org.junit.jupiter.api.Test;
22+
23+
import javax.ws.rs.GET;
24+
import javax.ws.rs.Path;
25+
import javax.ws.rs.core.Application;
26+
import javax.ws.rs.core.Response;
27+
28+
import static org.junit.jupiter.api.Assertions.assertEquals;
29+
import static org.junit.jupiter.api.Assertions.assertTrue;
30+
31+
class TypedVariableTest extends JerseyTest {
32+
33+
private static final String ENTITY = "entity";
34+
35+
@Path("/typed")
36+
public static class Resource {
37+
@GET
38+
@Path("extends")
39+
public <T extends CharSequence> T justExtends() {
40+
return (T) ENTITY;
41+
}
42+
}
43+
44+
@Override
45+
protected Application configure() {
46+
return new ResourceConfig(Resource.class);
47+
}
48+
49+
@Test
50+
void testExtends() {
51+
try (Response r = target("typed/extends").request().get()) {
52+
assertEquals(200, r.getStatus());
53+
assertTrue(r.readEntity(String.class).startsWith(ENTITY));
54+
}
55+
}
56+
}

0 commit comments

Comments
 (0)