users@jax-rs-spec.java.net

[jax-rs-spec users] Re: Getting full path template after sub-resource locators

From: Ron Dagostino <rndgstn_at_gmail.com>
Date: Tue, 16 Feb 2016 21:01:00 -0500

Hi again. I have concluded that it is not possible to construct the full
path template for a request without (re-)implementing a significant portion
of the matching algorithm (specifically, stage 3). The problem is that
UriInfo does not provide a complete picture of what happened during the
matching process -- it does not specify which methods were matched on
instances generated by sub-resource locators. It provides the instances,
but it does not provide the matched methods.

Assuming it is agreed to be reasonable to want to know the full path
template for a request (I can explain why I want to do this if necessary),
and assuming I am not missing anything and it is indeed not (easily)
possible with the 2.0 API, and simple solution would be to add a method to
UriInfo that returns the matched methods as shown in the sample Javadoc
below. A more complete solution would be to expose the entire match model:
a list with each element being an object that contained a resource method,
a path parameters map (empty if no template substitutions were made), and
the matched resource.

I am hoping for some feedback on this.

Ron

java.lang.List<java.lang.reflect.Method> *getMatchedMethods*()

Get a read-only list of the currently matched resource methods. Each entry
is a resource method that matched the request URI either directly or via a
sub-resource method or a sub-resource locator. Entries are ordered
according to reverse request URI matching order, with the current resource
method first. E.g. given the following resource classes:

@Path("foo")
public class FooResource {
  @GET
  public String getFoo() {...}

  @Path("bar")
  public BarResource getBarResource() {...}
}

public class BarResource {
  @GET
  public String getBar() {...}
}


The values returned by this method based on request uri and where the
method is called from are:
RequestCalled fromValue(s)
GET /foo FooResource.getFoo FooResource.getFoo
GET /foo/bar FooResource.getBarResource FooResource.getBarResource
GET /foo/bar BarResource.getBar BarResource.getBar,
FooResource.getBarResource

RequestCalled fromValue(s)
GET /foo RequestContextFilter (pre-match) null
GET /foo
RequestContextFilter (post-match)
FooResource.getFoo
GET /foo/bar
RequestContextFilter (post-match)
BarResource.getBar, FooResource.getBarResource

*Returns:*a read-only list of matched resource methods.



On Mon, Feb 15, 2016 at 9:55 PM, Ron Dagostino <rndgstn_at_gmail.com> wrote:

> Hi everyone. I want to write a ContainerRequestFilter that can generate
> the full path template value "root/id1={id1Value}/id2={id2Value}" for the
> following case and also generate correct full path template values in the
> general case. I don't think it can be reliably done when sub-resource
> locators are involved. For example, given these classes:
>
>
> @Path("root") // resource class
> public class Root {
> @Path("id1={id1Value}") // sub-resource locator
> public SubResource getSubResource() {
> return new SubResource();
> }
> }
>
> public class SubResource {
> @Path("id2={id2Value}")
> @GET // sub-resource method
> public String get() {
> return "the entity";
> }
> }
>
> And given this request:
>
> /root/id1=2/id2=2
>
>
> The problem is that uriInfo.getPathParameters() returns this
> MultiValuedMap in the filter:
>
> {id2Value=[2], id1Value=[2]}
>
> There is no way I can reliably get from "/root/id1=2/id2=2" to
> "root/id1={id1Value}/id2={id2Value}" given the MultiValuesMap contents.
>
> Basically I think there is no way to reliably know what the full path
> template value is for a request when sub-resource locators are involved.
> Is this true?
>
> Ron
>