I understand James's usecase, but I don't like his solution. I never
liked the 'limited' annotation attribute and thought we should expand on
@Path expressions instead. I propose supporting regular expressions
instead. Here's my idea:
"{}" denotes a PathParam, expression, or both:
"{" [ path_param ] ":" expression "}" |
"{" path_param "}"
The ":" denotes that there is an expression to be matched. If the ":"
is preceded by a path_param, then fill that path_param with that value.
For example:
1. /foo/{param}/blah -> "/foo/([^/])+"
2. /foo/{param: .*}/image.jpg -> "/foo/(.*)?/image.jpg"
3. /foo/{:.*}/image.jpg -> "/foo/.*/image.jpg"
#1 is an example of a path param with no expression
#2 is an example of a path param that matches a particular expression
#3 is an example of just an expression with no path param
We support regular expressions in JAX-RS 1.0. If we want to support
different expressions down the road we can either:
* create a new @Path annotation
@W3cPath
* Create an expression annotation that tells how to match the @Path
expression
@Path("/-pre(43233)hello")
@RFC3322PathExpresions
* Or add an attribute to @Path (I don't like this approach).
Stephan Koops wrote:
> 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
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jsr311.dev.java.net
> For additional commands, e-mail: users-help_at_jsr311.dev.java.net
>
--
Bill Burke
JBoss, a division of Red Hat
http://bill.burkecentral.com