Glynn, Eoghan wrote:

Folks,

A quick warning on some surprising Exchange.remove() semantics.

The following code doesn't work as you'd expect:

  exchange.put(MyClass.class, myObject);
  // do some stuff
  exchange.remove(MyClass.class);

specifically the remove doesn't actually have any effect. This bit me
big-time earlier today.

The problem is that the
org.apache.cxf.message.StringMapImpl.put(Class<T> key, T value)
inherited by ExchangeImpl does a Map.put() on key.getName(), not the key
itself.

So in order to actually remove the entry from the Exchange map, you'd
need to call exchange.remove(MyClass.class.getName()), i.e. use a
different key to the one originally passed to Exchange.put().

Now I guess we could override remove(Class<T> key) on StringMapImpl
also, so that exchange.remove(MyClass.class) would work as expected, but
do we really need to do that for every Map method that depends on the
key, e.g. containsKey(), keySet(), entrySet(), putAll() etc.
Nothing that we can or need to do for keySet(), entrySet(), putAll() - just the convenience overrides for remove and containsKey.

But I wonder why Exchange even implements
org.apache.cxf.message.StringMap, when clearly we're using it to set
non-string properties, i.e. those keyed on Class. Maybe instead Exchange
should revert to just implement java.util.Map directly?

Or have Exchange implement a generic Map sub-interface with T
get(Class<T> key) and void put(Class<T> key, T value) overrides (to
avoid having to cast the exchange.get(MyClass.class) return value), but
without the <String, Object> restriction?
Personally, I prefer not being ultra flexible here. And Message also extends StringMap, adding the get/setContent() methods.
But that's just my opinion.

Thoughts?

/Eoghan









Reply via email to