users@jersey.java.net

Re: AW: AW: AW: [Jersey] Reverse Lookup

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 01 Jun 2010 11:54:11 +0200

Hi Lerenc,

I was proposing as a work around you use the ResourceFilterFactory
just to collect information on resource classes, and not return any
filters as you do not require to filter the request or response.

public MyResourceFilterFactory implements ResourceFilterFactory {
   List<ResourceFilter> create(AbstractMethod am) {
    // called at initialization for methods on root resources
    // analyze am

     return Collections.<ResourceFlter>emptyList();
   }
}

To be honest this is rather hacky and i really should start working on
the reverse look up.


W.r.t. XStream can you share some code? I wonder if the application
can register implementations of ContextResolver<XStream> and the
XStream serialization and parsing code can utilize that for certain
types? see:
   https://jsr311.dev.java.net/nonav/javadoc/javax/ws/rs/ext/Providers.html
#getContextResolver%28java.lang.Class,%20javax.ws.rs.core.MediaType%29

Paul.



On Jun 1, 2010, at 4:35 AM, Lerenc, Vedran wrote:

> Hi Paul,
>
> thank you for the hints! However, I am not sure whether a filter
> will help me. Is a filter – as described in the JavaDoc – called
> before a request/after a response? In my case the system may get a
> PUT before a GET (let’s say the system was restarted and some
> application which did a GET a long time ago, now comes with a PUT).
> As long as I don’t persistent the proposed map of yours (which I
> also can generate directly when I serve my resources in the GETs), I
> have never seen resources of this type in a filter after the restart
> – yet I have to map them.
>
> Is there something else (like a registry) in Jersey that gives me
> all RootResources back? Or is a filter what I look for? However,
> when I implement a com.sun.jersey.spi.container.ResourceFilter which
> I register with com.sun.jersey.spi.container.ResourceFilters I
> should implement two methods called getRequestFilter() and
> getResponseFilter(), which don’t sound like they would help me,
> because I shall return com.sun.jersey.spi.container.
> ContainerRequestFilter/ ContainerResponseFilter instances which
> react only on requests/responses. In my case a get a PUT on one
> resource type with some URIs that I created with UriBuilder of a
> totally different resource type (either just a few milliseconds
> before or weeks before), i.e. the resource type in question (the
> contained one) didn’t run through these filters, might even never
> been served through Jersey. It was annotated with @Path and at least
> once I called the UriBuilder to get the path, but that might have
> happened a long time ago.
>
> As a side note: In fact I had (and have) similar issues with XStream
> that doesn’t know about XStreamAlias annotated resources until it
> serializes them for the first time (you have no problems without
> XStreamAlias, as then XStream runs its default class mapping which
> takes the full class name), i.e. if a PUT hit me before a GET, it
> failed until I implemented a very ugly workaround for the time
> being: some ugly name guessing and package prefixing, but it feels
> so wrong. If only I could get a hand on what Jersey knows, i.e. on
> all resources types, then I could solve my problems. I just don’t
> want to do the work twice and annotate resources AND put them also
> in a map of mine – if possible at all. If not, I will do that (fill
> and keep my own map manually) as my XStream hack is inacceptable,
> too. The filters, as I understood them, showed me no way out, but I
> may be wrong about them.
>
> Regards,
>
> Vedran
>
>
>
> Von: Paul.Sandoz_at_Sun.COM [mailto:Paul.Sandoz_at_Sun.COM]
> Gesendet: Montag, 31. Mai 2010 11:03
> An: Lerenc, Vedran
> Cc: users_at_jersey.dev.java.net
> Betreff: Re: AW: AW: [Jersey] Reverse Lookup
>
> 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.