Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added UriInfo#getMatchedResourceTemplate method #1236

Merged
merged 4 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 68 additions & 1 deletion jaxrs-api/src/main/java/jakarta/ws/rs/core/UriInfo.java
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -18,6 +18,8 @@

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
Expand Down Expand Up @@ -230,6 +232,71 @@ public interface UriInfo {
*/
public List<String> getMatchedURIs();

/**
* <p>
* Get a URI template that includes all {@link Path Paths} (including {@link ApplicationPath})
* matched by the current request's URI.
* </p>
* <p>
* 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:
* </p>
*
* <pre>
* &#064;Path("foo")
* public class FooResource {
* &#064;GET
* &#064;Path("{foo:[f-z][a-z]*}")
* public String getFoo() {...}
*
* &#064;Path("{bar:[b-e][a-z]*}")
* public BarResource getBarResource() {...}
* }
*
* public class BarResource {
* &#064;GET
* &#064;Path("{id}{id:[0-9]}")
* public String getBar() {...}
* }
* </pre>
*
* <p>
* The values returned by this method based on request uri and where the method is called from are:
* </p>
*
* <table border="1">
* <caption>Matched URIs from requests</caption>
* <tr>
* <th>Request</th>
* <th>Called from</th>
* <th>Value(s)</th>
* </tr>
* <tr>
* <td>GET /foo</td>
* <td>FooResource.getFoo</td>
* <td>/foo/{foo:[f-z][a-z]*}</td>
* </tr>
* <tr>
* <td>GET /foo/bar</td>
* <td>FooResource.getBarResource</td>
* <td>/foo/{bar:[b-e][a-z]*}</td>
* </tr>
* <tr>
* <td>GET /foo/bar/id0</td>
* <td>BarResource.getBar</td>
* <td>/foo/{bar:[b-e][a-z]*}/{id}{id:[0-9]}</td>
* </tr>
* </table>
*
* 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.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Class<?>> getClasses() {
Set<Class<?>> resources = new HashSet<Class<?>>();
resources.add(UriInfoTestResource.class);
return resources;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* 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 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();
}
}
Original file line number Diff line number Diff line change
@@ -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) {
jansupol marked this conversation as resolved.
Show resolved Hide resolved
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();
}
}