On May 30, 2010, at 2:15 PM, Lerenc, Vedran wrote:
> Hi Paul,
>
> Ø What the issue is about is essentially a reverse operation. We
> need to match the path to a resource class…
>
> Yes, that’s what I am looking for.
>
> Ø In the interim of any such functionality
>
> Oh, I am surprised as I thought it is good REST style to use URIs
> where the resources shouldn’t go over the wire.
Yes, URIs in the representations.
> Hence, if I am supposed to do that, I need a way back from the URI
> to my object. I don’t want to add redundant code – I have used the
> PATH annotation, use already the UriBuilder to map resources to URIs
> and hoped for a clean way back, thereby minimizing redundancy and
> bugs in my code (an own little mapper might get out of sync with the
> @PATH annotations if other developers take over/join team).
A valid point. JAX-RS 1.x punted better support for linking and
hypermedia to a JAX-RS 2.0 effort.
>
> Ø i can provide details of a way of obtaining the URI templates for
> the set root resources (and templates for sub-resource locators and
> sub-resource methods), and from that you can concoct your own
> reverse matching. I can send more details as required.
>
> That would be great! Yes, please send me some information so that I
> can do the reverse mapping. Thanks in advance!
>
OK. In the interim of fixing this here are some guidelines.
You can register a ResourceFilterFactory:
https://jersey.dev.java.net/nonav/apidocs/latest/jersey/com/sun/jersey/api/container/filter/package-summary.html
that does not add any filters but just analyses each AbstractMethod of
a resource class. From the AbstractMethod instance you can get access
to the AbstractResource as well. Anything with an @Path on it
implements PathAnnotated:
https://jersey.dev.java.net/nonav/apidocs/latest/jersey/com/sun/jersey/api/model/PathAnnotated.html
from which you can get the path value.
UriTemplate t = new PathTemplate(a.getPath().getValue());
PathPattern p = new PathPattern(t);
So you can obtain all the path patterns for all root resources and add
them to a sorted map (or set).
public class MyMap<R> extends TreeMap<PathPattern, R>{
public MyMap() {
super(PathPattern.COMPARATOR);
}
}
and then you can linearly match each PathPattern using
PathPattern.match.
Note that because of the JAX-RS matching algorithm you cannot merge
path patterns at multiple levels (e.g. @Path on root resource classes
and @Path on methods of those classes) as this will result in
incorrect matching depending on the @Path values. So as you can guess
it can quickly get more complex.
To fix this issue what i need to do is provide a set of "uri rules"
for reverse look up. Jersey has already has a set of rules for
matching, but i would prefer to keep the reverse look up functionality
separate so that it can be optimized (e.g. one does not require to
create an internal request context if a resource class is matched but
the instance is not required).
Paul.