jsr343-experts@jms-spec.java.net

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

From: John D. Ament <john.d.ament_at_gmail.com>
Date: Mon, 21 Jan 2013 08:51:29 -0500

Hi Nigel,

If there are no properties set on the JMSProducer, will this return null or
the equivalent of Collections.EMPTY_SET ? Since you should not modify it,
can we call it an immutable set in the API docs (e.g. a wrap of
Collections.unmodifiableSet ?)

John


On Mon, Jan 21, 2013 at 7:53 AM, Nigel Deakin <nigel.deakin_at_oracle.com>wrote:

> Following comments, I have now drafted this small API change. You can view
> it at
> http://jms-spec.java.net/2.0-**SNAPSHOT/apidocs/javax/jms/**
> JMSProducer.html#**getPropertyNames%28%29<http://jms-spec.java.net/2.0-SNAPSHOT/apidocs/javax/jms/JMSProducer.html#getPropertyNames%28%29>
>
> getPropertyNames
>
> Set<String> getPropertyNames()
>
> Returns an Set containing the names of all the message properties that
> have been set on this JMSProducer.
>
> Note that JMS standard header fields are not considered properties and
> are not returned in this Set.
>
> The returned Set is a copy. Changes to the JMSProducer will not be
> reflected in the Set, nor vice-versa.
>
> Returns:
> a Set containing the names of property values
> Throws:
> JMSRuntimeException - if the JMS provider fails to get the
> property names due to some internal error.
>
> Nigel
>
>
> On 11/01/2013 16:07, Nigel Deakin 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
>>>>
>>>