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: Fri, 11 Jan 2013 12:05:30 -0500

Agreed to changing it.


On Fri, Jan 11, 2013 at 11:22 AM, Rüdiger zu Dohna
<ruediger.dohna_at_1und1.de>wrote:

> +1
>
> I only would like to suggest that the set should be unmodifiable (e.g.
> wrapped in Collections#unmodifiableSet), not a copy; but that's a minor
> detail.
>
>
> On 11.01.2013, at 17:07, 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
> >>>>
> >>>>
> >>>>
> >>>> (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
>
>