@@ -263,20 +263,18 @@ func (msg *MessageImpl) GetJMSTimestamp() int64 {
263263 return timestamp
264264}
265265
266- // GetApplName retrieves the PutApplName field from the MQMD.
267- // This method is not exposed on the JMS style interface and is mainly for testing purposes.
268- func (msg * MessageImpl ) GetApplName () string {
269- applName := ""
266+ // GetJMSExpiration returns the timestamp at which the message is due to
267+ // expire.
268+ func (msg * MessageImpl ) GetJMSExpiration () int64 {
270269
271- // Note that if there is no MQMD then there is no correlID stored.
272- if msg .mqmd != nil {
273-
274- // Get hold of the bytes representation of the correlation ID.
275- applName = msg .mqmd .PutApplName
270+ // mqmd.Expiry gives tenths of a second after which message should expire
271+ timestamp := msg .GetJMSTimestamp ()
276272
273+ if timestamp != 0 && msg .mqmd .Expiry != 0 {
274+ timestamp += (int64 (msg .mqmd .Expiry ) * 100 )
277275 }
278276
279- return applName
277+ return timestamp
280278}
281279
282280// SetStringProperty enables an application to set a string-type message property.
@@ -288,6 +286,12 @@ func (msg *MessageImpl) SetStringProperty(name string, value *string) jms20subse
288286
289287 var linkedErr error
290288
289+ // Different code path and shortcut for special header properties
290+ isSpecial , _ := msg .setSpecialStringPropertyValue (name , value )
291+ if isSpecial {
292+ return nil
293+ }
294+
291295 if value != nil {
292296 // Looking to set a value
293297 var valueStr string
@@ -314,6 +318,104 @@ func (msg *MessageImpl) SetStringProperty(name string, value *string) jms20subse
314318 return retErr
315319}
316320
321+ // getSpecialPropertyValue returns the value of special header properties such as
322+ // values from the MQMD that are mapped to JMS properties.
323+ func (msg * MessageImpl ) setSpecialStringPropertyValue (name string , value * string ) (bool , error ) {
324+
325+ // Special properties always start with a known prefix.
326+ if ! strings .HasPrefix (name , "JMS" ) {
327+ return false , nil
328+ }
329+
330+ // Check first that there is an MQMD to write to
331+ if msg .mqmd == nil {
332+ msg .mqmd = ibmmq .NewMQMD ()
333+ }
334+
335+ // Assume for now that this property is special as it has passed the basic
336+ // checks, and this value will be set back to false if it doesn't match any
337+ // of the specific fields.
338+ isSpecial := true
339+
340+ var err error
341+
342+ switch name {
343+ case "JMS_IBM_Format" :
344+ if value != nil {
345+ msg .mqmd .Format = * value
346+ } else {
347+ msg .mqmd .Format = ibmmq .MQFMT_NONE // unset
348+ }
349+
350+ case "JMS_IBM_MQMD_Format" :
351+ if value != nil {
352+ msg .mqmd .Format = * value
353+ } else {
354+ msg .mqmd .Format = ibmmq .MQFMT_NONE // unset
355+ }
356+
357+ default :
358+ isSpecial = false
359+ }
360+
361+ return isSpecial , err
362+ }
363+
364+ // getSpecialPropertyValue returns the value of special header properties such as
365+ // values from the MQMD that are mapped to JMS properties.
366+ func (msg * MessageImpl ) getSpecialPropertyValue (name string ) (bool , interface {}, error ) {
367+
368+ // Special properties always start with a known prefix.
369+ if ! strings .HasPrefix (name , "JMS" ) {
370+ return false , nil , nil
371+ }
372+
373+ // Assume for now that this property is special as it has passed the basic
374+ // checks, and this value will be set back to false if it doesn't match any
375+ // of the specific fields.
376+ isSpecial := true
377+
378+ var value interface {}
379+ var err error
380+
381+ switch name {
382+ case "JMS_IBM_PutDate" :
383+ if msg .mqmd != nil {
384+ value = msg .mqmd .PutDate
385+ }
386+
387+ case "JMS_IBM_PutTime" :
388+ if msg .mqmd != nil {
389+ value = msg .mqmd .PutTime
390+ }
391+
392+ case "JMS_IBM_Format" :
393+ if msg .mqmd != nil && msg .mqmd .Format != ibmmq .MQFMT_NONE {
394+ value = msg .mqmd .Format
395+ }
396+
397+ case "JMS_IBM_MQMD_Format" : // same as JMS_IBM_Format
398+ if msg .mqmd != nil && msg .mqmd .Format != ibmmq .MQFMT_NONE {
399+ value = msg .mqmd .Format
400+ }
401+
402+ case "JMSXAppID" :
403+ if msg .mqmd != nil {
404+ value = msg .mqmd .PutApplName
405+ }
406+
407+ case "JMS_IBM_MQMD_ApplOriginData" :
408+ if msg .mqmd != nil && msg .mqmd .ApplOriginData != ibmmq .MQFMT_NONE {
409+ value = msg .mqmd .ApplOriginData
410+ }
411+
412+ default :
413+ isSpecial = false
414+ }
415+
416+ return isSpecial , value , err
417+ }
418+
317419// GetStringProperty returns the string value of a named message property.
318420// Returns nil if the named property is not set.
319421func (msg * MessageImpl ) GetStringProperty (name string ) (* string , jms20subset.JMSException ) {
@@ -324,32 +426,43 @@ func (msg *MessageImpl) GetStringProperty(name string) (*string, jms20subset.JMS
324426 impo := ibmmq .NewMQIMPO ()
325427 pd := ibmmq .NewMQPD ()
326428
327- _ , value , err := msg .msgHandle .InqMP (impo , pd , name )
429+ // Check first if this is a special property
430+ isSpecialProp , value , err := msg .getSpecialPropertyValue (name )
431+
432+ if ! isSpecialProp {
433+ // If not then look for a user property
434+ _ , value , err = msg .msgHandle .InqMP (impo , pd , name )
435+ }
328436
329437 if err == nil {
330438
331439 var parseErr error
332440
333- switch valueTyped := value .(type ) {
334- case string :
335- valueStrPtr = & valueTyped
336- case int64 :
337- valueStr := strconv .FormatInt (valueTyped , 10 )
338- valueStrPtr = & valueStr
339- if parseErr != nil {
340- retErr = jms20subset .CreateJMSException (MessageImpl_PROPERTY_CONVERT_FAILED_REASON ,
341- MessageImpl_PROPERTY_CONVERT_FAILED_CODE , parseErr )
441+ if value != nil {
442+
443+ switch valueTyped := value .(type ) {
444+ case string :
445+ valueStrPtr = & valueTyped
446+ case int64 :
447+ valueStr := strconv .FormatInt (valueTyped , 10 )
448+ valueStrPtr = & valueStr
449+ if parseErr != nil {
450+ retErr = jms20subset .CreateJMSException (MessageImpl_PROPERTY_CONVERT_FAILED_REASON ,
451+ MessageImpl_PROPERTY_CONVERT_FAILED_CODE , parseErr )
452+ }
453+ case bool :
454+ valueStr := strconv .FormatBool (valueTyped )
455+ valueStrPtr = & valueStr
456+ case float64 :
457+ valueStr := fmt .Sprintf ("%g" , valueTyped )
458+ valueStrPtr = & valueStr
459+ default :
460+ retErr = jms20subset .CreateJMSException (MessageImpl_PROPERTY_CONVERT_NOTSUPPORTED_REASON ,
461+ MessageImpl_PROPERTY_CONVERT_NOTSUPPORTED_CODE , parseErr )
342462 }
343- case bool :
344- valueStr := strconv .FormatBool (valueTyped )
345- valueStrPtr = & valueStr
346- case float64 :
347- valueStr := fmt .Sprintf ("%g" , valueTyped )
348- valueStrPtr = & valueStr
349- default :
350- retErr = jms20subset .CreateJMSException (MessageImpl_PROPERTY_CONVERT_NOTSUPPORTED_REASON ,
351- MessageImpl_PROPERTY_CONVERT_NOTSUPPORTED_CODE , parseErr )
463+
352464 }
465+
353466 } else {
354467
355468 mqret := err .(* ibmmq.MQReturn )
0 commit comments