users@jms-spec.java.net

[jms-spec users] Re: [jsr343-experts] Re: JMSProducer#getProperyNames()

From: Rüdiger zu Dohna <ruediger.dohna_at_1und1.de>
Date: Mon, 7 Jan 2013 08:44:00 +0100

I second Philippes suggestion. It's very forward-looking without breaking compatibility. This by far outweighs the mental effort when starting to use the new apis.


Rüdiger

On 04.01.2013, at 19:57, Philippe Marschall <kustos_at_gmx.net> wrote:

>
>
> On 04.01.2013 11:57, Nigel Deakin wrote:
>> Hi Philippe,
>>
>> On 03/01/2013 22:14, Philippe Marschall wrote:
>>> Hi
>>>
>>> Why is the return type of JMSProducer#getProperyNames() a raw (!)
>>> Enumeration instead of a Set<String>?
>>
>> Good question. This method (and many other methods on JMSProducer) is
>> simply a copy of the corresponding method on Message. And
>> Message#getPropertyNames returns a "raw" Enumeration.
>>
>> http://docs.oracle.com/javaee/6/api/javax/jms/Message.html#getPropertyNames%28%29
>>
>>
>> (Both methods return a collection of message property names)
>>
>> Hmm. There are two issues here:
>>
>> 1. whether it should return an Enumeration or a Set
>> 2. whether it should use a generic type, i.e. <String>
>>
>> In general I think we should avoid try to keep the methods on
>> JMSProducer and Message consistent since the user will need to use both.
>>
>> (The exception to this is that whereas Message has nine methods to set
>> properties with names like setStringProperty, setShortProperty etc,
>> JMSProducer has nine methods all called setProperty. So I have broken my
>> own "rule" in this case in order to simplify the API.)
>
> My understanding is that JMSProducer is the "new, clutter free, boiler
> plate free, concise" API. Enumeration itself is a pretty useless
> interface. There are no useful methods like #contains or #size, you
> can't put it into an enhanced-for-loop and it likely won't work with
> Java 8 "functional methods". You always have to iterate which is
> inefficient or convert to a Set which is boiler plate.
>
> It starts with simple things, iteration with a Set you can do
>
> for (String properytName : producer.getProperyNames()) {
>
> }
>
> with an enumeration you do
>
> Enumeration<?> enumeration = producer.getProperyNames();
> while (enumeration.hasMoreElements()) {
> String properytName = enumeration.nextElement();
> }
>
> but goes on to things like #contains, with a Set you can do:
>
> producer.getProperyNames().contains("JMSXProducerTXID")
>
> but with an enumeration you write the following which is probably also
> less efficient because you do a linear scan
>
> boolean contains = false;
> Enumeration<?> enumeration = producer.getProperyNames();
> while (enumeration.hasMoreElements()) {
> if ("JMSXProducerTXID".equals(enumeration.nextElement())) {
> contains = true;
> break;
> }
> }
>
> With Java 8 (which should ship this year) and a Set you can do:
>
> Set<String> jmsxProperties = producer.getProperyNames().filter(p ->
> p.startsWith("JMSX"));
>
> If you don't return a Set you'll have to do
>
> Set<String> jmsxProperties = new HashSet<>();
> Enumeration<?> enumeration = producer.getProperyNames();
> while (enumeration.hasMoreElements()) {
> String nextElement = (String) enumeration.nextElement();
> if (nextElement.startsWith("JMSX")) {
> jmsxProperties.add(nextElement);
> }
> }
>
>
>
>> My feeling is that returning a generic type would be a fairly
>> transparent improvement.
>>
>> However, given that Message#getPropertyNames returns an Enumeration I
>> think it might be confusing if JMSProducer#getPropertyNames returns a Set.
>
> Look at your current code that uses #getProperyNames and look how much
> simpler, easier to understand and less error prone it would be when
> #getProperyNames returned a Set.
>
> Could we at least have a second method that returns a Set?
>
>> So I suggest we change this to return an Enumeration <String>.
>
> Cheers
> Philippe