jsr343-experts@jms-spec.java.net

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

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Mon, 21 Jan 2013 12:53:54 +0000

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

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