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