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 18:41:54 +0200

Is there nothing in the Uri template specification that could be used?
http://bitworking.org/projects/URI-Templates/spec/draft-gregorio-uritemplate-03.html

Stephan

Marc Hadley schrieb:
> Funny, Paul and I were just discussing the exact same idea ! I'm not
> exactly sold on this yet but lets explore the idea to see if we end up
> somewhere good.
>
>> 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
>>
> So essentially if its a named template var then you turn whatever
> follows the ':' into a capturing group. I notice in your example you
> follow the capturing group with '?' - why ? Is there a usecase for
> allowing the user to specify qualifiers for a capturing group ?
>
>>
>> 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
>
> This is probably the most straightforward.
>
> Marc.
>
>>
>> * 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
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jsr311.dev.java.net
>> For additional commands, e-mail: users-help_at_jsr311.dev.java.net
>>
>
> ---
> Marc Hadley <marc.hadley at sun.com>
> CTO Office, Sun Microsystems.
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jsr311.dev.java.net
> For additional commands, e-mail: users-help_at_jsr311.dev.java.net
>