Markus KARG wrote:
> Craig,
>
> thank you so much for your comments. More inlined.
>
>
>>> For example, how to add multiple instances of the same class to a
>>>
>> root
>>
>>> element?
>>>
>>> return new MultiStatus(new Result(x), new Result(y)); (non-fluent)
>>>
>>> return WebDavBuilder.multiStatus().result(x).result(y); ?
>>>
>>> return WebDavBuilder.multiStatus(new Result(x), new Result(y)); ?
>>>
>>>
>> Technically, either of these can work.
>>
>
> Sure. But none of the two fluent variants is easier to write or read than
> the non-fluent variant, so what does the user win? A longer code and the
> confusion how to add something to the result, obviously!
>
>
Personally, I find the second alternative shown above to be much nicer
... not only is it fewer characters to type, it probably saves me having
to import Result or understand anything about its API.
>> One important principle illustrated in my example above (and sometimes
>> violated in the JAX-RS and Jersey instances of the pattern) is that the
>> "this" object you are building up should not change as the expression
>> gets evaluated. In your first pattern, I'm assuming that the result(x)
>> and result(y) methods return the MultiStatus instance you are adding
>> to,
>> so that would be obeying the pattern. However, what if result() was
>> itself a builder that let you construct a Result? That would be
>> confusing to the user, because the "." connectors in the expression
>> after this would refer to that Result, and you could never get back to
>> adding things to the MultiStatus.
>>
>
> Ok, this will work for HelloWorld, but to tell the whole truth about WebDAV
> and demonstrate the dilemma of a fluent API: A valid WebDAV Result is not
> constructed by just code and message (Result(int, String)) but a lot of
> other objects which again have a lot of references... This code line shows
> what currently is typical for WebDAV and must be replaced by a fluent API:
>
> -- SNIP --
>
> // Excerpt from webdav-addressbook sample
>
> final Response folder = new Response(new HRef(uriInfo.getRequestUri()),
> null, null, null, new PropStat(new Prop(new MicrosoftRedirectorPatch2(), new
> DisplayName("My Collection"), new CreationDate(new Date()), new
> GetLastModified(new Date()), COLLECTION), new Status(OK)));
>
> if (depth.equals(DEPTH_0))
> return new MultiStatus(folder);
>
> final Collection<Response> responses = new
> LinkedList<Response>(Collections.singletonList(folder));
> for (final Contact c : (List<Contact>)
> this.em().createNamedQuery("ListContacts").getResultList())
> responses.add(new Response(new
> HRef(uriInfo.getAbsolutePathBuilder().path(String.format("%s.adr",
> c.getMatchCode())).build()), null, null, null, new PropStat(new Prop(new
> MicrosoftRedirectorPatch2(), new DisplayName(String.format("%s %s",
> c.getLastName(), c.getFirstName())), new CreationDate(c.getCreationDate()),
> new GetLastModified(c.getLastModified()), new GetContentLength(0), new
> GetContentType(ADDRESS_MIME)), new Status(OK))));
>
> return new MultiStatus(responses.toArray(new Response[0]));
>
> -- SNIP --
>
> This is NOT an overly complex example -- it demonstrates the MINIMUM that is
> needed to construct a valid MultiStatus instance. Have a look at the
> contrib/webdav source and you'll notice that we're talking about dozens of
> XML elements that must be combined only in the valid schema (and the builder
> shall enforce and support that).
>
>
Now you know why I care so much about a nice client side API for WebDAV :-).
> So how to turn THIS into a fluent API without using a lot of different
> builders or split up into a lot of lines (and in both cases blow up the
> content by far)? Cannot imagine a solution.
>
> Any suggestions...? I do not see that it is possible AND useful to the
> user... :-(
>
>
I suspect we'll need some combination of multiple builders and lots of
alternatives on the fluent pattern builders to accomodate different
combinations of parameter signatures for the various builder methods.
You're absolutely right, though, WebDAV in its full glory is a pretty
complicated beast.
I will take a look at the specs again, but I'm going to be travelling
this week so won't have a heck of a lot of time to work on this.
> Thanks
> Markus
>
>
Craig