From 21714bfb49efea101e940cc7b0e7d3014ba2aa41 Mon Sep 17 00:00:00 2001 From: jansupol Date: Mon, 25 Mar 2024 22:05:30 +0100 Subject: [PATCH] Added List UriInfo#getMatchedResourceTemplates() Signed-off-by: jansupol --- .../main/java/jakarta/ws/rs/core/UriInfo.java | 68 +++++++++ .../ee/rs/core/uriinfo/TSAppConfig.java | 33 +++++ .../ee/rs/core/uriinfo/UriInfo40ClientIT.java | 130 ++++++++++++++++++ .../rs/core/uriinfo/UriInfoTestResource.java | 69 ++++++++++ 4 files changed, 300 insertions(+) create mode 100644 jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/TSAppConfig.java create mode 100644 jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/UriInfo40ClientIT.java create mode 100644 jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/UriInfoTestResource.java diff --git a/jaxrs-api/src/main/java/jakarta/ws/rs/core/UriInfo.java b/jaxrs-api/src/main/java/jakarta/ws/rs/core/UriInfo.java index 26a0a9f3a..0277c5ac0 100644 --- a/jaxrs-api/src/main/java/jakarta/ws/rs/core/UriInfo.java +++ b/jaxrs-api/src/main/java/jakarta/ws/rs/core/UriInfo.java @@ -16,6 +16,9 @@ package jakarta.ws.rs.core; +import jakarta.ws.rs.ApplicationPath; +import jakarta.ws.rs.Path; + import java.net.URI; import java.util.List; @@ -246,6 +249,71 @@ public interface UriInfo { */ public List getMatchedURIs(boolean decode); + /** + *

+ * Get a list of URI templates that contains all {@link Path Paths} templates (including {@link ApplicationPath} value if any) + * matched by the current request's URI. + *

+ *

+ * Each entry is {@link Path} value used to match a resource class, a sub-resource method or a sub-resource locator. + * The template does not include query parameters but does include matrix parameters + * if present in the request URI. The list is ordered in the request URI matching order, with the {@link ApplicationPath} + * value first, and with the current resource last. E.g. given the following resource classes: + *

+ * + *
+     * @Path("foo")
+     * public class FooResource {
+     *  @GET
+     *  @Path("{foo:[f-z][a-z]*}")
+     *  public String getFoo() {...}
+     *
+     *  @Path("{bar:[b-e][a-z]*}")
+     *  public BarResource getBarResource() {...}
+     * }
+     *
+     * public class BarResource {
+     *  @GET
+     *  @Path("{id}{id:[0-9]}")
+     *  public String getBar() {...}
+     * }
+     * 
+ * + *

+ * The values returned by this method based on request uri and where the method is called from are: + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Matched URIs from requests
RequestCalled fromValue(s)
GET /fooFooResource.getFoo/foo, /{foo:[f-z][a-z]*}
GET /foo/barFooResource.getBarResource/foo, /{bar:[b-e][a-z]*}
GET /foo/bar/id0BarResource.getBar/foo, /{bar:[b-e][a-z]*}, /{id}{id:[0-9]}
+ * + * In case the method is invoked prior to the request matching (e.g. from a pre-matching filter), the method returns an + * empty string. + * + * @return A list of {@link Path} templates. + */ + public List getMatchedResourceTemplates(); + /** * Get a read-only list of the currently matched resource class instances. * diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/TSAppConfig.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/TSAppConfig.java new file mode 100644 index 000000000..afcfddae8 --- /dev/null +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/TSAppConfig.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 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 ee.jakarta.tck.ws.rs.jaxrs40.ee.rs.core.uriinfo; + +import jakarta.ws.rs.ApplicationPath; +import jakarta.ws.rs.core.Application; + +import java.util.HashSet; +import java.util.Set; + +@ApplicationPath("/app") +public class TSAppConfig extends Application { + + public Set> getClasses() { + Set> resources = new HashSet>(); + resources.add(UriInfoTestResource.class); + return resources; + } +} diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/UriInfo40ClientIT.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/UriInfo40ClientIT.java new file mode 100644 index 000000000..2e22b151e --- /dev/null +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/UriInfo40ClientIT.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2024 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 ee.jakarta.tck.ws.rs.jaxrs40.ee.rs.core.uriinfo; + +import ee.jakarta.tck.ws.rs.common.JAXRSCommonClient; +import ee.jakarta.tck.ws.rs.lib.util.TestUtil; +import jakarta.ws.rs.core.Response; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit5.ArquillianExtension; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static ee.jakarta.tck.ws.rs.lib.util.TestUtil.getResponse; + +/* + * @class.setup_props: webServerHost; + * webServerPort; + */ +@ExtendWith(ArquillianExtension.class) +public class UriInfo40ClientIT extends JAXRSCommonClient { + protected static final String ROOT = "jaxrs40_ee_core_uriinfo_web"; + + protected static final String RESOURCE = "app/resource"; + + public UriInfo40ClientIT() { + setup(); + setContextRoot("/" + ROOT + "/" + RESOURCE); + } + + + @BeforeEach + void logStartTest(TestInfo testInfo) { + TestUtil.logMsg("STARTING TEST : " + testInfo.getDisplayName()); + } + + @AfterEach + void logFinishTest(TestInfo testInfo) { + TestUtil.logMsg("FINISHED TEST : " + testInfo.getDisplayName()); + } + + @Deployment(testable = false) + public static WebArchive createDeployment() throws IOException{ + WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs40_ee_core_uriinfo_web.war"); + archive.addClasses(TSAppConfig.class, UriInfoTestResource.class); + return archive; + } + + /* Run test */ + + /** + * @testName: getMatchedResourceTemplateOneTest + * + * @assertion_ids: JAXRS:JAVADOC:97; + * + * @test_Strategy: Check the template containing {@link UriInfoTestResource#ONE_POST} + */ + @Test + public void getMatchedResourceTemplateOneTest() throws Fault { + setProperty(Property.REQUEST, buildRequest(Request.POST, "one/azazaz00")); + setProperty(Property.SEARCH_STRING, "|/app|/resource|/one|/" + UriInfoTestResource.ONE_POST); + invoke(); + + } + + /** + * @testName: getMatchedResourceTemplateTwoGetTest + * + * @assertion_ids: JAXRS:JAVADOC:97; + * + * @test_Strategy: Check the template containing {@link UriInfoTestResource#TWO_GET} + */ + @Test + public void getMatchedResourceTemplateTwoGetTest() throws Fault { + setProperty(Property.REQUEST, buildRequest(Request.GET, "two/P/abc/MyNumber")); + setProperty(Property.SEARCH_STRING, "/app|/resource|/two|/" + UriInfoTestResource.TWO_GET); + invoke(); + } + + /** + * @testName: getMatchedResourceTemplateTwoPostTest + * + * @assertion_ids: JAXRS:JAVADOC:97; + * + * @test_Strategy: Check the template containing {@link UriInfoTestResource#TWO_POST} + */ + @Test + public void getMatchedResourceTemplateTwoPostTest() throws Fault { + setProperty(Property.REQUEST, buildRequest(Request.POST, "two/P/abc/MyNumber")); + setProperty(Property.SEARCH_STRING, "/app|/resource|/two|/" + UriInfoTestResource.TWO_POST); + invoke(); + } + + /** + * @testName: getMatchedResourceTemplateSubTest + * + * @assertion_ids: JAXRS:JAVADOC:97; + * + * @test_Strategy: Check the template including subresource containing {@link UriInfoTestResource#THREE_SUB} + */ + @Test + public void getMatchedResourceTemplateSubTest() throws Fault { + setProperty(Property.REQUEST, buildRequest(Request.PUT, "three/a")); + setProperty(Property.SEARCH_STRING, "/app|/resource|/three|/" + UriInfoTestResource.THREE_SUB); + invoke(); + } +} diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/UriInfoTestResource.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/UriInfoTestResource.java new file mode 100644 index 000000000..15977b56d --- /dev/null +++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/UriInfoTestResource.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 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 ee.jakarta.tck.ws.rs.jaxrs40.ee.rs.core.uriinfo; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriInfo; + +import java.util.List; + +@Path("/resource") +public class UriInfoTestResource { + public static final String ONE_POST = "{name:[a-zA-Z][a-zA-Z_0-9]*}"; + public static final String TWO_GET = "{Prefix}{p:/?}{id: ((\\d+)?)}/abc{p2:/?}{number: (([A-Za-z0-9]*)?)}"; + public static final String TWO_POST = "{Prefix}{p:/?}{id: ((\\d+)?)}/abc/{yeah}"; + public static final String THREE_SUB = "{x:[a-z]}"; + + public static class SubGet { + @PUT + public String get(@Context UriInfo uriInfo) { + return listToString(uriInfo.getMatchedResourceTemplates()); + } + } + + @POST + @Path("one/" + ONE_POST) + public String post(@Context UriInfo info) { + return listToString(info.getMatchedResourceTemplates()); + } + + @GET + @Path("two/" + TWO_GET) + public String get(@Context UriInfo info) { + return listToString(info.getMatchedResourceTemplates()); + } + + @POST + @Path("two/" + TWO_POST) + public String postTwo(@Context UriInfo info) { + return listToString(info.getMatchedResourceTemplates()); + } + + @Path("three/" + THREE_SUB) + public SubGet doAnything4() { + return new SubGet(); + } + + private static String listToString(List list) { + return list.stream().reduce("", (a, b) -> a + "|" + b); + } +}