Re: UriBuilder <was> Re: How to create URIs?

From: Marc Hadley <Marc.Hadley_at_Sun.COM>
Date: Tue, 14 Aug 2007 14:53:07 -0400

On Aug 14, 2007, at 8:25 AM, Paul Sandoz wrote:
>> > On a related note should the build methods throw a
>> URISyntaxException ?
>> > On the one hand that seems like the right thing to do, on the
>> other hand
>> > that checked exception makes working with the URI class quite
>> awkward.
>> Indeed. URI.create() throws an IllegalArgumentException.
>> Perhaps we can
>> use the same?
>> They should throw a public unchecked analog of URISyntaxException
>> (maybe UriBuilderException?) because:
>> a) A malformed URI to the builder represents a programmer bug
>> (validation failure or lack thereof)
>> b) A checked exception is meant for expected, recoverable errors
>> in the framework behavior (example socket-failure).
>> c) IllegalArgumentException is non-descript for a framework artifact
> Makes sense.
Works for me.

>> Should we fail at the earliest opportunity to give a
>> meaningful stack
>> trace to the source of error?
>> I think it is ok to fail at the build() step. That is the expected
>> contract of the builder pattern anyway.
> But not necessarily for the contract of a builder method with
> encode=false. If it is possible to detect early surely that is more
> helpful to find the source of the programmer bug?
I think if we can do it efficiently then failing early will give the
best feedback to a developer tracking down a bug.

>> Is it likely that a developer would mix encoded/decoded space
>> per a
>> UriBuilder or would a UriBuilder be used consistently in
>> encoded or
>> decoded space?
>> This is not an assumption we should force from the framework. How
>> about the builder bootstrap itself, something like:
>> URIBuilder.create(ENCODED)...
> I was more thinking along the lines that each static method would
> have an 'encode' boolean parameter that defaults to true.
That would certainly deliver a simpler API provided the assumption
about not mixing encoded and decoded in the same builder is valid.
What do other folks think, is this a reasonable assumption ?

>> Note that a character encoding needs to be specified too. How
>> would we handle that?
> I think we should only support UTF-8 [1].
I agree.

> [1]
>> >>
>> >> Specify a value of -1 as no port?
>> >>
>> >> public abstract UriBuilder port(int port);
>> >>
>> > So then you can "unset" the port after constructing a builder
>> from a URI
>> > with a specified port ? Sounds reasonable to me.
>> How about an unsetPort() method?

Either works for me with a slight preference for -1 to avoid having
an additional method.

>> >>
>> >> What about null segment values, and queryParam/matrixPath
>> names ?
>> >
>> > Should we make null equivalent to "" for those ?
>> >
>> Currently a path(null)/path("") results in nothing appended to
>> the path:
>> UriBuilder.fromPath("/a/b/c").append("").build().
>> toString().equals("/a/b/c");
>> UriBuilder.fromPath("/a/b/c").append(null).build().
>> toString().equals("/a/b/c");
>> but i am not sure if a '/' should be appended.

I'd expect a '/' to be appended.

>> Should an IllegalArgumentException be thrown for null or ""
>> query/matrix
>> names?
>> I like IAE being thrown on null, again it represents programmer
>> error.

I agree.


Marc Hadley <marc.hadley at>
CTO Office, Sun Microsystems.