The latest UriBuilder looks pretty good.
One aspect that isn’t clear (or isn’t how I would like it) is how a placeholder in a @Path value is treated.
What does the following create?
UriBuilder.fromResource( @Path(“widget/{id}/info”) ).build(“X/123”)
1. “widget/X/123/info”; or
2. “widget/X%2F123/info”
@Path explicitly states that {id} is a segment (not a path) for matching. That is, it matches [^/]+ so %2F is ok, but ‘/’ is not. UriBuilder really needs to treat it the same way. In this case the path(Method), path(Class), and path(Class, String) methods will escape a placeholder as a segment, while the path(String), fromPath(String) and replacePath(String) methods will escape a placeholder as a path. I think that is too confusing for such a common case.
First, I suggest renaming the path(Method), path(Class), and path(Class, String) methods to resource(…) as an explicit indication that they escape placeholder values differently than other *path(…) methods – and for consistency with fromResource(Class).
Second, I suggest the resource(..) methods make some effort to handle a regex in a @Path placeholder – without requiring JAX-RS implementations to understand arbitrary regular expressions. Possible text:
“For each placeholder in a @Path value:
1. If there is no regex, treat it as a segment placeholder (%-escape ‘/’s);
2. If the regex is “.*” or “.+”, treat it as a path placeholder (don’t escape ‘/’s);
3. For any other regex, %-escape all non-unreserved characters.
A JAX-RS implementation MAY relax the 3rd rule above by not %-escaping characters that it knows are allowed by the regex. An application should not rely on a JAX-RS implementation to recognize such situations.
A UriBuilderException shall be thrown if a placeholder value (after %-escaping) does not match the regex given in a @Path placeholder.”
I think those rules should not be too onerous to implement. After some more experience some common regexs for @Path values may emerge. A future version of JAX-RS could easily extend the above rules to require support for additional regexes – or they just get implemented in most JAX-RS implementations so applications can rely on them anyway. An implementation that tries escaping different reserved char until the regex matches may even be feasible.
James Manger