On Jul 2, 2008, at 6:28 PM, Marc Hadley wrote:
> 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.
>
Some comments:
- We can still retain the ordering of the "URI matchers" based on the
number of template variables (unnamed or
named) and literal characters that are not declared in a regex.
- URI matchers could be used as URI templates, although an unnamed
variable cause issues when constructing
the URI as information is lost. Thus i am wondering if they should
be disallowed and we should require a name
and that template variable name/value may be ignored e.g. call it
'noname'. Or a perhaps a known name is
assigned if one is absent e.g. _1, _2 etc.
- The regex associated with the template variable name could be used,
perhaps optionally, to validate the value
when the URI matcher is used as a URI template.
- What does it mean if the regex for a name contains one or more
capturing groups?
It is possible to determine using javax.util.regex.Pattern/Matcher
the number of capturing groups in an expression.
Tis a bit funky but one compiles the pattern and obtains a
matcher, m say, for say "", then one calls m.groupCount().
Thus it may also be possible to assign names to such sub-groups as
is the case for unnamed template variables. Or
it may be possible to easily reject a regex that contains
capturing groups.
Paul.
From what i can tell we could still retain the order
>> 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
>