Re: New sketch of updated APIs

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Fri, 20 Apr 2007 15:15:56 +0200

Dhanji R. Prasanna wrote:
> > 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 ;)

I really was referring to latter/former in reference to what you were
saying :-) but i agree having some formal identifiers would be useful
when discussing.

> > 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.

See the JavaDoc of MultivaluedMap [1]. It does not break the contract of

   public interface MultivaluedMap<K,V>
     extends java.util.Map<K,java.util.List<V>>

> 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

Since MultivaluedMap extends from java.util.Map<K,java.util.List<V>> it
works consistently with the Map.put/get methods that operate on the List.

The methods, add, putSingle, getFirst define additional semantics for
single values.

> 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? =)

Yes, that is what i was getting at. I would like to understand the
pros/cons of the approach RESTlet took.

> 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).

Right. Mozilla (via firebug) sends 11 request headers, and
responsds with 9 headers. I suspect there are cases where query params
can get larger. However, something in me balks at using a linear search
algorithm :-)

> 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.

I was referring to the use of Map not to the fact there can be multiple
values. I was wondering in this case whether List may be appropriate.

> 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.

Right, a create and copy rather than something direct.

> 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. =)

I think you are making a fair point. Such optimizations may not be worth
it. And if they are not then i do prefer the returning of something instead.



| ? + ? = To question
    Paul Sandoz