users@jms-spec.java.net

[jms-spec users] [jsr343-experts] Re: JMS 2.0 Late update: JMSProducer.getPropertyNames()

From: Clebert Suconic <clebert.suconic_at_gmail.com>
Date: Sat, 12 Jan 2013 21:11:07 -0600

+1

Sent from my iPhone

On Jan 12, 2013, at 8:11 PM, John Harby <jharby_at_gmail.com> wrote:

+1, I agree too. It looks like it will be a minor usability improvement.

On Fri, Jan 11, 2013 at 8:07 AM, Nigel Deakin <nigel.deakin_at_oracle.com>wrote:

> I'd like to propose we accept Philippe's proposal and change the
> definition of JMSProducer#getPropertyNames() to return a Set <String>
> instead of an Enumeration.
>
> I propose that for simplicity this be a copy of the property names. It
> would not be backed by the underlying collection, unlike Map#keySet. I
> cannot conceive of a use case where that would be needed.
>
> Although this is a minor change, if we are going to make it we have to
> make it before JMS 2.0 is released, since we won't be able to change it
> after that.
>
> Any comments?
>
> Nigel
>
>
>
> On 07/01/2013 12:40, Nigel Deakin wrote:
>
>> Philippe - Thank you for your detailed and well-argued message. I think
>> you make a very good case for changing
>> JMSProducer#getPropertyNames
>> from
>> Enumeration getPropertyNames()
>> to
>> Set<String>
>>
>> I think that probably is a good change.
>>
>> However I think it is worth me pointing out that this method (either
>> version) will be used rarely, since all it does it
>> allow an application to discover what property names were set using prior
>> calls to JMSProducer#setProperty() on the same
>> JMSProducer object.
>>
>> Although JMSProducer#getPropertyNames() and the various
>> JMSProducer#get*Property methods such as
>> JMSProducer#getLongProperty() were added for completeness and consistency
>> I think there are few use cases where they
>> would be used. So are they needed at all?
>>
>> Nigel
>>
>>
>> On 04/01/2013 18:57, Philippe Marschall 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<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
>>>
>>