users@jsr311.java.net

Sub-Resource Locators

From: Craig McClanahan <Craig.McClanahan_at_Sun.COM>
Date: Wed, 30 Jul 2008 16:04:42 -0700

I'm playing with a use case of using JAX-RS for AtomPub feeds and
entries, extending from the example in Marc's blog last February[1].
One of the first things you notice when trying this is that you need to
be able to convert your data objects into Atom entries in two different
resources ... one as part a GET for the feed, and one when the entry is
requested individually. Sounds like a good opportunity to share some
logic, so I'm modeling things like this:

    @Path("customers")
    public class CustomersResource {
        ...
        // Sub-resource locator
        @Path("{id}")
        public CustomerResource getCustomerResource() {
            return new CustomerResource();
        }
        ...
       // Return an Atom feed containing the entire collection
       @GET
        public Response find() {
            ...
            CustomerResource resource = getCustomerResource();
            List<Customer> customers = ... find the relevant customers ...;
            for (Customer customer : customers) {
                Entry entry = resource.formatEntry(customer);
                ... add this to the feed representation ...
            }
            ...
        }
    }

    public class CustomerResource {
        ...
        // Return an Atom entry for the specified customer id
        @GET
        public Entry find(@PathParam("id") String id) {
            Customer customer = ... look up customer by id ...
            Entry entry = formatCustomer(customer);
            return entry;
        }
        ...
        // Utility method called from both our find() method and
CustomersResource#find()
        public Entry formatCustomer(Customer customer) {
            ... format this customer as an Atom entry and return ...
        }
        ...
    }


The problem I'm having is that the sub-resource instance returned by
getCustomerResource() does not receive any injections like "@Context
UriContext context". Thus, if my formatCustomer() method tries to
access the context (in my case, so that I can generate link URIs based
on the base URI of this request), I get NPEs.

How can I code the getCustomerResource() method in such a way that the
returned instance gets injections performed in the usual way? I'd
imagine that I would need to invoke some factory method provided by the
JAX-RS implementation, but it's not clear how one might accomplish that.

Craig

[1]
http://weblogs.java.net/blog/mhadley/archive/2008/02/integrating_jer_2.html