users@jersey.java.net

Re: [Jersey] [PATCH] to allow the API of RESTful services to be rendered using hierarchial Implicit Views

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Fri, 20 Feb 2009 15:02:13 +0100

On Feb 19, 2009, at 4:42 PM, James Strachan wrote:

> 2009/2/19 Paul Sandoz <Paul.Sandoz_at_sun.com>:
>> Hi James,
>>
>> This looks really interesting! thanks for doing this.
>
> No worries - it was fun! I was surprised how easy it was to reuse the
> WadlResource in an implicit view with really minor changes to Jersey!
>

Index: jersey-server/src/main/java/com/sun/jersey/server/impl/uri/
rules/SubLocatorRule.java
===================================================================
--- jersey-server/src/main/java/com/sun/jersey/server/impl/uri/rules/
SubLocatorRule.java (revision 2021)
+++ jersey-server/src/main/java/com/sun/jersey/server/impl/uri/rules/
SubLocatorRule.java Thu Feb 19 14:03:33 GMT 2009
@@ -47,6 +47,8 @@
  import com.sun.jersey.spi.inject.Injectable;
  import com.sun.jersey.spi.uri.rules.UriRule;
  import com.sun.jersey.spi.uri.rules.UriRuleContext;
+import com.sun.jersey.spi.uri.rules.UriRules;
+
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import java.util.Iterator;
@@ -95,7 +97,14 @@
          context.pushResource(resource);

          // Match sub-rules on the returned resource class
- final Iterator<UriRule> matches =
context.getRules(resource.getClass()).
+ if (resource == null) {
+ return false;
+ }
+ UriRules<UriRule> rules =
context.getRules(resource.getClass());
+ if (rules == null) {
+ return false;
+ }
+ final Iterator<UriRule> matches = rules.
                  match(path, context);
          while(matches.hasNext())
              if(matches.next().accept(path, resource, context))

Was there something going wrong that forced the above changes. I am
trying to work out if there is a deeper problem here.

I think one problem is that a sub-resource locator can return a null
value, which was not checked before.

IIRC if "resource" is not null there will always be a non-null "rules"
returned. Did you have a case where this was null?


Do you think there might be value in letting the developer plugin in
the required WadlResource, extending from a base class? this might
make it easier to allow developers to evolve the code as they require
e.g a property for a class, or instance, that extends WadlResource.

Or... to support it using it in a conventional way e.g.

  @Path("/api")
  public CamelWadlResource extends WadlResource {
     ...
  }

and have things injected correctly on WadlResource. The runtime could
check in any resource class implements WadlResource and if none do it
can supply a default (if JAXB is present in the classpath).


Or do you think the modifications on the WADL-based resources will be
sufficient that no further modification would be required?


>
>> I am going to take a close look at this tomorrow. My first thought
>> is we
>> should move the Jersey WadlResource class to the API and we
>> document it in
>> relation to views.
>
> Yeah - it seems a very handy class and something I can imagine lots of
> folks tinkering with to get better self-documenting RESTful services.
>
> Incidentally I just attached a slightly modified patch; I found that
> there's a small discrepency between WADL's idea of child resources and
> JAX-RS path navigation. Namely that JAX-RS navigates a new path by
> splitting on "/" so "foo/{bar}" would be 2 paths - whereas in WADL
> documents "foo/{bar}" is often one path - so to work around this I've
> introduced a simple PartialResource class which matches the "foo" part
> so that when "{bar}" is navigated to it correctly finds the
> "foo/{bar}" resource in WADL etc.
>
> e.g. this URL now works in the Camel example...
> http://localhost:8080/api/resources/endpoints/{id}/messages/{id}
>
> as "messages/{id}" is a single child resource of {id} if you see
> what I mean.
>

OK.

Paul.