Unfortunately, I don't think returning an enum is good in this case. If we
didn't have to worry about extensibility (vendors providing extra) this
method won't work.
On Sun, Nov 4, 2012 at 3:08 AM, Chris Barrow <chris.barrow_at_kaazing.com>wrote:
> Hi Nigel,
>
> I would vote for getType returning an enum of {BYTES, MAP, OBJECT, STREAM,
> TEXT} as I mentioned in the thread below, because it makes it easier to
> write generic code to handle any message (using a switch statement), and
> getBody. I do not believe isBodyAssignableTo is worth including.
>
> thanks,
> Chris
>
> On 10/29/2012 3:07 AM, Nigel Deakin wrote:
>
>> Chris,
>>
>> On 26/10/2012 19:43, Chris Barrow wrote:
>>
>>> Hi Nigel,
>>>
>>> Amended Javadoc looks fine.
>>>
>>> I see what you mean about using isBodyAssignableTo for ObjectMessages,
>>> but I still don't see the necessity for it. Users
>>> can get the object as a Serializable and do instanceof checks or
>>> getClass or test themselves for assignability using
>>> reflection if they really want to cast it. The getBody method would not
>>> be able to do any useful data type conversion
>>> anyway ( as is done for example for message properties and MapMessage
>>> values, which is only possible because they are
>>> limited to be one of a narrow set of types).
>>>
>>
>> getBody is simply a convenience method intended to avoid the need for two
>> casts (in the case of ObjectMessage, where you need to cast Message to
>> ObjectMessage and then cast Serializable to the actual type) or one cast
>> (where you need to cast Message to one of the other message types).
>>
>> Do you think this would be useful? (Would a corresponding setBody() be
>> useful?)
>>
>> isBodyAssignableTo offers a way to find out whether getBody would succeed
>> or not. It's an alternative to doing instanceof on the Message followed in
>> the case of an ObjectMessage by instanceof on the Serializable.
>>
>> I quite like getBody, though as I mentioned I am less convinced about the
>> need for isBodyAssignableTo.
>>
>> To put it another way, as a programmer I do not believe I would ever use
>>> isBodyAssignableTo, but I would certainly use
>>> getType to switch to process different message types differently.
>>>
>>
>> Thanks for your comment. When you've decided your position, can you
>> please make a comment to the user list? This makes it easier for me to
>> publicly review feedback.
>>
>> Thanks,
>>
>> Nigel
>>
>>
>> thanks,
>>> Chris
>>>
>>> On 10/26/2012 10:55 AM, Nigel Deakin wrote:
>>>
>>>> Chris,
>>>>
>>>> On 26/10/2012 17:40, Chris Barrow wrote:
>>>>
>>>>> Hi Nigel,
>>>>>
>>>>> Rather than isBodyAssignableTo, which seems cumbersome, how about just
>>>>> providing a method getType returning an enum of
>>>>> {BYTES, MAP, OBJECT, STREAM, TEXT}? This allows developers to write
>>>>> elegant switch statements to handle cases where
>>>>> there can be multiple types of message:
>>>>> switch(message.getType()) {
>>>>> case BYTES:
>>>>> ...
>>>>> case MAP:
>>>>> ...
>>>>> }
>>>>>
>>>>> Of course the new method would have to be carefully distinguished from
>>>>> existing method getJMSType. But since it returns
>>>>> an enum instead of a string that should avoid any accidental misuse.
>>>>>
>>>>
>>>> This would offer a way of finding out the message type (BytesMessage,
>>>> ObjectMessage etc) without using instanceof.
>>>>
>>>> isBodyAssignableTo would do something slightly different as it also
>>>> tell you whether the body of an ObjectMessage
>>>> could be cast to a specified type. It is intended to match the
>>>> behaviour of getBody, which not only allows to, say,
>>>> extract the String from a TextMessage but also extract the body of an
>>>> ObjectMessage *and* cast it to the specified type.
>>>>
>>>> We could add getType in addition to this (if we were able to avoid
>>>> confusion with the existing getJMSType() method).
>>>> However I hope that methods such as getBody would make it much less
>>>> necessary to know the type of a message that has
>>>> been received.
>>>>
>>>> Javadoc, it looks clear, nice job. Perhaps use the word "must" instead
>>>>> of "should" in the description of the c parameter
>>>>> to tighten it up even more?
>>>>>
>>>>
>>>> Thanks. How about this:
>>>>
>>>> * @param c
>>>> * The type to which the message body will be assigned. <br/>
>>>> * If the message is a <code>TextMessage</code> then this must
>>>>
>>>> * be set to <code>String.class</code> or another class to which
>>>> * a String is assignable. <br/>
>>>> * If the message is a <code>ObjectMessage</code> then this
>>>> * must be set to <code>java.io.Serializable.**class</code> or
>>>>
>>>> * another class to which the payload is assignable. <br/>
>>>> * If the message is a <code>MapMessage</code> then this must
>>>>
>>>> * be set to <code>java.util.Map.class</**code>. <br/>
>>>> * If the message is a <code>BytesMessage</code> then this must
>>>>
>>>> * be set to <code>byte[].class</code>. The
>>>> * <code>BytesMessage</code> must not be in write-only mode.
>>>>
>>>> Nigel
>>>>
>>>>
>>>>> Chris
>>>>>
>>>>>
>>>>> On 10/26/2012 7:00 AM, Nigel Deakin wrote:
>>>>>
>>>>>> http://java.net/jira/browse/**JMS_SPEC-101<http://java.net/jira/browse/JMS_SPEC-101>
>>>>>> New method Message.getBody(Class<T> c)
>>>>>>
>>>>>> Following preceding discussions, I have changed the name of this
>>>>>> method to getBody and polished the javadoc comment
>>>>>> slightly. The updated API doc can be seen below and also at
>>>>>> http://jms-spec.java.net/2.0-**SNAPSHOT/apidocs/javax/jms/**
>>>>>> Message.html#getBody%28java.**lang.Class%29<http://jms-spec.java.net/2.0-SNAPSHOT/apidocs/javax/jms/Message.html#getBody%28java.lang.Class%29>
>>>>>>
>>>>>> In addition, I have taken up John A's suggestion and drafted an API
>>>>>> doc for a method isBodyAssignableTo which can be
>>>>>> used to find out whether a subsequent call to getBody would fail
>>>>>> because of an incompatible type. The APi docs can be
>>>>>> seen below and also at
>>>>>> http://jms-spec.java.net/2.0-**SNAPSHOT/apidocs/javax/jms/**
>>>>>> Message.html#**isBodyAssignableTo%28java.**lang.Class%29<http://jms-spec.java.net/2.0-SNAPSHOT/apidocs/javax/jms/Message.html#isBodyAssignableTo%28java.lang.Class%29>
>>>>>>
>>>>>> I think getBody() would be a nice addition to the API and is a useful
>>>>>> complement to the new receivePayload methods. It
>>>>>> would remove the need to cast a Message to a specific subtype in
>>>>>> other cases such as in a MessageListener. However I
>>>>>> would still welcome your views on this.
>>>>>>
>>>>>> I am less sure about isBodyAssignableTo. It is simple enough to
>>>>>> define, but I'm not totally convinced there's a good
>>>>>> case for adding it. Is this a useful complement to getBody, or is it
>>>>>> simply bloat?
>>>>>>
>>>>>> So please express your views on the following:
>>>>>>
>>>>>> 1. Do you support the addition of Message.getBody() as defined below?
>>>>>>
>>>>>> 2. Do you support the addition of Message.isBodyAssignableTo() as
>>>>>> defined below?
>>>>>>
>>>>>> Thanks,
>>>>>>
>>>>>> Nigel
>>>>>>
>>>>>> Here are those javadocs:
>>>>>>
>>>>>>
>>>>>> /**
>>>>>> * Returns the message body as an object of the specified type. The
>>>>>> message
>>>>>> * body must be capable of being assigned to the specified type. This
>>>>>> means
>>>>>> * that the specified class or interface must be either the same as,
>>>>>> or a
>>>>>> * superclass or superinterface of, the class of the message body. This
>>>>>> * method may be used to obtain the body of any type of message except
>>>>>> for
>>>>>> * <tt>StreamMessage</tt>. If the message has no body then null is
>>>>>> returned.
>>>>>> *
>>>>>> * @param c
>>>>>> * The type to which the message body should be assigned. <br/>
>>>>>> * If the message is a <code>TextMessage</code> then this should
>>>>>> * be set to <code>String.class</code> or another class to which
>>>>>> * a String is assignable. <br/>
>>>>>> * If the message is a <code>ObjectMessage</code> then this
>>>>>> * should be set to <code>java.io.Serializable.**class</code> or
>>>>>> * another class to which the payload is assignable. <br/>
>>>>>> * If the message is a <code>MapMessage</code> then this should
>>>>>> * be set to <code>java.util.Map.class</**code>. <br/>
>>>>>> * If the message is a <code>BytesMessage</code> then this should
>>>>>> * be set to <code>byte[].class</code>. The
>>>>>> * <code>BytesMessage</code> must not be in write-only mode.
>>>>>> *
>>>>>> * @return the message body
>>>>>> *
>>>>>> * @exception JMSException
>>>>>> * if the JMS provider fails to get the message body due to
>>>>>> * some internal error.
>>>>>> * @exception MessageFormatException
>>>>>> * if the message is a <code>StreamMessage</code>, or the
>>>>>> * message body cannot be assigned to the specified type, or
>>>>>> * the message is an <code>ObjectMessage</code> and object
>>>>>> * deserialization fails.
>>>>>> * @exception MessageNotReadableException
>>>>>> * if the message is a <code>BytesMessage</code> and the
>>>>>> * message is in write-only mode.
>>>>>> */
>>>>>> <T> T getBody(Class<T> c) throws JMSException;
>>>>>>
>>>>>> /**
>>>>>> * Returns whether the message body is capable of being assigned to the
>>>>>> * specified type. If this method returns true then a subsequent call
>>>>>> to the
>>>>>> * method <code>getBody</code> with the same type argument would not
>>>>>> throw a
>>>>>> * MessageFormatException.
>>>>>> * <p>
>>>>>> * If the message is a <code>StreamMessage</code> then false is
>>>>>> returned. If
>>>>>> * the message is a <code>ObjectMessage</code> and object
>>>>>> deserialization
>>>>>> * fails then false is returned. If the message has no body then true
>>>>>> is
>>>>>> * returned.
>>>>>> *
>>>>>> * @param c
>>>>>> * The specified type <br/>
>>>>>> * If the message is a <code>TextMessage</code> then method will
>>>>>> * only return true if this parameter is set to
>>>>>> * <code>String.class</code> or another class to which a String
>>>>>> * is assignable. <br/>
>>>>>> * If the message is a <code>ObjectMessage</code> then this
>>>>>> * method will only return true if this parameter is set to
>>>>>> * <code>java.io.Serializable.**class</code> or another class to
>>>>>> * which the payload is assignable. <br/>
>>>>>> * If the message is a <code>MapMessage</code> then this method
>>>>>> * will only return true if this parameter is set to
>>>>>> * <code>java.util.Map.class</**code>. <br/>
>>>>>> * If the message is a <code>BytesMessage</code> then this this
>>>>>> * method will only return true if this parameter is set to
>>>>>> * <code>byte[].class</code>.
>>>>>> *
>>>>>> * @return whether the message body is capable of being assigned to the
>>>>>> * specified type
>>>>>> *
>>>>>> * @exception JMSException
>>>>>> * if the JMS provider fails to return a value due to some
>>>>>> * internal error.
>>>>>> * @exception MessageNotReadableException
>>>>>> * if the message is a <code>BytesMessage</code> and the
>>>>>> * message is in write-only mode.
>>>>>> */
>>>>>> boolean isBodyAssignableTo(Class c) throws JMSException;
>>>>>>
>>>>>
>>>>>
>>>
>