From e201cc339d2f72592a539582142e012a8e4e7845 Mon Sep 17 00:00:00 2001 From: jansupol Date: Wed, 13 Mar 2024 19:40:25 +0100 Subject: [PATCH 1/4] Added UriInfo#getMatchedResourceTemplate method Signed-off-by: jansupol --- .../main/java/jakarta/ws/rs/core/UriInfo.java | 67 ++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) 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..b93e13a4e 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -18,6 +18,7 @@ import java.net.URI; import java.util.List; +import jakarta.ws.rs.Path; /** * An injectable interface that provides access to application and request URI information. Relative URIs are relative @@ -230,6 +231,70 @@ public interface UriInfo { */ public List getMatchedURIs(); + /** + *

+ * Get a template concatenated of all {@link Path Paths} matched by all the resources when matching the current request. + *

+ *

+ * Each {@link Path} value used to match a resource class, a sub-resource method or a sub-resource locator is concatenated + * to a single {@code String} value. The template does not include query parameters but do include matrix parameters + * if present in the request URI. The concatenation is ordered in the request URI matching order, with the current resource + * URI 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 concatenated string of {@link Path} templates. + */ + public String getMatchedResourceTemplate(); + /** * Get a read-only list of URIs for matched resources. * From ecdb02081f491ecdeb09d8476d4834c00bdc7b92 Mon Sep 17 00:00:00 2001 From: jansupol Date: Fri, 22 Mar 2024 17:19:50 +0100 Subject: [PATCH 2/4] Reflected review comments Added TCK tests Signed-off-by: jansupol --- .../main/java/jakarta/ws/rs/core/UriInfo.java | 8 +- .../ee/rs/core/uriinfo/JAXRSClientIT.java | 126 ++++++++++++++++++ .../ee/rs/core/uriinfo/TSAppConfig.java | 33 +++++ .../rs/core/uriinfo/UriInfoTestResource.java | 63 +++++++++ 4 files changed, 227 insertions(+), 3 deletions(-) create mode 100644 jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/JAXRSClientIT.java 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/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 b93e13a4e..668044233 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 @@ -19,6 +19,7 @@ import java.net.URI; import java.util.List; import jakarta.ws.rs.Path; +import jakarta.ws.rs.ApplicationPath; /** * An injectable interface that provides access to application and request URI information. Relative URIs are relative @@ -233,13 +234,14 @@ public interface UriInfo { /** *

- * Get a template concatenated of all {@link Path Paths} matched by all the resources when matching the current request. + * Get a URI template that includes all {@link Path Paths} (including {@link ApplicationPath}) + * matched by the current request's URI. *

*

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

* *
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/JAXRSClientIT.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/JAXRSClientIT.java
new file mode 100644
index 000000000..266d77abb
--- /dev/null
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/JAXRSClientIT.java
@@ -0,0 +1,126 @@
+/*
+ * 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 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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JAXRSCommonClient {
+
+  private static final long serialVersionUID = 40L;
+
+  protected static final String ROOT = "jaxrs40_ee_core_uriinfo_web";
+
+  protected static final String RESOURCE = "app/resource";
+
+  public JAXRSClientIT() {
+    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/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/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..e43a14711
--- /dev/null
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/UriInfoTestResource.java
@@ -0,0 +1,63 @@
+/*
+ * 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;
+
+@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 uriInfo.getMatchedResourceTemplate();
+        }
+    }
+
+    @POST
+    @Path("one/" + ONE_POST)
+    public Response post(@Context UriInfo info) {
+        return Response.ok(info.getMatchedResourceTemplate()).build();
+    }
+
+    @GET
+    @Path("two/" + TWO_GET)
+    public Response get(@Context UriInfo info) {
+        return Response.ok(info.getMatchedResourceTemplate()).build();
+    }
+
+    @POST
+    @Path("two/" + TWO_POST)
+    public Response postTwo(@Context UriInfo info) {
+        return Response.ok(info.getMatchedResourceTemplate()).build();
+    }
+
+    @Path("three/" + THREE_SUB)
+    public SubGet doAnything4() {
+        return new SubGet();
+    }
+}

From dab6fdccdf084b834db7e116681af4279832984e Mon Sep 17 00:00:00 2001
From: jansupol 
Date: Fri, 22 Mar 2024 18:53:55 +0100
Subject: [PATCH 3/4] Renamed the client class

Signed-off-by: jansupol 
---
 .../uriinfo/{JAXRSClientIT.java => UriInfo40ClientIT.java} | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)
 rename jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/{JAXRSClientIT.java => UriInfo40ClientIT.java} (96%)

diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/JAXRSClientIT.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/UriInfo40ClientIT.java
similarity index 96%
rename from jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/JAXRSClientIT.java
rename to jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/UriInfo40ClientIT.java
index 266d77abb..505013785 100644
--- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/JAXRSClientIT.java
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs40/ee/rs/core/uriinfo/UriInfo40ClientIT.java
@@ -35,15 +35,12 @@
  *                     webServerPort;
  */
 @ExtendWith(ArquillianExtension.class)
-public class JAXRSClientIT extends JAXRSCommonClient {
-
-  private static final long serialVersionUID = 40L;
-
+public class UriInfo40ClientIT extends JAXRSCommonClient {
   protected static final String ROOT = "jaxrs40_ee_core_uriinfo_web";
 
   protected static final String RESOURCE = "app/resource";
 
-  public JAXRSClientIT() {
+  public UriInfo40ClientIT() {
     setup();
     setContextRoot("/" + ROOT + "/" + RESOURCE);
   }

From 1e1ab57e1061799ddf133343c91bbb17ef4f8f0b Mon Sep 17 00:00:00 2001
From: jansupol 
Date: Tue, 26 Mar 2024 19:57:48 +0100
Subject: [PATCH 4/4] Added @Path to Sub-resource method

Signed-off-by: jansupol 
---
 jaxrs-api/src/main/java/jakarta/ws/rs/core/UriInfo.java     | 4 ++--
 .../ws/rs/jaxrs40/ee/rs/core/uriinfo/UriInfo40ClientIT.java | 6 ++++--
 .../rs/jaxrs40/ee/rs/core/uriinfo/UriInfoTestResource.java  | 1 +
 3 files changed, 7 insertions(+), 4 deletions(-)

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 668044233..2fad2945e 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
@@ -240,8 +240,8 @@ public interface UriInfo {
      * 

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

* *
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
index 505013785..f6c20ad4d 100644
--- 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
@@ -18,6 +18,7 @@
 
 import ee.jakarta.tck.ws.rs.common.JAXRSCommonClient;
 import ee.jakarta.tck.ws.rs.lib.util.TestUtil;
+import jakarta.ws.rs.core.UriInfo;
 import org.jboss.arquillian.container.test.api.Deployment;
 import org.jboss.arquillian.junit5.ArquillianExtension;
 import org.jboss.shrinkwrap.api.ShrinkWrap;
@@ -116,8 +117,9 @@ public void getMatchedResourceTemplateTwoPostTest() throws Fault {
    */
   @Test
   public void getMatchedResourceTemplateSubTest() throws Fault {
-    setProperty(Property.REQUEST, buildRequest(Request.PUT, "three/a"));
-    setProperty(Property.SEARCH_STRING, "/app/resource/three/" + UriInfoTestResource.THREE_SUB);
+    setProperty(Property.REQUEST, buildRequest(Request.PUT, "three/a/z"));
+    setProperty(Property.SEARCH_STRING,
+            "/app/resource/three/" + UriInfoTestResource.THREE_SUB + "/" + 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
index e43a14711..f64848285 100644
--- 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
@@ -33,6 +33,7 @@ public class UriInfoTestResource {
 
     public static class SubGet {
         @PUT
+        @Path(THREE_SUB)
         public String get(@Context UriInfo uriInfo) {
             return uriInfo.getMatchedResourceTemplate();
         }