Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,20 @@
import java.util.Map;
import java.util.logging.Logger;

import jakarta.ws.rs.core.Application;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.PathSegment;
import jakarta.ws.rs.core.UriBuilder;
import jakarta.ws.rs.core.UriInfo;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.jaxrs.model.ApplicationInfo;
import org.apache.cxf.jaxrs.model.MethodInvocationInfo;
import org.apache.cxf.jaxrs.model.OperationResourceInfo;
import org.apache.cxf.jaxrs.model.OperationResourceInfoStack;
import org.apache.cxf.jaxrs.model.URITemplate;
import org.apache.cxf.jaxrs.utils.HttpUtils;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
import org.apache.cxf.jaxrs.utils.ResourceUtils;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;

Expand Down Expand Up @@ -246,22 +249,41 @@ public URI resolve(URI uri) {
@Override
public String getMatchedResourceTemplate() {
if (stack != null) {
final List<URITemplate> templates = new LinkedList<>();
String matchedResourceTemplate = getApplicationPath();

for (MethodInvocationInfo invocation : stack) {
OperationResourceInfo ori = invocation.getMethodInfo();
templates.add(ori.getClassResourceInfo().getURITemplate());
templates.add(ori.getURITemplate());
}

if (!templates.isEmpty()) {
UriBuilder builder = UriBuilder.fromPath(templates.get(0).getValue());
for (int i = 1; i < templates.size(); ++i) {
builder = builder.path(templates.get(i).getValue());
}
return builder.build().toString();

matchedResourceTemplate = JAXRSUtils.combineUriTemplates(
matchedResourceTemplate, getValue(ori.getClassResourceInfo().getURITemplate()));

matchedResourceTemplate = JAXRSUtils.combineUriTemplates(
matchedResourceTemplate, getValue(ori.getURITemplate()));
}
return matchedResourceTemplate;
}

LOG.fine("No resource stack information, returning empty template");
return "";
}

private String getValue(URITemplate uriTemplate) {
return uriTemplate == null ? null : uriTemplate.getValue();
}

private String getApplicationPath() {
ApplicationInfo appInfo = (ApplicationInfo) message.getExchange().getEndpoint()
.get(Application.class.getName());

if (appInfo == null) {
return "/";
}

String applicationPath = ResourceUtils.locateApplicationPath(appInfo.getProvider().getClass()).value();
if (!applicationPath.startsWith("/")) {
applicationPath = "/" + applicationPath;
}

return applicationPath;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2160,7 +2160,7 @@ private static String getUriTemplate(ClassResourceInfo cri) {
* @param child child URI template
* @return the URI template combined from the parent and child
*/
private static String combineUriTemplates(final String parent, final String child) {
public static String combineUriTemplates(final String parent, final String child) {
if (StringUtils.isEmpty(child)) {
return parent;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,16 @@
import java.util.ArrayList;
import java.util.List;

import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.Application;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.PathSegment;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriInfo;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.jaxrs.model.ApplicationInfo;
import org.apache.cxf.jaxrs.model.ClassResourceInfo;
import org.apache.cxf.jaxrs.model.MethodInvocationInfo;
import org.apache.cxf.jaxrs.model.OperationResourceInfo;
Expand Down Expand Up @@ -430,6 +434,12 @@ public Response get() {
return null;
}

@GET
@Path("one/{name:[a-zA-Z][a-zA-Z_0-9]*}")
public Response getTemplate() {
return null;
}

@GET
@Path("bar")
public Response getSubMethod() {
Expand All @@ -455,6 +465,10 @@ public Response getFromSubSub() {
}
}

@ApplicationPath("app")
public static class TestApplication extends Application {
}

private static ClassResourceInfo getCri(Class<?> clazz, boolean setUriTemplate) {
ClassResourceInfo cri = new ClassResourceInfo(clazz);
Path path = AnnotationUtils.getClassAnnotation(clazz, Path.class);
Expand Down Expand Up @@ -563,10 +577,71 @@ public void testGetMatchedURIsSubResourceLocatorSubPath() throws Exception {
assertEquals("foo", matchedUris.get(2));
}

@Test
public void testGetMatchedResourceTemplateIncludesApplicationPathAndTemplateVariables() throws Exception {
Message m = mockMessage("http://localhost:8080/app", "/foo/one/abc");
setApplication(m, new TestApplication());
OperationResourceInfoStack oriStack = new OperationResourceInfoStack();
ClassResourceInfo cri = getCri(RootResource.class, true);
OperationResourceInfo ori = getOri(cri, "getTemplate");

MethodInvocationInfo miInfo = new MethodInvocationInfo(ori, RootResource.class, new ArrayList<String>());
oriStack.push(miInfo);
m.put(OperationResourceInfoStack.class, oriStack);

UriInfoImpl u = new UriInfoImpl(m);
assertEquals("/app/foo/one/{name:[a-zA-Z][a-zA-Z_0-9]*}", u.getMatchedResourceTemplate());
}

@Test
public void testGetMatchedResourceTemplateUsesApplicationPathAnnotation() throws Exception {
Message m = mockMessage("http://localhost:8080/context/service/app", "/foo/bar");
setApplication(m, new TestApplication());

OperationResourceInfoStack oriStack = new OperationResourceInfoStack();
ClassResourceInfo cri = getCri(RootResource.class, true);
OperationResourceInfo ori = getOri(cri, "getSubMethod");

MethodInvocationInfo miInfo = new MethodInvocationInfo(ori, RootResource.class, new ArrayList<String>());
oriStack.push(miInfo);
m.put(OperationResourceInfoStack.class, oriStack);

UriInfoImpl u = new UriInfoImpl(m);
assertEquals("/app/foo/bar", u.getMatchedResourceTemplate());
}

@Test
public void testGetMatchedResourceTemplateSubResourceWithoutClassPath() throws Exception {
Message m = mockMessage("http://localhost:8080/app", "/foo/sub");
setApplication(m, new TestApplication());
OperationResourceInfoStack oriStack = new OperationResourceInfoStack();
ClassResourceInfo rootCri = getCri(RootResource.class, true);
OperationResourceInfo rootOri = getOri(rootCri, "getSubResourceLocator");

MethodInvocationInfo miInfo = new MethodInvocationInfo(rootOri, RootResource.class, new ArrayList<String>());
oriStack.push(miInfo);

ClassResourceInfo subCri = getCri(SubResource.class, false);
OperationResourceInfo subOri = getOri(subCri, "getFromSub");

miInfo = new MethodInvocationInfo(subOri, SubResource.class, new ArrayList<String>());
oriStack.push(miInfo);
m.put(OperationResourceInfoStack.class, oriStack);

UriInfoImpl u = new UriInfoImpl(m);
assertEquals("/app/foo/sub", u.getMatchedResourceTemplate());
}

private Message mockMessage(String baseAddress, String pathInfo) {
return mockMessage(baseAddress, pathInfo, null, null);
}

private void setApplication(Message m, Application app) {
Endpoint endpoint = mock(Endpoint.class);
when(endpoint.get(Application.class.getName())).thenReturn(new ApplicationInfo(app, null));
m.getExchange().put(Endpoint.class, endpoint);
}

private Message mockMessage(String baseAddress, String pathInfo, String query) {
return mockMessage(baseAddress, pathInfo, query, null);
}
Expand Down
Loading