dev@jsr311.java.net

Re: New sketch of updated APIs

From: Dhanji R. Prasanna <dhanji_at_gmail.com>
Date: Fri, 20 Apr 2007 22:45:33 +1000

On 4/20/07, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:

>
> I may have caused some confusion: by 'latter' i was referring to the use
> of annotations and by 'former' i was referring to Response and
> ResponseProvider.


Ok that's what I thought initially but was thrown off after a re-read of
your sentence, I apologize. Then I am with you in that I would prefer the
builder as being the high-level abstraction for returning responses.

> The nice thing is the latter and former are rather independent. It
> > appears we have some consensus on the former to take this forward,
> > while still allowing use-cases for the latter to be
> > proposed/discussed/investigated. Is that a reasonable way forward?
> >


Is there some value to us putting some sort of numbering or naming scheme
around each of these proposals, so we can formalize referring to them?
Perhaps at the head of the thread, like Marc does with code snippets? I
think we're going to run into a lot of formers and latters otherwise ;)

> There is no elbow room (unlike the optional contract for "destructive"
> > methods).
> >
>
> Can you explain a bit more about "destructive" methods?


So-called destructive methods are those that mutate the state of the map
(removeAll(), iterator().remove() etc.). These can be left unimplemented
according to the contract of Map so long as they throw
UnsupportedOperationException. Other query methods can optionally throw a
certain subset of unchecked exceptions or return statuses (booleans). This
is the sort of elbow room available in JCF.

A multi-valued map (where put() appends an element to a list of values)
would break the contract as there's no room for altering those
semantics--that's what I was getting at. To be sure, jakarta commons
MultiMap does generalize to Map and altered methods are re-contracted
(documented again), but its kludgey and I believe it to be a mistake.

In general we need to get the right abstraction for what is currently
> MultivaluedMap for a thing where a key can have a one or more values. V
> can also be List<T>. List<String> is used for request headers.


There's nothing particularly bad about MultivaluedMap so long as we remove
the generalization to the Map interface. Here's something to illustrate my
point:

Map<String, String> map = new Jsr311MultivaluedMap<String, String>();
map.put("key1", "val1");
map.put("key1", "val2");

map.get("key1"); //either a ClassCastException or a breach of contract if
you use *some* domain logic to select from the value list

I noticed RESTlet uses something different around the concept of a
> series.


This is interesting--could you speak to this a bit further? Better yet can
we trouble Jerome for example code? =)

We chose Map because we thought the most common operation is
> likely to be put/get using a key, either putting/getting a single value
> or putting/getting a list of the values, and this can be efficiently and
> easily supported using a HashMap implementation (which scales for large
> number of keys).


Sure, though I dont think we're going to see anywhere near the number of
keys where HashMap or j.u.c.CHM come into their own (a la EHCache reference
maps).

A multivalued thing in general is rather common for query, request
> header, matrix and, to some extent, URI parameters all of which are
> consumed. But perhaps the same abstraction is not required for the
> response headers that are produced?


You can have multiple values for content-type as we've seen in other
discussions. That I'm sure is one among many, so there is probably a case
for it. Or for a suitable alternative.


> The reasons we thought for ResponseProvider (or Response as you propose)
> adding its meta-data rather than returning the meta-data is:
>
> 1) the runtime can provide the implementation, which may be
> optimized/resued (e.g. the underlying container artifacts could be
> set/get directly using this interface); and


This can still be the case. I applied the your stated principle to the
Response artifact--a user can supply their own impl of a map that the
runtime *adds* to its custom implementation.

2) the particular ResponseProvider, e.g. for created, it is not
> necessary to create a map for when the common meta-data is used.


I suppose, but I tend to think of such savings as meretricious ones. The
same result (for oft-used metadata) can be achieved with a static final Map.
Then again Im not particularly against it--it was just a suggestion. I like
to reduce the use of the visitor pattern where possible, but this is a
matter of taste. =)

Dhanji.