users@jsr311.java.net

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

From: Marc Hadley <Marc.Hadley_at_Sun.COM>
Date: Wed, 02 Jul 2008 12:54:33 -0400

On Jul 2, 2008, at 12:41 PM, Stephan Koops wrote:

> Is there nothing in the Uri template specification that could be used?
> http://bitworking.org/projects/URI-Templates/spec/draft-gregorio-uritemplate-03.html
>
The URI template spec is more oriented towards URI generation than
matching.

Marc.

>
> 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
>>
>
> ---------------------------------------------------------------------
> 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.