users@jsr311.java.net

Re: JAX-RS: _at_Path limited=false templates: (?!/).+(?<!/)

From: Stephan Koops <Stephan.Koops_at_web.de>
Date: Wed, 02 Jul 2008 09:34:58 +0200

Hi James,

I think it is a more common case, that you have a fix start of the path
and the different ends of the path to be matched. But perhaps we could
support both with a new attribute, analogue to limited.
Let's see, what the others say.

BTW: You could handle the file extensions the the extension mapping, and
use the http content negotiation, or leave the extension out. IMO you
should not hardcode the file extensions.

best regards
   Stephan

Manger, James H schrieb:
> A @Path template can have a placeholder for:
> 1) A single path segment (or part of one); or
> 2) Everything remaining in the path.
>
> {name} at the end of a @Path value with limited=false gives the 2nd option;
> {name} in any other circumstance gives the 1st option.
>
> These are the only two options, but I am not confident that they will be sufficient.
>
> I suspect many web apps might use a variable-depth hierarchy in the *middle* of their URIs. Below are some made up examples, none of which are valid in JAX-RS 0.9:
>
> 1. A genealogy site with any number of ancestors;
> http://example.net/genealogy/alice/bob/chris/photo.jpg
> http://example.net/genealogy/alice/bob/tree.json
> http://example.net/genealogy/alice/bob/dave/details.html
> => @Path(value="genealogy/{ancestors}/photo.jpg", limited=false)
> @Path(value="genealogy/{ancestors}/tree.json", limited=false)
>
> 2. A Java source code repository;
> http://example.net/java/java/lang/Integer/methods.json
> http://example.net/java/javax/ws/rs/core/Request/methods.xml
> http://example.net/java/javax/ws/rs/core/Request/dependencies.xml
> => @Path(value="java/{class}/methods.{format}", limited=false)
>
>
> There are two hassles:
> 1. limited=false should apply to specific {...} placeholders,
> not a whole path that can have many placeholders;
> 2. You cannot have anything after a limited=false placeholder.
>
>
> I suggest that when limited=false, {name} should (greedily) match at least 1 char, and not start or end with a '/'. This is a change from matching the whole remaining path (except an optional final '/'). It allows literal characters after the placeholder.
> When limited=false replace {name} with:
> (?!/).+(?<!/)
>
> I also suggest limited=false should apply to the *FIRST* placeholder, not the last. Better still, there could be two types of placeholder --
> say {name} and {name*} -- for limited and unlimited placeholders respectively.
>
> Applying limited=false to the *FIRST* placeholder still allows code that wants an earlier limited placeholder to use two @Path annotations (eg on a class then method). The reverse is harder. That is, when limited=false applies to the *LAST* placeholder it is not currently possible (and still harder with mods) to allow code that wants a later limited placeholder. Using a subsequent @Path does not really work as the whole path has already been gobbled up.
>
> Example: http://example.net/cafes/us/california/sanfran/city/east/map.png
>
> @Path("{country}")
> class Abc {
> @Path(value="{location}/map.png", limited=false)
> public Image getMap(...)
> @Path(value="{location}/description.html", limited=false)
> public String getWebpage(...)
> }
>
>
> Proposed replacement for
> 3.7.3 Converting URI Templates to Regular expressions. The changes are to points 3, 4 & 5.
>
>
> "The function R(A) converts a URI path template annotation A into a regular expression as follows:
> 1. If A:encode = true, URI encode the template, ignoring URI template variable specifications.
> 2. Escape any regular expression characters in the URI template, again ignoring URI template variable
> specifications.
> 3. Replace all limited placeholders with the regular expression ‘([ˆ/]+?)’.
> 4. Replace all unlimited placeholders with the regular expression ‘(?!/).+(?<!/)’.
> 5. If the resulting string ends with ‘/’ append ‘(.+)?’, otherwise append ‘(?:/(.+))?’
> Note that the above renders the name of template variables irrelevant for template matching purposes. However, implementations will need to retain template variable names in order to facilitate the extraction of
> template variable values via @PathParam or UriInfo.getTemplateParameters."
>
>
> [The final capturing group does not start with '/' so §3.7.2 2(a) would need to be adjusted from "If U is null or '/'" to "If U is null".]
>
>
> P.S. In the current §3.7.3 "Converting URI Templates to Regular Expressions" the result is undefined if limited=false, but the "final URI template variable" (placeholder) is not the "last thing in the URI template".
>
> James Manger
>